57788 sc medium missing claimrewards implementation in aavev3arbusdcstrategy leads to permanent loss of aave incentive rewards

#57788 [SC-Medium] Missing `_claimRewards()` Implementation in AaveV3ARBUSDCStrategy Leads to Permanent Loss of Aave Incentive Rewards

Submitted on Oct 28th 2025 at 21:31:15 UTC by @Orhuk1 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57788

  • Report Type: Smart Contract

  • Report severity: Medium

  • Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/strategies/arbitrum/AaveV3ARBUSDCStrategy.sol

  • Impacts:

    • Permanent freezing of unclaimed yield

Description

The AaveV3ARBUSDCStrategy contract supplies USDC to Aave V3 on Arbitrum but fails to implement the required _claimRewards() function. This results in all Aave incentive rewards earned by the strategy becoming permanently inaccessible.

Vulnerability Details

The MYTStrategy base contract provides a public claimRewards() function that calls an internal virtual _claimRewards() function:

// MYTStrategy.sol
function claimRewards() public virtual returns (uint256) {
    require(!killSwitch, "emergency");
    _claimRewards();
}

/// @dev override this function to claim all available rewards from the respective
/// protocol of this strategy
function _claimRewards() internal virtual returns (uint256) {}

The AaveV3ARBUSDCStrategy contract inherits from MYTStrategy and correctly implements other required overrides (_allocate(), _deallocate(), _previewAdjustedWithdraw(), and realAssets()). However, it does not override _claimRewards(), leaving it as an empty function.

When USDC is supplied to Aave through the strategy:

The strategy contract becomes the holder of aUSDC tokens and begins accruing Aave incentive rewards, https://aave.com/docs/developers/incentives. According to Aave's design, https://aave.com/docs/developers/aptos/smart-contracts/incentives, only the aToken holder can claim their own rewards through the Incentives Controller at address 0x929EC64c34a17401F460460D4B9390518E5B473e.

Since the strategy has no implementation to interact with Aave's Incentives Controller, and only the strategy contract can claim its own rewards, all accrued incentives become permanently inaccessible.

Impact Classification

Severity: High - Permanent Freezing of Unclaimed Yield

Per the severity classification system:

"Permanent freezing of unclaimed yield: A yield is any asset distributed as a reward for participation in a system. Whenever an attacker can prevent the yield from being able to move from the contract, for example by making the harvest() function always fail, this would mean the yield is permanently frozen."

In this case, while there is no attacker, the missing implementation has the same effect - the yield cannot be moved from Aave's Incentives Controller, and the rewards are permanently frozen.

Direct Financial Impact

All Aave incentive rewards earned by capital deployed in the AaveV3ARBUSDCStrategy are permanently lost. The magnitude of loss depends on:

  • Total USDC allocated to this strategy

  • Aave's incentive emission rate on Arbitrum

  • Duration of deployment

For context, if $1M USDC is deployed earning 2% APR in incentives over one year, approximately $20,000 in reward tokens would be permanently locked.

Recommendation

Implement _claimRewards() in AaveV3ARBUSDCStrategy.sol:

Acknowledgment

This vulnerability represents an implementation oversight where a required function was not overridden, resulting in the permanent freezing of unclaimed yield. The severity classification follows the established standards for High severity impacts: "Permanent freezing of unclaimed yield." The test demonstrates conclusively that rewards cannot be claimed by the strategy or any other party, making them permanently inaccessible.

Proof of Concept

Proof of Concept

  • Create a poc.t.sol and paste the content in the test file run

Test Result: ✅ PASS

The test confirms:

  1. Strategy successfully allocates USDC and receives aUSDC tokens

  2. claimRewards() executes without error but returns 0 (does nothing)

  3. The strategy owner cannot claim rewards on behalf of the strategy (returns 0)

  4. Only the aToken holder (the strategy contract) can claim rewards, but it has no code to do so

Was this helpful?