58449 sc medium tokeautoeth strategy balance approval mismatch dos

Submitted on Nov 2nd 2025 at 13:20:13 UTC by @T0nraq for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58449

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

    • Smart contract unable to operate due to lack of token funds

Description

Summary

The TokeAutoEth strategy's _allocate() function approves only the requested amount to the router but then calls router.depositMax(), which attempts to deposit the entire WETH balance of the strategy contract. When the strategy's balance exceeds the approval EVEN BY 1 WEI (due to residual rewards, previous withdrawal leftovers, or donations), the transaction reverts.

Vulnerable Code

Strategy Allocation (Approves only amount)

File: src/strategies/mainnet/TokeAutoEth.sol

function _allocate(uint256 amount) internal override returns (uint256) {
    require(TokenUtils.safeBalanceOf(address(weth), address(this)) >= amount, "Strategy balance is less than amount");
    
    // Only approves `amount` to router
    TokenUtils.safeApprove(address(weth), address(router), amount);
    
    // But depositMax() tries to deposit entire balance!
    uint256 shares = router.depositMax(autoEth, address(this), 0);
    
    TokenUtils.safeApprove(address(autoEth), address(rewarder), shares);
    rewarder.stake(address(this), shares);
    return amount;
}

Router DepositMax (Deposits entire balance)

Contract: AutopilotRouter (0x37dD409f5e98aB4f151F4259Ea0CC13e97e8aE21arrow-up-right)

Vulnerability Details

The Balance-Approval Mismatch Flow

Step 1: Strategy approves only requested amount

Step 2: Router reads entire balance

Step 3: Router attempts to pull more than approved

How Extra Balance Accumulates

  1. Reward Claims: When rewarder.withdraw(claim=true) is called during deallocations, extra reward tokens are sent to the strategy

  2. Withdrawal Leftovers: Slippage or rounding in autoEth.redeem() may leave dust amounts

  3. Direct Transfers: Accidental or malicious transfers of >= 1 wei of WETH to the strategy will PERMANENTLY cause the strategy to always revert during deallocation.

Root Cause

The AutopilotRouter.depositMax() function uses balanceOf(msg.sender) to determine the deposit amount, completely ignoring the approval. This creates a fundamental mismatch when any extra balance exists in the strategy contract.

Impact

Severity Justification

  • This will render the startegy completely unuseable as it will always revert.

Approve Entire Balance

If using depositMax() is required, approve the entire balance instead:

References

Proof of Concept

Proof of Concept

Test File: Create/Add snippet to test/TokeAutoEthBugs.t.sol

Run with:

Was this helpful?