# Yearn yETH $9M Numerical Solver Exploit

> 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.

Source: https://defimon.xyz/blog/yearn-yeth-hack-november-2025 · Published: 2025-11-30 · Network: Ethereum · Impact: $9.00M

---

## TLDR

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.

## Technical Analysis

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:

1. Trigger Π = 0 via imbalanced `add_liquidity`
2. Mint excess LP tokens under the constant-sum regime
3. Call `remove_liquidity(0)` to restore Π to a non-zero value
4. Call `update_rates` to reconcile the inflated D against Protocol-Owned Liquidity
5. Withdraw more assets than deposited using the over-minted LP tokens

This 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.

## Impact Assessment

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.

## Response and Recovery

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](https://etherscan.io/tx/0x919dc0d056953e7449e7e6e4044fc991d0feebab195e9239750d584fd8179607) 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](https://github.com/yearn/yearn-security/blob/master/audits/20230626_ChainSecurity_yeth_core/ChainSecurity_Yearn_Yearn_yETH_audit.pdf) 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:**

- Attacker: [0xa80D3F2022F6Bfd0B260bF16D72CaD025440C822](https://etherscan.io/address/0xa80D3F2022F6Bfd0B260bF16D72CaD025440C822)
- Exploit Contract: [0xB8e0A4758Df2954063Ca4ba3d094f2d6EdA9B993](https://etherscan.io/address/0xB8e0A4758Df2954063Ca4ba3d094f2d6EdA9B993)
- Victim Pool: [0xCcd04073f4BdC4510927ea9Ba350875C3c65BF81](https://etherscan.io/address/0xCcd04073f4BdC4510927ea9Ba350875C3c65BF81)

## References

- https://github.com/banteg/yeth-exploit/blob/main/report.pdf
- https://github.com/yearn/yearn-security/blob/master/disclosures/2025-12-01.md
- https://slowmist.medium.com/9-million-stolen-analysis-of-the-yearn-yeth-pool-vulnerability-557237092054
- https://x.com/0xKaden/status/1996643983964184731
- https://app.blocksec.com/explorer/tx/eth/0x53fe7ef190c34d810c50fb66f0fc65a1ceedc10309cf4b4013d64042a0331156

