Incorrect balance accounting during state transitions in the transmuter deposit process
When funds are deposited via transmuter.deposit(), they simultaneously appear in:
unexchangedBalance (via transmuter)
underlying.balanceOf (not immediately cleared)
The balanceDeployed() function adds both these balances together, effectively counting the same funds twice during the deposit state transition.
This is a state transition vulnerability where the contract fails to properly account for the intermediate state where funds exist in multiple accounting buckets simultaneously.
The actual balance change after deployment doesn't match the expected amount, due to this double counting during the state transition period.
In all strategy contracts (StrategyArb.sol, StrategyMainnet.sol, StrategyOp.sol), the vulnerability lies in the balance accounting during the deposit and claim process.
The fundamental issue is in the state transition handling between these token states
WETH (underlying) -> alETH (asset) conversion
Unexchanged balance in transmuter
Claimable balance from transmuter
The balanceDeployed() function adds all these balances together, but during state transitions (deposit/claim/swap), the same value can exist in multiple states simultaneously, leading to inflated balance reporting.
Impact
Share Price Manipulation: Incorrect total assets calculation affects share price
Accounting Errors: Strategy reports more assets than actually controlled
Cross-chain Implications: Affects all implementations (Arbitrum, Optimism, Mainnet) due to shared architecture
Specific Vulnerabilities
The issue affects all supported tokens:
WETH <-> alETH conversions
Yearn V3 tokenized strategy accounting
This particularly affects the core accounting mechanism across all three blockchain implementations, potentially impacting the entire Alchemix ecosystem's balance reporting accuracy.
function _deployFunds
function _deployFunds
function _deployFunds
function claimAndSwap
function claimAndSwap
function claimAndSwap
function balanceDeployed
function balanceDeployed
function balanceDeployed
As th bug is caused by incorrect balance accounting during state transitions in the transmuter system.
Deposit Flow Issue
Claim and Swap Flow Issue
The root cause is the lack of atomic state transitions in the balance accounting system. When funds move between states (underlying -> transmuter -> asset), they temporarily exist in multiple balance categories simultaneously. The balanceDeployed() function adds these balances together without accounting for these transition states, leading to double counting.
This also affects all three implementations (StrategyArb.sol, StrategyMainnet.sol, StrategyOp.sol) because they share the same fundamental accounting structure and interaction pattern with the transmuter system.
In this mitigations we implement
Explicit Balance State Tracking:
Introduces state enumeration for different token states
Maintains clear separation between underlying, unexchanged, and claimed balances
Atomic Balance Transitions:
Adds pre and post balance checks for state transitions
Ensures balance consistency during deposit and claim operations
Single Source of Truth:
Simplifies balanceDeployed() to prevent double counting
Removes underlying balance from total calculation
Balance Consistency Checks:
Adds requirements to verify balance transitions
Prevents invalid state transitions during operations
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.