Comptabilité de récompenses de Popsicle Finance
20,7 M$ drainés du pool Sorbetto Fragola de Popsicle : prêts flash et transferts de parts ont trompé le contrat lui faisant devoir des récompenses = TVL.
- Date
- Victime
- Popsicle Finance
- Chaîne(s)
- Statut
- Fonds dérobés
Le 4 août 2021, la plateforme DeFi Popsicle Finance a perdu environ 20,7 millions de dollars depuis son pool de liquidité Sorbetto Fragola. L'attaquant a utilisé des prêts flash et une séquence de transferts de parts entre adresses pour tromper la logique de suivi des récompenses du contrat lui faisant croire qu'on lui devait des récompenses égales à la TVL totale du pool.
Ce qui s'est passé
Sorbetto Fragola était un gestionnaire de liquidité active Uniswap v3 — les utilisateurs déposaient des actifs, recevaient des « parts » représentant leur position LP, et gagnaient des frais proportionnels à leur part. Le pool suivait les récompenses en enregistrant, pour chaque adresse, le bloc dans lequel elle a reçu pour la première fois des parts et en appliquant l'accumulation de frais à partir de ce bloc.
La faille fatale : le contrat ne mettait pas à jour l'état de suivi des récompenses lorsque les parts étaient transférées entre adresses. Spécifiquement :
- Lorsque l'utilisateur A transférait ses parts à l'utilisateur B, le contrat enregistrait l'utilisateur B comme éligible aux récompenses depuis le bloc 0 (le bloc de déploiement initial du pool), pas depuis le bloc de transfert réel.
- Les mêmes parts pouvaient être transférées plusieurs fois à différentes adresses, et chaque adresse de réception serait créditée de récompenses comme si elle avait détenu ces parts depuis la création du pool.
L'attaque :
- Emprunt flash d'environ 30 M$ USDT et 32 M$ ETH depuis diverses sources.
- Dépôt des actifs empruntés dans Sorbetto Fragola, recevant des parts Sorbetto.
- Transfert des parts vers une séquence d'adresses contrôlées par l'attaquant — chaque transfert enregistrait le destinataire comme « éligible aux récompenses depuis le bloc 0 ».
- Réclamation des récompenses depuis chacune des adresses contrôlées par l'attaquant — le contrat calculait la part de récompense de chaque adresse comme si elle avait détenu la mise maximale depuis le déploiement.
- Résultat net : les récompenses réclamées sur toutes les adresses de l'attaquant totalisaient environ la TVL totale du pool.
- Retrait des récompenses comme actifs réels, remboursement des prêts flash, départ avec ~20,7 M$.
Notamment, l'attaquant a pris principalement de l'USDC et de l'USDT (environ 10 M$ combinés) plus plusieurs autres actifs. Les autres contrats de Popsicle n'ont pas été affectés — le bug était spécifique à la logique de suivi des récompenses de Sorbetto Fragola.
Conséquences
- Popsicle a mis Sorbetto Fragola en pause et annoncé une refonte de la logique de comptabilité des récompenses.
- L'équipe a publié un post-mortem identifiant le manque de mise à jour d'état lors du transfert de parts comme la cause racine.
- Un Sorbetto redessiné avec des mises à jour appropriées de l'état lors des transferts de parts a finalement été lancé, mais la position de Popsicle dans la catégorie de gestion de liquidité active ne s'est pas rétablie.
- Aucune récupération publique des fonds volés.
Pourquoi c'est important
Popsicle est le cas d'école pour pourquoi chaque opération modifiant l'état dans un système de suivi de récompenses doit mettre à jour chaque variable d'état dépendante. La fonction transfer du contrat déplaçait les parts sans toucher au timestamp d'éligibilité aux récompenses, laissant les deux morceaux d'état incohérents — et l'incohérence était tout l'exploit.
Le schéma se répète à travers la DeFi chaque fois qu'un protocole implémente le suivi de frais/récompenses en stockant un timestamp de « début d'éligibilité » qui devrait être mis à jour à chaque transfert :
- Forks de MasterChef qui ne mettent pas à jour la dette de récompense lors des transferts de parts.
- Contrats de staking qui calculent les récompenses sur la base d'un bloc de « premier dépôt ».
- Agrégateurs de rendement qui agrègent l'état utilisateur sur les lots de dépôt.
Le schéma défensif — mettre à jour tout l'état de dette de récompense à chaque transfert de parts, pas seulement à dépôt/retrait — est maintenant standard dans le code moderne de suivi de récompenses. Les 20,7 M$ de Popsicle sont l'un des cas fondateurs qui l'ont rendu standard.
Il est également notable que Certora a plus tard publié une analyse de vérification formelle montrant que le bug aurait été détecté par leur outil. La vérification formelle des invariants de suivi de récompenses est par la suite devenue plus courante chez les protocoles qui gèrent une TVL significative.
Sources & preuves on-chain
- [01]halborn.comhttps://www.halborn.com/blog/post/explained-the-popsicle-finance-hack-august-2021
- [02]coindesk.comhttps://www.coindesk.com/markets/2021/08/04/popsicle-finance-loses-207m-in-cyberattack
- [03]theblock.cohttps://www.theblock.co/linked/113482/defi-platform-popsicle-finance-suffers-20-million-exploit