Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
The _allocate function in TokeAutoUSDStrategy sets the minSharesOut parameter to zero when depositing USDC into the Tokemak AutoUSD vault via the Autopilot Router. This allows the strategy to accept any amount of shares in return, including amounts significantly below expected value. According to Tokemak's official integration documentation, slippage protection is necessary during Autopool deposits to prevent value loss, as share prices can fluctuate due to debt reporting timing and market conditions.
Vulnerability Details
The _allocate function in TokeAutoUSDStrategy.sol lacks slippage protection when depositing into the Tokemak Autopool:
function_allocate(uint256amount)internaloverridereturns(uint256){require(TokenUtils.safeBalanceOf(address(usdc),address(this))>= amount,"Strategy balance is less than amount"); TokenUtils.safeApprove(address(usdc),address(router), amount);uint256 shares = router.depositMax(autoUSD,address(this),0);// @audit minSharesOut = 0 TokenUtils.safeApprove(address(autoUSD),address(rewarder), shares); rewarder.stake(address(this), shares);return amount;}
The Issue:
The third parameter of router.depositMax() is minSharesOut, which specifies the minimum acceptable shares to receive. Setting this to 0 means the transaction will succeed regardless of the share-to-asset exchange rate, even if unfavorable.
Root Cause:
According to Tokemak's documentation, Autopools can experience slippage during deposits because:
Share prices are affected by periodic debt reporting cycles
The debt reporting may not reflect the most current state
Market conditions can change between transaction submission and execution
Share-to-asset conversion rates are not constant
Impact Scenario:
Allocator initiates allocation of 100,000 USDC
At transaction submission, expected shares = 100,000 (1:1 ratio for simplicity)
Before transaction execution, debt reporting updates or market moves
Actual shares received = 95,000 (5% unfavorable slippage)
Transaction succeeds because minSharesOut = 0 provides no protection
Strategy permanently has 5,000 fewer shares than it should
When the strategy later deallocates these shares, it can only redeem what it actually holds (95,000 shares ≈ 95,000 USDC), resulting in permanent loss of the missing 5,000 USDC worth of value.
Impact Details
The vulnerability causes permanent loss of depositor funds through acceptance of unfavorable share exchange rates without validation.
Nature of the Loss:
When the strategy receives fewer shares than expected due to slippage:
The missing shares represent permanently lost value
This value cannot be recovered through deallocation
The strategy can only redeem the shares it actually received
Vault depositors bear the loss
Quantified Example (from PoC):
For a 100,000 USDC allocation experiencing 5% slippage:
Deposited: 100,000 USDC
Expected shares: 100,000
Actual shares received: 95,000
Missing value: 5,000 USDC equivalent
When later redeemed:
Can redeem: 95,000 shares → ~95,000 USDC
Cannot recover: 5,000 USDC (permanently lost)
Severity Factors:
Slippage likelihood depends on:
Debt reporting frequency and timing
Network congestion (transaction delay)
Autopool activity levels
Market volatility
Expected loss ranges:
Varies upto a 100% as it accepts zeo shares
Cumulative impact:
Strategy performs multiple allocations over time
Each allocation without slippage protection can incur losses
Losses accumulate and compound
Example Cumulative Loss:
For a strategy managing $10M with 10 allocation operations:
10 allocations of $1M each
Average 1% slippage per allocation (conservative estimate)
Total permanent loss: $100,000
The loss is borne by vault depositors and represents theft of expected value that should have been captured during the allocation process.
"Depending on the conditions of the Autopool, the overall market, and the timing of the debt reporting process slippage may be encountered on both entering and exiting the Autopool. It is very important to always check the shares received on entering, and the assets received on exiting, are greater than an expected amount."
Implement slippage protection using the Autopool's previewDeposit() function with the strategy's existing slippageBPS parameter:
This fix:
Queries expected shares before deposit
Calculates minimum acceptable shares using the strategy's slippageBPS setting
Passes minShares to depositMax() instead of 0
Validates received shares meet the minimum threshold
Reverts if slippage exceeds tolerance, protecting depositor funds
Proof of Concept
Proof of Concept
Add the following test to src/test/strategies/TokeAutoUSDStrategy.t.sol:
Run with:
Test Output:
The test demonstrates that when 5% slippage occurs, the strategy loses 5,000 USDC in value but the transaction still succeeds because minSharesOut = 0 provides no protection.