calculateUnwindParams returns collateralToWithdraw and debtAmount for unwinding a position. Callers (e.g. frontend, tests) use these values to build 1inch swap data and pass them to unwindPosition. The function also applies a 5% slippage buffer to collateralToWithdraw before returning.
unwindPosition accepts _collateralToWithdraw and stores it in UnwindParams, but _executeUnwindOperation completely ignores it. The callback recalculates collateralToWithdraw using a different formula (with LTV/liqThreshold from Aave). The 5% slippage in calculateUnwindParams only affects the 1inch swap input size (built from the returned value), while the actual withdrawal uses the internal formula. This creates a mismatch: the swap is prepared for one amount, but a different amount is withdrawn. If the internal formula withdraws less, the swap receives less input than expected and the unwind can revert at require(returnAmount >= totalDebt).
Likelihood (high):
Every unwind flow uses this pattern: call calculateUnwindParams, build 1inch swap from the result, then call unwindPosition. The tests (e.g. Stratax.t.sol:202-206) follow this exact flow.
The two formulas differ: calculateUnwindParams uses a pure price-based conversion; _executeUnwindOperation uses LTV/liqThreshold. Per finding 006, liqThreshold > LTV causes the internal formula to withdraw less collateral than the price-based formula would suggest.
Impact (medium):
Swap is built for collateralToWithdraw from calculateUnwindParams, but actual withdrawal is the recalculated amount. If recalculated amount is less, swap receives less input → may return less than totalDebt → unwind reverts.
User-facing confusion: the displayed/returned collateral amount does not match what the contract actually withdraws.
Severity (low):
Option A: Use unwindParams.collateralToWithdraw in _executeUnwindOperation instead of recalculating. Align the formula in calculateUnwindParams with the unwind logic (use LTV, not liqThreshold) so both produce the same result.
Option B: Remove collateralToWithdraw from calculateUnwindParams return and document that it is a view helper for display/estimation only. Have the frontend build the 1inch swap using the same formula as _executeUnwindOperation (or expose an internal view that returns the actual amount that will be withdrawn).
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.
The contest is complete and the rewards are being distributed.