In _executeUnwindOperation, after the flash loan is repaid, any surplus debt tokens are automatically supplied to Aave as a new supply position:
The contract has no direct withdraw() function to retrieve tokens supplied to Aave. The only available function is recoverTokens(), which can transfer aTokens out of the contract — but aTokens cannot be redeemed for the underlying asset without calling aavePool.withdraw(), which the contract doesn't expose.
Likelihood:
Surplus tokens are generated on every unwind operation where the swap returns more debt tokens than needed for flash loan repayment
The collateral-to-withdraw calculation uses the liquidation threshold (liqThreshold), which provides a buffer above 100% of the debt value. After swapping this buffer, surplus tokens are expected
Example: With liqThreshold = 85%, the collateral withdrawn is ~117.6% of the debt value. After swap slippage, ~115% remains. The ~15% surplus is auto-supplied to Aave
Impact:
Over multiple unwind operations, significant value accumulates in Aave supply positions that the contract cannot directly access
The owner cannot withdraw these surplus funds through any existing function
The recoverTokens() function can transfer aTokens to the owner, but the owner then needs to interact with Aave directly to redeem them — a suboptimal and error-prone workaround
Funds are not permanently lost, but they are operationally inaccessible through the Stratax contract
How the issue manifests:
Owner has a leveraged position: 10 ETH collateral, 8000 USDC debt
Owner calls unwindPosition to close the position
Flash loan: 8000 USDC → repay Aave debt → withdraw ~9400 USDC worth of ETH (117.6% of debt at liqThreshold 85%)
Swap ETH → USDC: receives ~9200 USDC (accounting for slippage)
Flash loan repayment: 8000 USDC + ~7.2 USDC premium = ~8007.2 USDC
Surplus: 9200 - 8007.2 = ~1192.8 USDC is auto-supplied to Aave
Owner now has ~1192.8 USDC worth of aUSDC in the contract's Aave position
There is no function to withdraw this USDC from Aave
Expected outcome: ~1192.8 USDC is locked in an Aave supply position with no direct withdrawal mechanism available through the Stratax contract.
The root cause is that the contract creates Aave supply positions (both intentionally during leveraged position creation and incidentally during unwind surplus handling) but lacks a general-purpose withdrawal function.
Primary fix — Add a direct Aave withdrawal function:
Why this works:
Provides the owner with a direct mechanism to withdraw any tokens supplied to Aave, including surplus from unwind operations
onlyOwner ensures only the position owner can withdraw
The _to parameter allows withdrawing directly to the owner's wallet without an intermediate step
This complements the existing recoverTokens() for tokens held directly by the contract (not in Aave)
Alternative fix — Send surplus to owner instead of supplying to Aave:
Tradeoff: The alternative is simpler but loses the "supply to Aave to improve health factor" behavior for multi-position scenarios. The primary fix (adding withdrawFromAave) is more flexible and preserves the existing behavior while giving the owner control.
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.