After flash loan repayment in _executeUnwindOperation(), excess tokens are supplied back to Aave as collateral (L591-595). But _asset in the unwind path is the debt token (the flash loan token), not the collateral token. Leftover debt tokens become a new, unintended collateral position in Aave under the Stratax contract, and the user never receives them.
After repaying the flash loan, any excess tokens should be returned to the user. In the open path (L529-532), the leftover handling is correct because _asset is the collateral token. Supplying leftover collateral back to Aave improves the position.
In the unwind path (L591-595), the same pattern is copy-pasted, but _asset is the debt token (because the flash loan borrows the debt token to repay Aave debt):
For an ETH/USDC position (ETH collateral, USDC debt), the leftover USDC gets supplied to Aave as USDC collateral. This USDC is not part of the user's intended position and is stranded in the contract's Aave account.
The owner can technically recover via recoverTokens() on the aToken address, but this is a manual process that requires knowing the correct aToken address.
Likelihood: Medium
Leftovers occur whenever the DEX swap produces slightly more than needed to repay the flash loan. This is common because swap routes are quoted off-chain with slippage buffers. Not every unwind produces leftovers, but a significant portion will.
Impact: Medium
Leftover tokens are locked as collateral in Aave. The user never receives them. For a 10 ETH position unwind, even a 0.1% excess on the swap produces ~$30 of stranded USDC collateral. Over many unwinds across all users, this accumulates. Recovery requires admin intervention.
Trace the code path for unwinding an ETH/USDC position (ETH collateral, USDC debt):
Flash loan borrows 5000 USDC (_asset = USDC)
Repay 5000 USDC debt to Aave (L559-560)
Withdraw ETH collateral from Aave (L579)
Swap ETH to USDC via 1inch, receive 5010 USDC (L584)
totalDebt = 5000 + 4.5 (premium) = 5004.5 USDC (L587)
returnAmount - totalDebt = 5010 - 5004.5 = 5.5 USDC (L591)
aavePool.supply(USDC, 5.5 USDC, address(this), 0) supplies USDC as collateral (L593-594)
User receives nothing. 5.5 USDC is now aUSDC in the contract's Aave position.
Transfer leftover tokens to the user instead of supplying them as wrong-type collateral to Aave:
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.