0x.1 Vorwort
Am 15. November 2021 erfasste unser internes Überwachungssystem verdächtige Flashloan-Transaktionen auf BSC. Nach Untersuchung stellten wir fest, dass es sich um einen Angriff auf Nerve Bridge handelte, der auch die MetaPools von fUSDT und UST umfasste.

Zum Zeitpunkt der Erstellung dieses Berichts hat der Angreifer die Liquidität von fUSDT und UST der Staking-Pools von Nerve erschöpft und einen Gewinn von 900 BNB erzielt.
Überraschenderweise stellten wir fest, dass der anfällige Code von Saddle.Finance abgezweigt wurde, was bereits am 6. November 2021 zu einem Verlust von 800 Mio. USD bei Synapse Bridge führte. Insbesondere liegt die Kernursache der Schwachstelle in der inkonsistenten Implementierung der Berechnung des Wechselbetrags von Tokens in verschiedenen Bibliotheken.
Es existiert jedoch KEIN öffentlich verfügbarer Bericht zur Analyse dieses Sicherheitsvorfalls. Daher zielt dieser Blog darauf ab, eine umfassende Analyse bereitzustellen, einschließlich des Mechanismus des Projekts, der Schwachstelle und des Angriffs.
0x2. Hintergrund
0x2.1 Was ist MetaPool?
Grundsätzlich bietet Curve zwei Arten von Stablecoin-Swap-Pools an, nämlich Standard StableSwap Pool und MetaPool. Der erstere ist ein vollständiger AMM zur Schaffung von Cross-Markets zwischen verschiedenen Stablecoins [1]. Er ist der am weitesten verbreitete Pooltyp, z. B. Curve.3pool, der DAI, USDC und USDT umfasst. Dieser Pool kann jedoch das Risiko zwischen Stablecoins nicht isolieren, was zu großen Verlusten für LP-Anbieter führen kann.
Daher wird MetaPool vorgeschlagen, um dieses Problem zu lösen.
Wie von Curve [2] angegeben, „ermöglicht er die Bündelung eines einzelnen Coins mit allen Coins eines anderen (Basis-)Pools, ohne dessen Liquidität zu verdünnen“. Es handelt sich im Wesentlichen um einen Swap-Pool zwischen einem Stablecoin und einem LP-Token eines Standard StableSwap Pools (der aus mehreren anderen Stablecoins besteht). In unserem Kontext nennen wir diese beiden Arten von Stablecoins Pool-Stablecoin und Basis-Stablecoin.
Ein Opfer dieses Vorfalls ist beispielsweise der MetaPool von fUSDT und der LP-Token von Nerve.3pool (einschließlich BUSD, USD und USDC), und die Struktur dieses Pools ist im Wesentlichen [fUSDT, LP-Token von (BUSD, USD, USDC)]. Somit ist fUSDT der Pool-Stablecoin, während BUSD, USD und USDC die Basis-Stablecoins sind.

0x2.2 Quelle des anfälligen Codes
Curve's MetaPool ist in Vyper implementiert. Um die Entwicklung von Solidity zu unterstützen, hat das Entwicklerteam von Saddle.Finance den Code in Solidity neu geschrieben. Als Ursprung dieser Schwachstelle wurde er von Synapse und Nerve abgezweigt und übernommen. Am 6. November wurde Synapse angegriffen.

Etwa 8,2 Mio. USD wurden aus dem MetaPool abgezogen, wobei aufgrund eines „dummen“ Fehlers des Angreifers keine Gelder tatsächlich verloren gingen [3].
Danach ergriff Saddle.Finance eine Notfallmaßnahme, um die Sicherheit ihrer Gelder zu gewährleisten, indem alle MetaPool-Verträge pausiert wurden. Nerve Bridge unternahm jedoch keine Maßnahmen, was unvermeidlich zu diesem Sicherheitsvorfall führte.
Die relevanten Vertragsadressen sind unten aufgeführt:
- MetaSwap: 0xd0fBF0A224563D5fFc8A57e4fdA6Ae080EbCf3D3
- SwapUtils: 0x02338Ee742ddCDe44488640F4edf1Aa947E670E7
0x3. Schwachstellenanalyse
Im MetaPool gibt es zwei wichtige Funktionen, nämlich swap und swapUnderlying. Insbesondere wird erstere verwendet, um den LP-Token und den Pool-Stablecoin zu tauschen, während letztere verwendet wird, um den Pool-Stablecoin und die Basis-Stablecoins zu tauschen.


Die beiden Funktionen sind jedoch inkonsistent implementiert. Wie in den obigen beiden Abbildungen gezeigt. Der Codeausschnitt im roten Rechteck dient dazu, den Wert des LP-Tokens durch Messung des „virtuellen Preises“ eines LP-Tokens anzupassen (der von einem Basiswert von 1 steigt, je mehr Gebühren anfallen). Die swap-Funktion ignoriert jedoch den Einfluss des virtuellen Preises, was bedeutet, dass der Wert des LP-Tokens unterschätzt wird. Mit anderen Worten, es könnten mehr LP-Tokens getauscht werden.
Infolgedessen ist es möglich, mehr Pool-Stablecoins zu generieren, indem zunächst die Liquidität der Basis-Stablecoins mit dem entsprechenden LP-Token zurückgeholt und dann Pool-Stablecoins durch Aufruf der swapUnderlying-Funktion getauscht werden.
0x4. Angriffsanalyse
Wir nehmen die Beispieltransaktion als Beispiel, um den Angriff zu veranschaulichen.

Abbildung 6 zeigt, dass der Angreifer die folgenden fünf Schritte unternahm, um den Angriff zu starten:
- Schritt 1: Aufnahme von 50.000 BUSD per Flashloan von Fortube
- Schritt 2: Tausch von 50.000 BUSD gegen 50.351 fUSDT von Ellipsis.
- Schritt 3: Aufruf der
swap-Funktion von MetaSwap, um 50.351 fUSDT gegen 36.959 Nerve 3-LP mit einem relativ großen Slippage zu tauschen. - Schritt 4: Aufruf der
removeLiquidityOneCoin-Funktion von Nerve.3pool mit den LP-Tokens (im vorherigen Schritt erhalten), um die Liquidität von BUSD, d. h. 37.071 BUSD, zu entfernen. - Schritt 5: Aufruf der
swapUnderlying-Funktion von MetaSwap, um BUSD gegen fUSDT zu tauschen, und Erhalt von 51.494 fUSDT.
Der Angreifer führte die oben genannten fünf Schritte wiederholt aus (ca. 200+ Transaktionen), um die Liquidität des MetaPools abzuschöpfen und erzielte schließlich 900 BNB Gewinn.
Interessanterweise übernahm der Angreifer denselben Ansatz wie beim Synapse-Vorfall, was keine optimierte Methode ist, um das Ziel zu erreichen. Alternativ ist es möglich, Angriffe effizienter zu starten, z. B. durch Anwendung optimierter Parameter, um die Liquidität in einer Transaktion abzuschöpfen. Das Ergebnis legt nahe, dass der Angreifer die Kernursache dieser Schwachstelle möglicherweise NICHT vollständig verstanden hat.
Referenzen
[1] https://curve.fi/files/stableswap-paper.pdf
[2] https://resources.curve.fi/lp/depositing/depositing-into-a-metapool/
[3] https://synapseprotocol.medium.com/11-06-2021-post-mortem-of-synapse-metapool-exploit-3003b4df4ef4
Credits: Hailin Wang, Lei Wu, Yajin Zhou @BlockSec
Twitter: https://twitter.com/BlockSecTeam



