Yearn's yETH weighted stableswap pool exploited through numerical instability in fixed-point iteration solver. Attacker collapsed product term to zero, switching pool to constant-sum invariant, then triggered arithmetic underflow to mint 2.35×10⁵⁶ LP tokens.
On November 30, 2025, Yearn's yETH weighted stableswap pool was exploited for approximately $9 million. The attacker exploited a numerical instability in the pool's fixed-point iteration solver, causing the virtual balance product term (Π) to collapse to zero. This effectively switched the pool from its intended hybrid stableswap invariant to a constant-sum curve, allowing the attacker to systematically over-mint LP tokens. After draining the pool, a secondary arithmetic underflow in the same solver minted approximately 2.35 × 10⁵⁶ yETH LP tokens, which were used to drain the yETH/WETH Curve pool. Yearn's V2 and V3 vaults were not affected as yETH was an isolated product with separate code.
The yETH pool implemented an amplified, weighted stableswap AMM designed for liquid staking tokens (LSTs). The pool tracked per-asset virtual balances through external rate providers, maintaining two aggregate quantities: a sum term (Σ) representing the total of all virtual balances, and a product term (Π) computed from weighted virtual balances. The supply invariant D was calculated using a fixed-point iteration solver in the _calc_supply function.
The core vulnerability resided in the fixed-point iteration used to compute the supply. The iteration formula derived from the yETH whitepaper was:
D_{m+1} = (A * f^n * Σ - D_m * π_m) / (A * f^n - 1)
π_m = (D_m / D_{m-1})^n * π_{m-1}
The implementation used unchecked arithmetic operations (unsafe_sub, unsafe_mul, unsafe_div) and did not enforce convergence or sanity checks. When the solver entered a divergent regime, the ratio D_{m+1} / D_m could become extremely small. Raising this sub-unitary value to the 8th power (for 8 assets) and multiplying by the current product term would truncate to zero in integer arithmetic.
The attack proceeded in three phases. In Phase 1, the attacker performed a sequence of add_liquidity and remove_liquidity operations with extremely imbalanced deposits. This forced the solver into a regime where the iteration diverged rather than converged. When the second iteration computed s' ≈ 1.94e18 compared to s ≈ 1.09e22, the ratio s'/s was so small that r' = r * (s'/s)^8 rounded to zero.
Once Π = 0, the solver formula simplified to:
s' = (A * Σ) / (A - PREC)
This is equivalent to a constant-sum invariant, which systematically over-mints LP tokens for unbalanced deposits compared to the intended stableswap curve. The attacker exploited the asymmetry between these curves: when reserves are imbalanced, the constant-sum curve mints more LP tokens than the stableswap curve for the same deposit.
In Phase 2, the attacker repeatedly cycled between the corrupted state (Π = 0, inflated supply) and a restored state. The key insight was that remove_liquidity(0) would recompute Π from scratch without burning any LP tokens, while update_rates would reconcile the supply by burning yETH from the st-yETH staking contract. This allowed the attacker to:
add_liquidityremove_liquidity(0) to restore Π to a non-zero valueupdate_rates to reconcile the inflated D against Protocol-Owned LiquidityThis cycle was repeated until the pool was drained to Σ = 0, Π = 0, D = 0.
In Phase 3, with the pool empty but still accepting deposits, the attacker deposited dust amounts: [1, 1, 1, 1, 1, 1, 1, 9] wei across the 8 LST assets. This triggered the bootstrap initialization path with prev_supply == 0. The dust deposit produced Σ ≈ 16 and a recomputed Π ≈ 4.28e19. In this invalid state, when the solver computed:
s' = (l - s * r) / d
The term s * r exceeded l, and the unchecked subtraction underflowed. In EVM's 256-bit arithmetic, this wrapped to approximately 2^256, producing a supply of:
D' ≈ 2^256 / (4.49e20) ≈ 2.35e56
All these LP tokens were minted to the attacker, who then used them to drain the yETH/WETH Curve pool for an additional ~$1 million.
The exploit resulted in approximately $9 million in losses. The yETH weighted stableswap pool lost $8 million in LST assets including apxETH, sfrxETH, wstETH, cbETH, rETH, ETHx, mETH, and wOETH. The yETH/WETH Curve pool lost an additional $0.9 million in WETH. With assistance from the Plume and Dinero teams, Yearn recovered 857.49 pxETH worth approximately $2.4 million. The attacker laundered 1,000 ETH ($3 million) through Tornado Cash during the attack transaction itself.
Yearn's V2 and V3 vaults were completely unaffected as yETH was a separate product with isolated code and no shared infrastructure. The exploit was confined to the yETH stableswap pool and its direct integrators. Under YIP-72 §8, yETH depositors acknowledged a "use at own risk" clause, meaning Yearn governance is not liable for reimbursement.
Yearn convened a war room within hours of the attack. The team coordinated with Plume and Dinero to recover 857.49 pxETH by burning the tokens held by the attacker. A message was sent to the exploiter on December 1, 2025, but the remaining funds were subsequently sent to Tornado Cash on December 5, 2025.
The yETH pool was audited by ChainSecurity in June 2023, but the specific combination of states required to trigger the vulnerability was not discovered until the exploit. The incident highlights critical lessons for AMM design: numerical solvers must enforce convergence and domain validity checks, degenerate states like Π = 0 should trigger reverts, and unchecked arithmetic should never be used in invariant-critical code paths.
Related Addresses:
In DeFi, a small delay costs millions.
Get the threat intelligence to rely on.