Le 5 octobre 2026, un attaquant a exploité une vulnérabilité de veBTC sur Mezo et pris le contrôle de 37 positions appartenant à 36 détenteurs. Selon le rapport d’incident publié par Mezo, environ 5,52 BTC ont été dérobés puis transférés hors de la chaîne.
Le plus intéressant techniquement n’est pas la présence d’une fonction évidemment dangereuse. Mezo explique que l’exploitation résultait de l’interaction entre deux choix de conception courants : les meta-transactions transitant par un trusted forwarder et la séparation d’une partie de la logique dans des bibliothèques Solidity externes.
C’est un exemple de faille de composition : deux mécanismes peuvent présenter des garanties raisonnables séparément, puis perdre ces garanties lorsqu’ils interagissent.
Comment l’identité de l’émetteur devait être déterminée
Les meta-transactions permettent à un relais de soumettre une transaction pour le compte d’un utilisateur.
Le forwarder vérifie la signature produite hors chaîne par l’utilisateur, puis ajoute son adresse à la fin des données d’appel (calldata). Le contrat destinataire peut ainsi retrouver l’émetteur effectif à partir de ces derniers octets, plutôt que de considérer le relayer comme l’utilisateur.
Cette méthode repose sur une hypothèse : l’adresse ajoutée à la fin du calldata doit encore être disponible lorsque le code qui en dépend s’exécute.
Là où cette hypothèse a cessé d’être vraie
Une partie de la logique VotingEscrow de Mezo avait été déplacée dans des bibliothèques externes pour respecter les contraintes de taille de contrat de l’EVM.
Or un appel à une bibliothèque externe crée un nouveau contexte d’appel. Le compilateur construit un nouveau bloc d’arguments à partir des paramètres déclarés par la fonction.
L’adresse ajoutée par le trusted forwarder ne faisait pas partie de ces paramètres déclarés.
Par conséquent, les métadonnées permettant d’identifier l’émetteur réel n’étaient pas automatiquement transportées dans ce nouveau contexte.
Selon le postmortem, un paramètre de données construit spécialement dans un appel à safeTransferFrom pouvait amener la bibliothèque à interpréter les 20 derniers octets de données contrôlées par l’attaquant comme une adresse d’émetteur authentifiée.
La garantie de sécurité n’a donc pas simplement échoué dans l’un des deux mécanismes : elle a échoué à leur frontière.
Pourquoi ce type de faille échappe aux contrôles classiques
Un audit est souvent structuré par fonction ou par composant.
Un auditeur vérifie que le forwarder contrôle correctement les signatures. Il peut le faire.
Il vérifie que la bibliothèque applique correctement ses règles de transfert. Elle peut également le faire.
Mais la question décisive est différente : les hypothèses valables avant un changement de contexte d’appel restent-elles valables après ?
Ces hypothèses concernent notamment :
- l’identité réelle de l’émetteur ;
- les octets considérés comme fiables ;
- la conservation du format de calldata ;
- les effets d’un appel externe ou d’un delegatecall sur le contexte ;
- la visibilité des données d’environnement par la bibliothèque ;
- l’origine effective d’un paramètre contrôlé par un utilisateur.
La sécurité d’un protocole complexe ne se réduit donc pas à une addition de composants réputés sûrs.
Une exploitation plus rapide que la fenêtre de réponse
La chronologie publiée par Mezo est particulièrement instructive.
Le 5 octobre, l’attaquant a approvisionné son adresse à 18 h 03 UTC. Les positions concernées ont été prises entre 18 h 54 et 19 h 06.
À 19 h 09, le solde avait été transféré vers Ethereum au moyen d’un bridge. À 19 h 15, il avait été converti en ETH.
Le lendemain matin, l’équipe a détecté des anomalies à 08 h 45 UTC. Elle a déclaré l’incident à 09 h 04, suspendu les retraits du bridge à 09 h 17, identifié la vulnérabilité à 09 h 21, puis arrêté l’ensemble des transactions de la chaîne Mezo à 09 h 27.
Selon le rapport, la correction a été appliquée et le bridge comme la chaîne ont été réactivés vers 15 h 00.
Une fois l’incident identifié, le confinement a été rapide. Le problème le plus difficile était donc de détecter l’exploitation avant que les actifs ne quittent l’environnement.
Deux audits et un bug bounty n’ont pas suffi
Mezo indique explicitement que le code concerné avait fait l’objet de deux audits et bénéficiait d’un programme de bug bounty actif.
Cela ne rend pas les audits inutiles.
Cela rappelle qu’un audit constitue une assurance limitée à un périmètre et à un instant donnés, et non une démonstration mathématique de l’absence de toute défaillance future.
L’équipe annonce notamment vouloir évoluer vers des revues offensives continues de ses contrats en production et réduire certaines fonctionnalités peu utilisées qui élargissent la surface d’attaque.
Cette évolution répond directement à la nature du problème.
Supprimer une fonctionnalité peut être un contrôle de sécurité
Après l’incident, Mezo a désactivé les meta-transactions, car leur usage en production ne justifiait plus leur maintien.
Cette décision illustre un principe souvent sous-estimé : une capacité inutilisée continue de créer du risque.
Chaque fonctionnalité ajoute :
- des chemins d’exécution ;
- des hypothèses supplémentaires ;
- des scénarios de test ;
- des interactions avec les mises à jour ;
- de nouveaux besoins de surveillance.
Lorsqu’une fonction n’apporte plus suffisamment de valeur, la supprimer peut être plus efficace que multiplier les contrôles pour la maintenir.
Ce que les équipes protocole devraient retenir
Auditer les interactions, pas seulement les composants
Les modèles de menace doivent couvrir les transitions entre bibliothèques, proxies, forwarders, bridges, hooks et services hors chaîne.
Tester les frontières contrôlées par un attaquant
Toute donnée qui passe d’un contexte fiable vers un nouveau contexte d’exécution doit être examinée pour détecter une ambiguïté d’origine ou d’interprétation.
Surveiller les invariants économiques
Un flux de transactions peut rester techniquement valide tout en provoquant des changements d’état anormaux. Le monitoring doit détecter les mouvements impossibles ou hautement inhabituels, pas seulement les erreurs et les transactions qui échouent.
Préparer les mécanismes de suspension avant le lancement
Mezo a pu suspendre les retraits, puis arrêter la chaîne. Ces pouvoirs sont importants : ils doivent être documentés, testés et encadrés pour éviter qu’une mesure d’urgence ne devienne elle-même un risque de gouvernance.
Le point de vue GLOV
La leçon n’est pas « ne jamais utiliser de meta-transactions » ni « ne jamais utiliser de bibliothèques ».
La leçon est que l’architecture produit des propriétés de sécurité émergentes.
Une revue sérieuse doit examiner ce que chaque composant suppose des composants qui l’entourent.
GLOV Secure privilégie cette lecture systémique. Pour les équipes qui exploitent des systèmes complexes associant smart contracts et infrastructure, un audit de sécurité devrait couvrir les frontières de confiance, les accès privilégiés, le monitoring et les contrôles d’incident, en complément de la revue du code.