The claimableBalance is actually a subset of unexchangedBalance, not a separate component. When the strategy calculates total assets, it's counting the claimable portion twice:
Once through unexchangedBalance
Again through underlying.balanceOf()
The bug is in the balance accounting system across all three strategy implementations (StrategyArb.sol, StrategyMainnet.sol, and StrategyOp.sol) when interacting with the Alchemix Transmuter system it affect function balanceDeployed
The root cause lies in the fundamental misunderstanding of the Transmuter's balance accounting system:
When users deposit alETH into the strategy
The Transmuter tracks these deposits as unexchanged balance
When exchange conditions are met, a portion becomes claimable
Impact across supported chains:
Ethereum Mainnet: Affects interactions with Curve pools
Optimism: Impacts Velodrome trading routes
Arbitrum: Affects Ramses exchange operations
The bug creates a systemic overstatement of total assets because:
unexchangedBalance includes all deposited alETH
When portions become claimable, they remain part of unexchangedBalance
After claiming, the same value is counted again through underlying.balanceOf()
This affects:
Share price calculations
Deposit/withdrawal accounting
TVL reporting
Profit/loss calculations
Particularly severe because it operates across three major networks with different DEX integrations (Curve, Velodrome, Ramses) but shares the same fundamental accounting error in the base strategy logic.
Can be exploited through carefully timed deposits and withdrawals that take advantage of the double-counting during claim periods.
In the Transmuter Contract Design:
The Transmuter maintains two key balances:
UnexchangedBalance: Total amount of synthetic tokens (alETH) deposited
ClaimableBalance: Portion of unexchanged balance that can be claimed as underlying (WETH)
In the Strategy Implementation
This creates a systematic overstatement of total assets that compounds with each claim operation, affecting all three network implementations (Ethereum, Optimism, Arbitrum) regardless of which DEX integration is used for swaps.
The bug spreads through the entire accounting system because this balanceDeployed() function is used as the source of truth for total strategy assets.
balanceDeployed()
balanceDeployed()
balanceDeployed()
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.