Réentrance d'Origin Dollar (OUSD)
7,7 M$ drainés du coffre stablecoin OUSD deux mois après le lancement via un bug de réentrance par faux stablecoin introduit par un refactor d'économie de gaz.
- Date
- Victime
- Origin Protocol
- Chaîne(s)
- Statut
- Fonds dérobés
Le 17 novembre 2020 à 00h47 UTC, le coffre du stablecoin Origin Dollar (OUSD) a été drainé d'environ 7,7 millions de dollars — 11 809 ETH et 2 249 821 DAI — moins de deux mois après le lancement d'OUSD. L'exploit était une attaque par réentrance d'école rendue possible par une seule vérification de validation manquante qui avait été discrètement supprimée pendant un refactor d'économie de gaz.
Ce qui s'est passé
OUSD permettait aux utilisateurs de créer le stablecoin en déposant des stablecoins sous-jacents acceptés (USDC, USDT, DAI). Les chemins mint() et mintMultiple() du coffre vérifiaient que le jeton déposé était un sous-jacent en liste blanche avant d'appeler transferFrom() sur lui — empêchant exactement le type de réentrance que cette attaque utiliserait plus tard.
Un refactor d'économie de gaz ultérieur a copié la logique de mintMultiple() depuis la fonction mono-jeton mint() mais a omis la vérification de validation pour la liste blanche du jeton sous-jacent. Le bug est ensuite resté indétecté à travers le processus d'audit et de lancement.
L'attaque :
- L'attaquant a créé un faux contrat « stablecoin » qu'il contrôlait entièrement.
- A appelé
mintMultiple()en passant à la fois un vrai stablecoin et le faux stablecoin comme entrées. - Le coffre a accepté le faux contrat (pas de vérification de liste blanche), et a appelé
transferFrom()sur lui pendant la phase de dépôt. - Le
transferFrom()du faux contrat a réintroduit le coffre avant que la première création n'ait fini de mettre à jour l'état de l'offre — déclenchant un événement rebase qui a recalculé les soldes OUSD en utilisant l'état au milieu de la création. - Le rebase a massivement favorisé les avoirs OUSD préexistants de l'attaquant, lui accordant une part disproportionnée des actifs sous-jacents du coffre au moment du retrait.
Total drainé : ~7,7 M$, blanchis via Tornado Cash et renBTC.
Conséquences
- Origin Protocol a publiquement reconnu la perte le même jour et annoncé le remboursement complet des utilisateurs affectés depuis le propre trésor du projet et les fonds personnels de l'équipe.
- Les contrats OUSD ont été redessinés avec une protection complète contre la réentrance sur chaque fonction modifiant l'état et une validation explicite par liste blanche sur chaque interaction avec un jeton sous-jacent.
- Les fonds n'ont jamais été récupérés on-chain.
Pourquoi c'est important
L'incident Origin Dollar est l'un des cas les plus nets pour pourquoi le code audité peut être déployé avec des bugs évitant l'audit. Le mint() original avait la vérification de validation ; l'audit a examiné mint(). Le refactor post-audit a copié la logique mais a laissé tomber la vérification, et il n'y a pas eu de deuxième audit avant le lancement. La classe d'échec — modifications ultérieures au code audité sans nouvel audit — a représenté plusieurs pertes majeures depuis, dont Fei/Rari.
La réponse de l'équipe — remboursement complet depuis les fonds de l'équipe — était également inhabituellement rapide et complète pour l'ère DeFi 2020 ; elle a établi un précédent que d'autres protocoles ont suivi plus tard (et que beaucoup n'ont pas suivi par la suite).
Sources & preuves on-chain
- [01]medium.comhttps://medium.com/originprotocol/urgent-ousd-has-hacked-and-there-has-been-a-loss-of-funds-7b8c4a7d534c
- [02]peckshield.medium.comhttps://peckshield.medium.com/origin-dollar-incident-root-cause-analysis-f27e11988c90
- [03]medium.comhttps://medium.com/originprotocol/what-weve-changed-since-the-ousd-attack-5894f2bd77cf