58759 sc high yield stuck in adapter contracts forever

Submitted on Nov 4th 2025 at 12:10:01 UTC by @Django for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58759

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Permanent freezing of unclaimed yield

Description

Brief/Intro

The adapter contracts allow underlying tokens to be allocated to other vaults to accumulate rewards, however, the rewards can never be claimed from the adapter contract. The adapter's realAssets() will show growth, but the growing capital can not be deallocated.

Vulnerability Details

Quite simply, there is no way to withdraw accumulated yield out of the adapter contracts. The adapters' realYield() amount will continue to grow as rewards are earned by the adapter, however, Alchemix will only be able to deallocate the amount that was previously allocated, not the yield.

For example, take the following strategy:

    function _deallocate(uint256 amount) internal override returns (uint256) {
        uint256 usdcBalanceBefore = TokenUtils.safeBalanceOf(address(usdc), address(this));
        vault.withdraw(amount, address(this), address(this));
        require(TokenUtils.safeBalanceOf(address(usdc), address(this)) >= amount, "Strategy balance is less than the amount needed");
        TokenUtils.safeApprove(address(usdc), msg.sender, amount);
        uint256 usdcBalanceAfter = TokenUtils.safeBalanceOf(address(usdc), address(this));
        uint256 usdcRedeemed = usdcBalanceAfter - usdcBalanceBefore;
        if (usdcRedeemed < amount) {
            emit StrategyDeallocationLoss("Strategy deallocation loss.", amount, usdcRedeemed);
        }
        require(TokenUtils.safeBalanceOf(address(usdc), address(this)) >= amount, "Strategy balance is less than the amount needed");
        return amount;
    }

We see that upon deallocation, the exact amount requested is approved to the calling contract (VaultV2), however any yield generated is not returned.

Impact Details

  • All yield (rewards from adapter vaults) will remain stuck in adapter contracts.

Proof of Concept

Proof of Concept

Was this helpful?