Retour au blog

Blog

Anatomie d'une attaque par manipulation d'oracle en DeFi

La manipulation d'oracle est le pattern d'attaque le plus régulièrement réussi de l'histoire de la DeFi. Voici comment ça marche, pourquoi ça continue de marcher, et les choix de design qui l'empêchent.

Si vous lisez les post-mortems d'exploits DeFi pendant un an, un pattern saute aux yeux : la plupart parlent de « manipulation d'oracle » dès le premier paragraphe. Pas reentrancy, pas access control, la manipulation d'oracle, exécutée via flash loan.

Le pattern continue de marcher parce que l'erreur de design sous-jacente, pricer des décisions précieuses du protocole sur une seule source on-chain manipulable, continue d'être livrée en production. Cet article décrit comment l'attaque marche, pourquoi les protocoles continuent à construire ainsi, et les choix de design qui l'empêchent.

L'attaque, de bout en bout

Une attaque canonique de manipulation d'oracle a quatre étapes :

  1. Emprunter. L'attaquant prend un flash loan de, disons, 100 M$ de WETH. Pas de collatéral, pas de check de crédit ; juste un appel de fonction de smart contract.
  2. Manipuler. Il utilise le capital emprunté pour swap un gros montant à travers une pool AMM peu liquide, que le protocole cible utilise comme oracle de prix. Le prix rapporté de la pool bouge dramatiquement.
  3. Exploiter. Il interagit avec le protocole cible, emprunt, mint, retrait, au prix manipulé. Peut-être qu'il emprunte 50 M$ contre 5 M$ de vrai collatéral, valorisé au mauvais prix par l'oracle. Peut-être qu'il rachète une position LP pricée à la mauvaise NAV.
  4. Rembourser. Il rembourse le flash loan dans la même transaction. Résultat net : il repart avec les fonds du protocole cible, et le capital emprunté est revenu d'où il vient.

La séquence entière se déroule en un bloc. Le protocole n'a aucune occasion de réagir.

Pourquoi ça marche

Le prix on-chain de toute paire AMM, c'est le prix que le prochain swap peut atteindre. Dans une pool profonde et liquide, ETH/USDC sur Uniswap, des milliards de dollars, bouger le prix de manière significative coûte plus que ce que tout flash loan peut financer. Dans une pool peu liquide, quelques millions peuvent bouger le prix de 50 % ou plus.

Un protocole qui price ses opérations contre une pool peu liquide price, par définition, ses opérations contre un nombre que l'attaquant peut choisir le temps d'une transaction.

Le péché originel, c'est de lire le prix spot d'un seul AMM et de lui faire confiance. Le correctif, c'est de ne jamais faire ça.

Pourquoi ça continue de livrer

Dans notre activité Smart Contract Audit, nous trouvons toujours ce pattern dans du nouveau code. Il continue de livrer pour quelques raisons :

Le TWAP a l'air d'être de la sur-ingénierie en dev. Le prix spot, c'est une ligne ; un TWAP demande de la logique d'accumulateur, de la gestion de fenêtre, et du gas. En environnement de test où les prix ne bougent pas adversariallement, le prix spot marche très bien.

L'intégration est pratique. Tirer le prix de votre propre AMM, c'est pas de dépendance externe, pas d'abonnement oracle, pas d'intégration Chainlink. Ça paraît simple, mais c'est du couplage.

L'attaque n'est pas évidente sans flash loans dans le modèle de menace. Un développeur qui ne pense pas activement aux flash loans raisonne : « il faudrait à un attaquant 100 M$ pour bouger ce prix ; personne n'a 100 M$ ; donc c'est OK. » Le modèle de menace flash loan casse ce raisonnement.

Ça marche jusqu'à ce que ça ne marche plus. Beaucoup de protocoles livrent avec des oracles manipulables, tournent des mois sans incident, et accumulent assez de TVL pour devenir dignes d'être attaqués. Puis un jour un chercheur (ou un voleur) écrit l'exploit, et le post-mortem dit « manipulation d'oracle ».

Les patterns spécifiques qui l'empêchent

Trois choix de design, utilisés ensemble, neutralisent l'attaque :

1. Utilisez des TWAPs, pas des prix spot

Un time-weighted average price calculé sur une fenêtre de 30 minutes (ou plus) ne peut pas être bougé par un seul bloc, quel que soit le capital de l'attaquant. Un attaquant qui veut manipuler un TWAP de 30 minutes doit tenir le prix manipulé pendant 30 minutes, en s'exposant à l'arbitrage de tous les autres acteurs du marché.

Uniswap v3 expose un oracle TWAP nativement. Utilisez-le. Les quelques lignes de code en plus sont l'assurance la moins chère que vous achèterez jamais.

2. Utilisez des sources d'oracle redondantes

Si le pricing de votre protocole dépend d'un seul oracle, la sécurité de votre protocole dépend de cet oracle. Utilisez-en deux : un feed Chainlink plus un TWAP, par exemple. Exigez que les deux soient d'accord à une tolérance près avant qu'une opération privilégiée procède ; revertez sinon.

Le coût, c'est un peu de complexité dans la fonction de lecture de prix. Le bénéfice, c'est qu'une attaque qui compromet un oracle ne draine pas le protocole.

3. Plafonnez l'exposition du protocole aux erreurs d'oracle

Même avec TWAPs et sources redondantes, des erreurs arrivent. Un vrai depeg, une déviation de feed Chainlink, un mismatch de prix de bridge. Construisez le protocole de telle sorte que la pire erreur d'oracle produise une perte bornée, pas catastrophique.

Ça veut dire : caps d'emprunt par epoch, décotes de liquidation qui absorbent les petits mispricings, circuit breakers qui mettent en pause quand la déviation d'oracle dépasse un seuil. L'objectif : qu'une erreur d'oracle de 5 % vous coûte 5 %, pas 100 %.

À quoi ça ressemble en revue de code

Quand on revoit un protocole DeFi, la fonction de lecture de prix est l'une des premières choses qu'on regarde. Les questions qu'on pose :

  • D'où vient ce prix ?
  • Un seul bloc peut-il le bouger ? Un flash loan peut-il le bouger ?
  • Que se passe-t-il si la source rend zéro, une valeur périmée, ou une valeur 100x à côté ?
  • Y a-t-il un fallback ou un sanity check ?
  • Le contrat utilise-t-il getReserves() directement sur une paire Uniswap v2 ? (Si oui, stop, c'est la vulnérabilité.)

Un protocole qui a de bonnes réponses à toutes ces questions a réfléchi à son modèle de menace. Un protocole qui n'en a pas est à un flash loan de la une de presse.

Après le mainnet

Même avec le design correctement fait, le modèle de menace change quand le protocole est en ligne. De nouveaux AMM se déploient. La liquidité migre. Les représentations bridgées de vos collatéraux apparaissent avec des profils de prix différents. La fenêtre TWAP qui était sûre au lancement peut ne pas l'être à 1 G$ de TVL.

Wallet Surveillance sur les clés admin du protocole et la trésorerie attrape les cas où la gouvernance devient le prochain vecteur d'attaque après le durcissement des contrats. Un retainer Réponse à incident garantit que si le prochain exploit passe à travers tout, la réponse se mesure en minutes, pas en jours.

La manipulation d'oracle est un problème résolu en tant que classe de vulnérabilité. Toutes les équipes exploitées par ça auraient pu ne pas l'être. Construire correctement coûte moins cher que le post-mortem, par ordres de grandeur.

Glossaire

Concepts évoqués.

Services

Comment nous travaillons sur ce sujet.

Par secteur

Pour qui cela compte.

Pour continuer

Plus d'articles.

Un projet qui mérite un deuxième regard ? Parlons-en.