Root Cause
Moonwell on Base priced MAMO using a spot-price oracle backed by a DEX pool with thin liquidity (MAMO market cap under $2M pre-attack). The oracle read the pool's instantaneous reserve ratio, which an attacker could shift via direct ERC-20 transfers — bypassing swap-fee mechanics while still moving the price used by the collateral valuation.
// Uniswap-v2-style spot price (vulnerable to direct-transfer inflation)
function getReserves() public view returns (
uint112 reserve0, // MAMO
uint112 reserve1, // USDC
uint32 blockTimestampLast
) {
reserve0 = _reserve0;
reserve1 = _reserve1;
// Direct ERC20.transfer(poolAddress, amount) raises _reserve0
// without going through swap(); spot price MAMO/USDC = reserve1 / reserve0
// → MAMO price drops in ratio terms, inflating apparent MAMO value
}
// No TWAP, no minimum-liquidity guard, no circuit breaker on oracle read
With no TWAP window, price could be moved from ~$0.0105 to ~$0.43 (~43×) at low cost.
Attack Steps
| Step | Action | Detail |
|---|---|---|
| 1 | Source MAMO | Accumulated MAMO at the prevailing price (~$0.0105) |
| 2 | Direct-transfer inflation | Sent MAMO directly to the DEX pool contract, bypassing the router; raised pool's MAMO reserve without paying swap fees |
| 3 | Swap-based pumping | Combined with swap-path trades to push MAMO/USD spot to ~$0.43 (~43×) |
| 4 | Oracle registers spike | Moonwell's price feed read the inflated pool spot |
| 5 | Deposit collateral | Supplied artificially valued MAMO to Moonwell |
| 6 | Borrow assets | Withdrew cbBTC, WETH, USDC, and wstETH from four markets |
| 7 | Extraction window | $11,028,762 gross borrowed between 06:09–09:30 UTC (~3 h 20 min) |
| 8 | Consolidation | Proceeds converted to DAI, consolidated in a single wallet |
| 9 | Protocol freeze | Moonwell set borrow caps and MAMO/WELL supply caps to 1 wei |
Impact
- Gross borrowed: ~$11.0M across cbBTC, WETH, USDC, wstETH markets
- Net protocol loss: ~$8.7M (after liquidated collateral and residual bad debt)
- WELL token: fell ~13% in 24 hours post-exploit
- Revenue comparison: $8.7M loss exceeded Moonwell's entire annual protocol revenue
- Incident count: Moonwell's third security incident in 11 months (prior: cbETH oracle mispricing → $1.8M bad debt, Feb 2026; a governance exploit earlier in 2026)
Lessons for Auditors
-
Direct-transfer oracle inflation is cheaper than swap-based manipulation. Sending tokens directly to a Uniswap-v2-style pool inflates the reserve without paying the swap fee. Auditors must flag every oracle that reads pool reserves rather than a time-weighted average.
-
Spot oracles on illiquid assets require explicit guardrails. Any asset with under $10M in DEX liquidity should be priced exclusively via TWAP (minimum 30-minute Uniswap v3 observation window or a Chainlink feed with a staleness bound).
-
Collateral factor and liquidity depth must be co-governed on-chain. Enforce an on-chain invariant: if
poolLiquidity < threshold, the collateral factor automatically drops to 0. -
Implement price-bound circuit breakers. Reject oracle readings that deviate more than (e.g.) 20% from the TWAP within a single block. This aborts the attack before borrowed funds leave the protocol.
-
Treat repeat victims as structurally vulnerable. Three incidents in 11 months at the same protocol signals an architectural pattern, not isolated bugs. Auditors reviewing Moonwell or forks should dedicate additional coverage to oracle and collateral configuration.