The calculateUnwindParams() and _executeUnwindOperation() use different formulas to calculate collateralToWithdraw (15.4% discrepancy). Additionally, the user-provided collateralToWithdraw parameter is completely ignored — a local variable shadows the struct field.
calculateUnwindParams() (L464-468) uses debtValue × 1.05 (5% buffer), while _executeUnwindOperation() (L575-577) uses debtValue × (10000 / liqThreshold) ≈ × 1.212 for ETH — a 15.4% difference between preview and execution.
The _collateralToWithdraw parameter in unwindPosition() is stored in the UnwindParams struct and passed through the flash loan, but at line 575, a local variable uint256 collateralToWithdraw = (...) shadows unwindParams.collateralToWithdraw — the struct field is never read.
Likelihood: This inconsistency exists in every unwind call flow. The local variable shadowing is deterministic.
Impact: No direct fund loss — the contract uses its own calculation. However, the API parameter is functionally useless (wastes gas, misleads integrators), and frontends show previews that differ ~15% from execution.
For ETH (liqThreshold=8250): calculateUnwindParams returns debtValue × 1.05, while _executeUnwindOperation computes debtValue × 1.2121 — a 15.4% gap. The user parameter traces through encoding → flash loan → decoding, but the struct field is shadowed at line 575 and never referenced.
Either use the user-provided value (Option A) to align execution with the preview, or remove the unused parameter (Option B) to clean up the API.
function logic ignores user input
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.