58192 sc high tokeautoeth strategy tokens locked when autopool router enforces maxdeposit cap

Submitted on Oct 31st 2025 at 09:43:06 UTC by @T0nraq for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58192

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Permanent freezing of funds

Description

Summary

The TokeAutoEth strategy's use of router.depositMax() causes WETH tokens to become permanently locked in the strategy contract when router::maxDeposit limits are enforced. The VaultV2 transfers the full requested amount to the strategy, but depositMax() only deposits min(balance, maxDeposit), leaving the difference trapped in the contract with no recovery mechanism.

Vulnerable Code

VaultV2 Transfers Full Amount to Strategy

File: lib/vault-v2/src/VaultV2.sol

function allocateInternal(address adapter, bytes memory data, uint256 assets) internal {
        require(isAdapter[adapter], ErrorsLib.NotAdapter());

        accrueInterest();

        SafeERC20Lib.safeTransfer(asset, adapter, assets); // <<<<<@ full amt sent
        (bytes32[] memory ids, int256 change) = IAdapter(adapter).allocate(data, assets, msg.sig, msg.sender);

        for (uint256 i; i < ids.length; i++) {
            Caps storage _caps = caps[ids[i]];
            _caps.allocation = (int256(_caps.allocation) + change).toUint256();

            require(_caps.absoluteCap > 0, ErrorsLib.ZeroAbsoluteCap());
            require(_caps.allocation <= _caps.absoluteCap, ErrorsLib.AbsoluteCapExceeded());
            require(
                _caps.relativeCap == WAD || _caps.allocation <= firstTotalAssets.mulDivDown(_caps.relativeCap, WAD),
                ErrorsLib.RelativeCapExceeded()
            );
        }
        emit EventsLib.Allocate(msg.sender, adapter, assets, ids, change);
    }

Strategy Allocation (Fails to Deploy Full Amount)

File: src/strategies/mainnet/TokeAutoEth.sol Lines: 56-63

Router DepositMax (Caps at maxDeposit)

Contract: AutopilotRouter (0x37dD409f5e98aB4f151F4259Ea0CC13e97e8aE21arrow-up-right)

Vulnerability Details

The Token Lock Flow

Step 1: VaultV2 transfers full amount to strategy

Step 2: Strategy approves and calls depositMax

Step 3: Router caps deposit at maxDeposit limit

Step 4: Excess tokens are locked

Root Cause Analysis

The vulnerability arises from a three-way contract interaction failure:

  1. VaultV2 Assumption: Transfers full amount expecting complete deployment

  2. Router Reality: Respects maxDeposit limits and may deposit less

  3. Strategy Gap: No logic to handle partial deposits or return excess funds

The strategy's _allocate() function returns amount (claiming full deployment) even when only a portion was actually deposited, creating an accounting mismatch that traps the difference.

Impact

Severity Justification

  • Permanent Capital Loss: Tokens become irrecoverably stuck in strategy

Replace router.depositMax() with direct vault deposit and enforce limits upfront:

References

Proof of Concept

Proof of Concept

Steps to run POC

  1. Create directory v3-poc/test/TokeAutoEthBugs.t.sol

  2. Paste the snippet below in the newly created file and run with forge test

Was this helpful?