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

Incorrect Yield Calculation Due to Mishandling of Aave's Rebasing Mechanism

Relevant Context

The AaveDIVAWrapper protocol integrates with Aave V3 to generate yield on user deposits. It uses Aave's aTokens which implement a rebasing mechanism where the token's value increases through exchange rate adjustments rather than balance increases.

Description

The AaveDIVAWrapper protocol's yield calculation mechanism fundamentally mishandles how Aave V3's aToken rebasing works. The protocol mints wTokens 1:1 with user deposits and attempts to track yield by comparing raw aToken balances with wToken supply in _getAccruedYieldPrivate().

The core issue lies in the protocol's assumption that yield accrual increases aToken balances directly. However, Aave V3's aTokens accrue value through exchange rate adjustments while maintaining constant token quantities. The current implementation in _getAccruedYieldPrivate() only compares raw token quantities:

function _getAccruedYieldPrivate(address _collateralToken) private view returns (uint256) {
uint256 aTokenBalance = IERC20Metadata(IAave(_aaveV3Pool).getReserveData(_collateralToken).aTokenAddress)
.balanceOf(address(this));
uint256 wTokenSupply = IERC20Metadata(_collateralTokenToWToken[_collateralToken]).totalSupply();
return aTokenBalance > wTokenSupply ? aTokenBalance - wTokenSupply : 0;
}

This leads to a situation where real yield generated through exchange rate increases is not captured by the calculation, resulting in incorrect yield accounting and potential loss of funds.

Impact

The protocol systematically fails to account for actual yield generated through Aave's rebasing mechanism, leading to incorrect yield distribution and potential permanent loss of funds for users when yield is claimed or positions are redeemed.

Impact Explanation

High. The bug directly impacts core protocol functionality by breaking yield calculations and leading to permanent loss of user funds through incorrect accounting of generated yields.

Proof of Concept

  1. User deposits 100 USDC into protocol

    • Protocol receives 100 aUSDC from Aave

    • Protocol mints 100 wUSDC to user

  2. After time passes, Aave rebase occurs

    • aUSDC exchange rate increases to 1.05

    • 100 aUSDC now worth 105 USDC

    • Raw aToken balance remains at 100

  3. Owner calls claimYield()

    • _getAccruedYieldPrivate() compares 100 (aToken balance) vs 100 (wToken supply)

    • Returns 0 yield despite 5 USDC in actual accrued value

  4. When user redeems wTokens

    • Receives less than entitled amount due to incorrect yield accounting

    • Lost yield cannot be recovered

Tools Used

Manual review

Recommended Mitigation Steps

The protocol should track yields using Aave's scaled balances and exchange rates instead of raw token comparisons. This ensures accurate accounting of yield generated through the rebasing mechanism.

function _getAccruedYieldPrivate(address _collateralToken) private view returns (uint256) {
IAave.ReserveData memory reserveData = IAave(_aaveV3Pool).getReserveData(_collateralToken);
uint256 scaledBalance = IERC20(reserveData.aTokenAddress).scaledBalanceOf(address(this));
uint256 exchangeRate = IAave(_aaveV3Pool).getReserveNormalizedIncome(_collateralToken);
uint256 aTokenValue = (scaledBalance * exchangeRate) / 1e27;
uint256 wTokenSupply = IERC20(_collateralTokenToWToken[_collateralToken]).totalSupply();
return aTokenValue > wTokenSupply ? aTokenValue - wTokenSupply : 0;
}
Updates

Lead Judging Commences

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

Support

FAQs

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