Yearn Finance and the 16-Wei Deposit That Drained $9 Million
A technical breakdown of how 16 wei became 235 septillion tokens—and the dangers of cached state in DeFi.
Overview
On November 30, 2025, Yearn Finance’s yETH pool on Ethereum suffered a $9 million exploit—one of DeFi’s most capital-efficient attacks. An attacker exploited a cached storage flaw in the pool’s accounting to mint 235 septillion yETH tokens by depositing just 16 wei. The desynchronization between reset supply counters and lingering virtual balances enabled infinite minting. The attacker then swapped the tokens for LSTs like wstETH and rETH.
Yearn confirmed the bug was isolated to a custom stableswap contract—V2/V3 vaults were unaffected. The attacker laundered roughly $3 million in ETH through Tornado Cash, though ~$2.4 million was later recovered. The incident highlights critical risks in gas-optimized storage and “first deposit” logic in AMM designs.
Background on Yearn Finance
Yearn Finance is a decentralized finance (DeFi) aggregator on Ethereum. Launched in 2020, it automates and optimizes yield generation. Its flagship product—Vaults (yVaults)—lets users deposit assets that the protocol automatically allocates across lending and liquidity strategies like Aave or Compound to maximize returns. In exchange, users receive yield-bearing “yTokens” representing their pool share.
Yearn is widely respected for its robust V2 and V3 vault standards, but it also develops specialized financial products for niche markets. The yETH pool—the target of this exploit—was one such custom product. Unlike standard vaults, yETH operated as a “weighted stableswap” AMM designed to trade Liquid Staking Tokens (LSTs) like wstETH and rETH efficiently. This distinction is critical: the vulnerability existed in this custom stableswap logic, not in the protocol’s core vaults, which remained completely unaffected.
Technical Analysis of the Exploit
Incident Overview
Date: November 30, 2025
yETH Weighted Stableswap Pool: 0xccd04073f4bdc4510927ea9ba350875c3c65bf81
Exploiter Address: 0xFb63aa935Cf0a003335dCE9Cca03c4F9c0fa4779
Attack Transaction: 0x53fe7ef190c34d810c50fb66f0fc65a1ceedc10309cf4b4013d64042a0331156
Understanding the Weighted StableSwap Pool
Weighted stableswap pools (WSS) combine stableswap’s low-slippage mechanics for pegged assets with configurable per-token weights. This allows uneven liquidity allocation (e.g., 60/40 instead of 50/50). Unlike equal-weight stableswap, WSS normalizes balances using weights wi (which sum to 1), targeting specific portfolio ratios for correlated assets like LSTs (wstETH/rETH) or stablecoins with imbalances.
A standard stableswap uses a symmetric formula that blends “constant sum” (for low slippage) and “constant product” (for stability), but it enforces equal token quantities. The weighted variant modifies this by baking specific weights directly into the pricing curve. By normalizing balances based on their assigned weights, the pool delivers the same tight spreads and low slippage as a stablecoin pool—even when token quantities differ dramatically.
Yearn yETH Exploit: The Core Mechanism
The attacker executed three phases that systematically exploited vulnerabilities in the yETH stableswap to achieve unlimited token minting:
Phase 1—Collapse the Invariant: Extreme imbalanced deposits forced the Newton-Raphson solver into an unintended regime. The product term (vb_prod) became so small that iteration divergence caused the supply update to round to zero, collapsing the product accumulator Π to 0. This destroyed the weighted-stableswap invariant and caused the solver to return a massively inflated supply D that the protocol accepted without validation.
Phase 2—Drain via POL: With over-minted LP tokens and a broken pool state, the attacker called remove_liquidity(0) to restore a valid Π while keeping D inflated. Then update_rates reconciled the discrepancy by burning yETH from the staking contract’s Protocol-Owned Liquidity (POL)—not from the attacker. Repeated withdrawals using the oversized LP balance drained nearly all pool assets while offloading costs onto the protocol.
Phase 3—Infinite Mint: With the pool emptied (prev_supply = 0), the attacker re-entered the bootstrap initialization path and deposited a configuration violating A⋅Σ≥D⋅Π. The solver’s unsafe arithmetic underflowed, wrapping to the maximum uint256 value and producing approximately 2.35 × 10^56 yETH tokens.
Now let’s examine the attack transaction.
Attack Flow
The attacker executed a precision attack that exploited state desynchronization to mint tokens from nothing.
Flash Loan Liquidity: The attacker borrowed large amounts of liquid staking tokens (LSTs)—wstETH, rETH, and cbETH—from the yETH pool via flash loan.
State Desynchronization (The Setup): Using the flash-loaned capital, the attacker executed rapid deposits and withdrawals to manipulate the contract’s accounting. The target was a gas-saving feature: the
packed_vbs(packed virtual balances) variable, which cached balance data to reduce transaction costs. By repeatedly updating this cache while simultaneously withdrawing real assets, the attacker created a critical state contradiction: the pool’s actual liquidity dropped to near zero, but the cachedpacked_vbsvariable still held “phantom” values indicating the pool was full. This poisoned cache set the trap for the next step.Resetting Total Supply: The attacker withdrew all assets, reducing the pool’s
totalSupplyto zero. In a healthy state, this should reset the pool. However, thepacked_vbscache was neither cleared nor synchronized—it retained “phantom” values from the previous state.The Infinite Mint Trigger: With the pool’s totalSupply reset to zero, the attacker deposited just 16 wei spread across the tokens. This triggered the contract’s “initial deposit” logic—a critical initialization phase that sets the pool’s pricing curve. But due to the desynchronization, the contract calculated the invariant
Dusing stale, inflated values from the poisoned packed_vbs cache instead of the actual 16 wei deposit. This mathematical mismatch tricked the protocol into treating the tiny deposit as equivalent to the massive “phantom” liquidity, minting 235 septillion yETH shares to the attacker.Profit Extraction: Holding virtually unlimited yETH shares, the attacker then turned to the open market to cash out. They utilized liquidity pools on Balancer and Curve to swap the newly minted yETH for real underlying assets (like wstETH and rETH), effectively draining approximately $9 million from the ecosystem before the exploit was halted.
Conclusion
The exploit resulted from a cascade of logical and numerical failures that let the attacker desynchronize the pool’s state and trigger a catastrophic underflow.
State Desynchronization via Numerical Instability: The protocol used internal variables—specifically the product term
Πand invariantD—to track the pool’s liquidity curve. Under large relative deposits, the solver’s iteration logic became numerically unstable, causing these variables to diverge. This instability drove the product termΠto zero while the invariantDremained inflated, breaking the fundamental mathematical relationship between them.The “Zero-Supply” Trap: The code allowed the pool’s internal supply counter
Dto drop to zero while actual token balances (Protocol-Owned Liquidity) still existed. This let the attacker reach theprev_supply == 0state—a “bootstrap” branch intended only for initial deployment—on a mature, active pool.The Catastrophic Underflow: The fatal blow occurred in the
_calc_supplyfunction when the contract recalculated the new liquidity. The formulaval = A * Σ - D * Πassumed thatA * Σwould always exceedD * Π. Because the attacker had drivenΠto zero (step 1), this assumption failed. The contract usedunsafe_sub(unchecked subtraction) for this operation. Instead of reverting, the subtraction underflowed, wrapping from a negative result to a near-infinite integer (2^256).





