On 2026-08-09, an attacker on Ethereum drained ~70.83 ETH from USM by minting FUM with a Morpho flash loan and redeeming it across 64 small `defund` slices instead of one large redemption.
Logged as “2026-08-09: Defund Price Split Invariance Rounding Exploit on USM”.
USM (Minimalist USD stablecoin, 0x2a7FFf44C19f39468064ab5e5c304De01D591675) issues FUM (0x86729873e3b88DE2Ab85CA292D6d6D69D548eDF3), an ETH-denominated claim. defund() redeems FUM for ETH, priced off the arithmetic mean of the current FUM sell price and the estimated final FUM sell price after the redemption, and each defund() also contracts internal state through adjShrinkFactor. That averaging is not "split invariant": redeeming one large FUM amount in a single defund() pays strictly less ETH than redeeming the same total FUM amount as many small equal slices across consecutive defund() calls. The per-call state contraction plus integer rounding compound the gap. An attacker who minted a large FUM position with fund() and then redeemed it in many small slices instead of one extracted more ETH than it paid in.
This is a pure pricing-and-rounding logic flaw, not a price manipulation. The Chainlink/Uniswap TWAP oracle reads are identical before and during the attack (same latestPrice() return every call in the trace); nothing about the ETH/USD price is moved. The Morpho Blue flash loan only supplied working capital to fund() a big FUM position; it is not used to move any price.
The attacker (EOA 0xb92b2E47680c89DA8f951B8963ef469f461a50Fc, via attack contract 0x5a5e29ba89663a3558273354E990426F3cAc7de7) ran the exploit in 0xfae5e751b8ce01457cbb6b529839f24a0cff50faaabcbd0fd02ca0cf559b050e on Ethereum block 25,716,150. Inside the Morpho flash-loan callback the attacker unwrapped 11,579.978 WETH, fund()-ed the whole amount, then ran 64 defund() calls of ~971,629 FUM each (the same split the attacker used), re-wrapped the proceeds, and repaid the flash loan. Net ETH gain landed near the reported ~70.83 ETH.
Every fund() and defund() in the sequence is a plain permissionless public call made by the attacker contract inside the Morpho flash-loan callback. No signer, no admin role, no privileged path. fund(to, minFumOut) and defund(to, fumToBurn, minEthOut) are open to any caller.
The fix is to make defund() linear in fumToBurn, so the same total input always pays the same total output regardless of how it is sliced. The deeper fix is to remove the per-call state contraction entirely or to cap its effect per call to a small fraction of the state, so a single attacker cannot amplify returns by slicing.
Query every incident yourself — free, no signup
Updated 14 Oct 2026. Figures are as reported by the sources listed above and are not independently verified.