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

wToken Transferability & Ownership Context allow to balanceOf Donation Attack

Root Cause

  1. wToken Transferability

    • The WToken contract inherits standard ERC20 transfer functionality unless explicitly overridden. No code restricts transfers, so users can freely send wTokens to any address, including the AaveDIVAWrapper contract.

    • Example Attack Flow:

      1. Attacker transfers X wTokens directly to the AaveDIVAWrapper contract.

      2. Victim calls removeLiquidity(), triggering a balance check:

        uint256 _wTokenAmountReturned = balanceAfter - balanceBefore; // Includes attacker's X wTokens
      3. Protocol burns victim’s wTokens + X and withdraws victim’s collateral + X from Aave.

      4. Attacker front-runs to steal the surplus X collateral.

  2. wToken Mint/Burn Control

    • While only the AaveDIVAWrapper can mint/burn wTokens (owner-restricted), transfers between users are unrestricted by default (ERC20 standard). This allows attackers to manipulate the contract’s wToken balance via direct transfers.


Impact Amplification

  • wToken = Aave Collateral: Since 1 wToken always represents 1 underlying Aave collateral token (e.g., USDC), manipulating wToken balances directly impacts real assets. Attackers can "donate" wTokens to exploit the balance delta, converting fake wToken inflation into stolen collateral.


Recommendations

  1. Internal Accounting
    Track wToken inflows/outflows using internal state variables instead of balanceOf. For example:

    // In AaveDIVAWrapperCore
    mapping(bytes32 => uint256) private _expectedCollateralReturns;
    function _removeLiquidity(...) internal {
    _expectedCollateralReturns[_poolId] = _calculateExpectedReturn(...);
    IDIVA(_diva).removeLiquidity(...);
    uint256 _wTokenAmountReturned = _expectedCollateralReturns[_poolId];
    delete _expectedCollateralReturns[_poolId];
    // ...
    }
  2. Restrict wToken Transfers
    Modify the WToken contract to disable arbitrary transfers, allowing only the AaveDIVAWrapper to move tokens:

    // In WToken.sol
    function _beforeTokenTransfer(address from, address to, uint256) internal override {
    require(from == address(0) || to == address(0) || msg.sender == owner(), "Transfers disabled");
    }
    • This restricts transfers to only mint/burn operations by the owner (wrapper contract), preventing external manipulation.

Updates

Lead Judging Commences

bube Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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