Skip to content
Est. MMXXVIVol. VI · № 273RSS
Blockchain Breaches

An archive of cryptocurrency security incidents — hacks, exploits, bridge failures and rug pulls, documented with on-chain evidence.

Dossier № 064Smart Contract Bug

MonoX Same-Token Swap

$31M drained from MonoX's single-token pools after the attacker swapped a token with itself, pumping MONO in the protocol's own oracle until pools emptied.

Date
Status
Funds Stolen

On November 30, 2021, the single-pool AMM MonoX Finance lost approximately $31 million across its Ethereum and Polygon deployments. The bug was almost too simple to be real: the swap contract did not check whether the input token and the output token were the same.

What happened

MonoX used a novel "single-pool" AMM design where every token was paired against the protocol's MONO governance token internally, rather than against other tokens directly. A swap from token A to token B was implemented as A → MONO → B in two internal steps, each updating the relevant token prices.

The fatal omission: the swap function did not validate that tokenIn ≠ tokenOut. When a user swapped MONO for MONO, the price-update logic ran on both legs:

  1. The "sell" leg of the swap pushed MONO's price down (typical AMM behaviour).
  2. The "buy" leg pushed MONO's price up.
  3. Crucially, the price-update functions ran sequentially, and the tokenOut price update happened last — so the protocol ended the transaction with MONO's price massively inflated.

The attack loop:

  1. Swap MONO for MONO repeatedly, pumping MONO's recorded price.
  2. Swap the artificially expensive MONO for real assets — WETH, WMATIC, WBTC, USDC, USDT, LINK, GHST, DUCK, MIM, IMX.
  3. Repeat until each pool was drained.

Total losses on Polygon + Ethereum: ~2,100 WETH, 1.9M WMATIC, 36 WBTC, $8.2M USDC, $9.1M USDT and a long tail of other tokens, summing to ~$31M.

Aftermath

  • MonoX paused both deployments and announced a recovery plan.
  • The attacker laundered through Tornado Cash; no public recovery.
  • MonoX never returned to its pre-incident standing.

Why it matters

MonoX is the textbook case for how a single missing equality check can be a fully-loaded exploit primitive. The bug — require(tokenIn != tokenOut) — is exactly one line of code. Its absence cost $31M.

The deeper lesson is the recurring one for novel AMM designs: every claimed invariant of the AMM must be tested across the full input space, including obviously-degenerate cases. The "swap a token for itself" case is degenerate from the user's perspective — no one would ever want to do it. From the protocol's perspective, it's a state-update path that produces unconstrained price drift. Modern AMM testing frameworks (Echidna, Foundry invariants) specifically generate degenerate inputs to surface exactly this class of bug.

Sources & on-chain evidence

  1. [01]slowmist.medium.comhttps://slowmist.medium.com/detailed-analysis-of-the-31-million-monox-protocol-hack-574d8c44a9c8
  2. [02]cryptobriefing.comhttps://cryptobriefing.com/monox-finance-drained-of-31m-in-latest-defi-hack/
  3. [03]immunebytes.comhttps://immunebytes.com/blog/monox-hack-incident-nov-30-2021-detailed-analysis/

Related filings