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

Missing Validations in `_redeemWToken` Function

Summary

Missing Validations in _redeemWToken Function

Vulnerability Details

The _redeemWToken function in the AaveDIVAWrapperCore contract lacks critical validations for its input parameters:

  1. _wToken is not validated as a contract address. This could allow interactions with non-contract addresses, leading to failed transactions or unexpected behavior.

  2. _recipient is not validated as a non-zero address. Sending funds to the zero address (address(0)) would result in permanent loss of tokens.

function _redeemWToken(address _wToken, uint256 _wTokenAmount, address _recipient) internal returns (uint256) {
// No validation of `_wToken` as a contract or `_recipient` as non-zero.
return _redeemWTokenPrivate(_wToken, _wTokenAmount, _recipient, msg.sender);
}
function _redeemWTokenPrivate(
address _wToken,
uint256 _wTokenAmount,
address _recipient,
address _burnFrom
) private returns (uint256) {
if (_recipient == address(0)) revert ZeroAddress(); // Check for `_recipient` exists here.
// Burn wToken and interact with Aave without validating `_wToken` is a contract.
IWToken(_wToken).burn(_burnFrom, _wTokenAmount);
address _collateralToken = _wTokenToCollateralToken[_wToken];
return IAave(_aaveV3Pool).withdraw(_collateralToken, _wTokenAmount, _recipient);
}

Proof of Concept

Scenario 1: _wToken is Not a Contract

  1. Attacker Action: Call redeemWToken with _wToken = address(0x123) (an EOA).

  2. Result: The transaction reverts at IWToken(_wToken).burn(), as EOAs cannot implement the burn function. Users cannot redeem tokens, and gas is wasted.

Scenario 2: _recipient is Zero Address

  1. User Mistake: A user accidentally sets _recipient = address(0) in redeemWToken.

  2. Result: The private function reverts, but validating earlier would prevent unnecessary state changes.

Impact

  1. Interacting with Non-Contract Addresses

    • If _wToken is not a contract (e.g., an EOA or uninitialized address), calls to IWToken(_wToken).burn() will revert, wasting gas and disrupting user operations.

    • An attacker could exploit this to intentionally cause transaction failures, harming protocol reliability.

  2. Loss of Funds

    • If _recipient is set to address(0), tokens withdrawn from Aave will be sent to an irrecoverable address, permanently burning user funds. While the private function checks for this, earlier validation improves safety.

Tools Used

Hardhat

Recommendations

1. Validate _wToken is a Contract
Use OpenZeppelin’s Address library to ensure _wToken is a contract:

import {Address} from "@openzeppelin/contracts/utils/Address.sol";
function _redeemWToken(address _wToken, uint256 _wTokenAmount, address _recipient) internal returns (uint256) {
require(Address.isContract(_wToken), "Invalid wToken: not a contract");
require(_recipient != address(0), "Invalid recipient: zero address");
return _redeemWTokenPrivate(_wToken, _wTokenAmount, _recipient, msg.sender);
}

2. Validate _wToken is Registered
Ensure _wToken is a registered collateral token to prevent invalid redemptions:

function _redeemWToken(address _wToken, uint256 _wTokenAmount, address _recipient) internal returns (uint256) {
require(_wTokenToCollateralToken[_wToken] != address(0), "wToken not registered");
require(Address.isContract(_wToken), "Invalid wToken: not a contract");
require(_recipient != address(0), "Invalid recipient: zero address");
return _redeemWTokenPrivate(_wToken, _wTokenAmount, _recipient, msg.sender);
}

3. Use Safe Token Transfers
Add checks for collateral token validity before burning wTokens:

function _redeemWTokenPrivate(...) private returns (uint256) {
require(_recipient != address(0), "Invalid recipient: zero address");
address _collateralToken = _wTokenToCollateralToken[_wToken];
require(_collateralToken != address(0), "wToken has no collateral");
IWToken(_wToken).burn(_burnFrom, _wTokenAmount);
return IAave(_aaveV3Pool).withdraw(_collateralToken, _wTokenAmount, _recipient);
}
Updates

Lead Judging Commences

bube Lead Judge 5 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.