When redeeming X wTokens, all corresponding aTokens (after interest) must be converted to the collateral token but the code converts only X underlying tokens instead of the full X * exchangeRate, resulting in leftover value, thereby breaking the invariant that all burned wTokens are fully redeemed.
The _redeemWTokenPrivate function burns _wTokenAmount (representing aTokens) and calls IAave.withdraw with _wTokenAmount as the requested underlying amount. However, Aave's withdraw expects the underlying amount, not the aToken amount. Since aTokens accrue interest, burning N aTokens should withdraw N * exchangeRate underlying, not N underlying. Using _wTokenAmount directly results in under-withdrawal, leaving residual aTokens in the contract.
Example: If 1 aToken = 1.1 USDC (due to interest), burning 100 aTokens should withdraw 110 USDC. The current code withdraws 100 USDC, leaving 10 USDC worth of aTokens unclaimed.
Using _wTokenAmount directly results in under-withdrawal, leaving residual aTokens in the contract. Incorrect conversion of wrapped tokens (wTokens) into the underlying collateral.
Manual Review
Adjust the logic so that burning _wTokenAmount aTokens withdraws the equivalent underlying amount based on the current exchange rate.
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.