HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: high
Invalid

Withdraw from AAVE may not return full amount requested and lead to loss of funds.

Summary

When removing liquidity or redeeming position the `_amountReturned` from AAVE may not be the full amount the user requested. This will lead to funds being lost for the user since all of his wTokens are being burned, leaving him with no wTokens to get his remaining collateral from AAVE.

Vulnerability Details

When a user decides to removing liquidity or redeeming position he calls the corresponding function in the AaveDIVAWrapper/Core contract. The correspongin function calls '_redeemTokenPrivate' function. Let's take a look at that function:

function _redeemWTokenPrivate(
address _wToken,
uint256 _wTokenAmount,
address _recipient,
address _burnFrom
) private returns (uint256) {
if (_recipient == address(0)) revert ZeroAddress();
// Burn the specified amount of wTokens. Only this contract has the authority to do so.
// Reverts if `_wTokenAmount` exceeds the user's wToken balance.
IWToken(_wToken).burn(_burnFrom, _wTokenAmount);
address _collateralToken = _wTokenToCollateralToken[_wToken];
// Withdraw the collateral asset from Aave, which burns the equivalent amount of aTokens owned by this contract.
// E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC.
// Collateral token is transferred to `_recipient`.
// Reverts if the collateral token is not a registered wToken (first parameter will be address(0)).
uint256 _amountReturned = IAave(_aaveV3Pool).withdraw(
_collateralToken, // Address of the underlying asset (e.g., USDT), not the aToken.
_wTokenAmount, // Amount to withdraw.
_recipient // Address that will receive the underlying asset.
);
emit WTokenRedeemed(_wToken, _wTokenAmount, _collateralToken, _amountReturned, _recipient);
return _amountReturned;
}

So the function calls the `withdraw` function from AAVE. Let's take a look at the documentation from AAVE:

https://aave.com/docs/developers/smart-contracts/pool

For the withdraw function we have this important message:

`If user has any existing debt backed by the underlying token, then the maximum amount available to withdraw is the amount that will not leave user's health factor < 1 after withdrawal.`

Meaning if a user has used this collateral in a debt backing he will return only the part that will not harm his debt.

But as we previously see in the function ,if a user withdraws all of his wToken the user will have his whole wToken balance burned but may NOT receive the whole amount returned from AAVE.

Leaving him with no wToken and only a portion of his collateral back , in a case where he decided to withdraw all of his collateral.

There is no checking for the _amountReturned to be equal to the _wTokenAmount.

Impact

High as funds from the user will be lost.

Tools Used

Manual review

Recommendations

Compare the _amountReturned with the _wTokenAmount in the _redeemTokenPrivate function.

Or another approach is to keep the eligible tokens to withdraw in a separate mapping and make the withdrawal in a separate function.

Updates

Lead Judging Commences

bube Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!