Aller au contenu
Fondé MMXXVIVol. VI · № 273RSS
Blockchain Breaches

Archive des incidents de sécurité dans les cryptomonnaies — piratages, exploits, défaillances de ponts et rug pulls, documentés avec des preuves on-chain.

Dossier № 064Bug de smart contract

Swap d'un même jeton sur MonoX

31 M$ drainés des pools mono-jeton de MonoX après que l'attaquant a échangé un jeton avec lui-même, gonflant MONO dans l'oracle propre jusqu'à vider les pools.

Date
Chaîne(s)
Statut
Fonds dérobés

Le 30 novembre 2021, l'AMM mono-pool MonoX Finance a perdu environ 31 millions de dollars sur ses déploiements Ethereum et Polygon. Le bug était presque trop simple pour être réel : le contrat de swap ne vérifiait pas si le jeton d'entrée et le jeton de sortie étaient identiques.

Ce qui s'est passé

MonoX utilisait une conception AMM « mono-pool » novatrice où chaque jeton était apparié en interne contre le jeton de gouvernance MONO du protocole, plutôt que directement contre d'autres jetons. Un swap du jeton A vers le jeton B était implémenté comme A → MONO → B en deux étapes internes, chacune mettant à jour les prix des jetons concernés.

L'omission fatale : la fonction de swap ne validait pas que tokenIn ≠ tokenOut. Lorsqu'un utilisateur échangeait MONO contre MONO, la logique de mise à jour des prix s'exécutait sur les deux jambes :

  1. La jambe de « vente » du swap poussait le prix de MONO vers le bas (comportement AMM typique).
  2. La jambe d'« achat » poussait le prix de MONO vers le haut.
  3. De manière cruciale, les fonctions de mise à jour de prix s'exécutaient séquentiellement, et la mise à jour du prix tokenOut se produisait en dernier — de sorte que le protocole terminait la transaction avec le prix de MONO massivement gonflé.

La boucle d'attaque :

  1. Échanger MONO contre MONO à plusieurs reprises, gonflant le prix enregistré de MONO.
  2. Échanger le MONO artificiellement coûteux contre de vrais actifs — WETH, WMATIC, WBTC, USDC, USDT, LINK, GHST, DUCK, MIM, IMX.
  3. Répéter jusqu'à ce que chaque pool soit drainé.

Pertes totales sur Polygon + Ethereum : ~2 100 WETH, 1,9 M WMATIC, 36 WBTC, 8,2 M$ USDC, 9,1 M$ USDT et une longue traîne d'autres jetons, totalisant ~31 M$.

Conséquences

  • MonoX a mis en pause les deux déploiements et annoncé un plan de récupération.
  • L'attaquant a blanchi via Tornado Cash ; aucune récupération publique.
  • MonoX n'est jamais revenu à son standing pré-incident.

Pourquoi c'est important

MonoX est le cas d'école pour comment une seule vérification d'égalité manquante peut être une primitive d'exploit pleinement chargée. Le bug — require(tokenIn != tokenOut) — est exactement une ligne de code. Son absence a coûté 31 M$.

La leçon plus profonde est celle qui se répète pour les conceptions AMM novatrices : chaque invariant revendiqué de l'AMM doit être testé sur tout l'espace d'entrée, y compris les cas manifestement dégénérés. Le cas « échanger un jeton contre lui-même » est dégénéré du point de vue de l'utilisateur — personne ne voudrait jamais le faire. Du point de vue du protocole, c'est un chemin de mise à jour d'état qui produit une dérive de prix non contrainte. Les frameworks modernes de test AMM (Echidna, invariants Foundry) génèrent spécifiquement des entrées dégénérées pour faire surface exactement cette classe de bug.

Sources & preuves on-chain

  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/

Dépôts liés