Back to Blog

~9,4 Mio. $ verloren: Injective- und Aquifer-Exploits | BlockSec Weekly

Code Auditing
11. September 2026
27 min read
Key Insights
  • Vier Vorfälle in dieser Woche verursachten Verluste von rund 9,4 Millionen US-Dollar auf Injective, Solana, Ethereum und Flow EVM.

  • Die Exploits bei Injective, Aquifer und Notional Finance benötigten weder Preismanipulation noch einen Flash Loan. Jeder von ihnen sorgte lediglich dafür, dass die eigene Buchführung des Protokolls eine Zahl ausgab, die nie zutraf: Bei Injective glich ein Versicherungsfonds, dessen Kennung mit der eines Marktes kollidierte, ein fingiertes Defizit von 12.744 USDC mit einem ungeprüften Guthaben in einem anderen Token aus, das nur einen Bruchteil eines Cents wert war, und bei Notional Finance wurde eine Schuld von exakt -2^128 mit null bewertet.

  • In drei der vier Fälle hatte das Protokoll die korrekte Prüfung bereits implementiert, nur eben nicht auf dem Pfad, auf den es ankam. Aquifer lieferte eine Zulassungsliste für das Token Program aus, die von seinem Swap-Einstiegspunkt nie aufgerufen wurde, Ankr FLOW sicherte einen Staking-Einstiegspunkt mit einem Pause-Modifier ab und ließ den dazugehörigen Gegenpart offen, und Notional Finance verwendete für eine Umrechnung in einer Funktion einen geprüften Cast, während die Umrechnung darüber ein ungeprüfter Raw Cast blieb.

Im Laufe der vergangenen Woche (31.08.2026 - 06.09.2026) haben wir 4 Sicherheitsvorfälle mit einem geschätzten Gesamtschaden von etwa 9,4 Mio. USD beobachtet.

Datum Vorfall Typ Geschätzter Schaden
31.08.2026 Ankr FLOW Fehlerhafte Zustandsvalidierung ~410.000 USD
31.08.2026 Aquifer Fehlerhafte Eingabevalidierung ~2,47 Mio. USD
31.08.2026 Injective Fehlende Validierung der Denomination ~4,8 Mio. USD
03.09.2026 Notional Finance Unsichere Typumwandlung ~1,73 Mio. USD

Der beste Sicherheitsauditor für Web3

Validieren Sie Design, Code und Geschäftslogik vor dem Launch

Highlight der Woche: Injective

Dieser Vorfall ist das Highlight der Woche aufgrund der Komplexität seiner Angriffskette und der Höhe des Schadens: Zwei separate Defekte mussten zusammentreffen, bevor eine einzelne Abrechnung ausgezahlt werden konnte. Beide befanden sich in der eigenen Exchange-Logik der Chain und nicht in einem Anwendungscontract. Er zeigt, wie ein Identifikator, der aus aneinandergereihten Feldern ohne Trennzeichen zusammengesetzt wird, zwei Objekte, die niemals miteinander in Beziehung stehen sollten, stillschweigend verschmelzen kann – und wie teuer diese Verschmelzung wird, wenn der Abrechnungspfad niemals prüft, ob ein Fonds die Denomination des Marktes hält, den er absichert.

Am 31.08.2026 wurde die Binäroptionslogik innerhalb des exchange-Moduls von Injective für rund 4,8 Mio. USD in USDC ausgenutzt. Injective ist eine Layer-1-Chain, die eine Orderbuch-Exchange direkt in die Chain integriert, sodass der betroffene Code Teil der Node-Software ist und nicht ein von jemandem bereitgestellter Contract. Ein Versicherungsfonds, der INJ, das native Token von Injective, hielt, wurde an einen in USDC notierten Binäroptionsmarkt gebunden, weil die beiden Identifikatoren kollidierten, und der Abrechnungspfad, der auf einen Versicherungsfonds zugreift, verglich die beiden niemals. Der Angreifer handelte gegen seine eigenen Subkonten innerhalb eines solchen Marktes, um ein Defizit zu erzeugen, das das Protokoll dann mit einem INJ-Guthaben deckte, das nur einen Bruchteil eines Cents wert war. Jede Position wurde vollständig erstattet, und der Angreifer zog weitaus mehr ab, als er eingezahlt hatte.

Hintergrund

Das exchange-Modul von Injective listet Binäroptionsmärkte, bei denen es sich um vollständig besicherte Wetten auf ein Ja-Nein-Ergebnis handelt. Jeder kann einen solchen Markt auflisten, indem er eine Listing-Gebühr zahlt, das Orakel auswählt, das den Markt auflösen wird, sowie die Zeitstempel für Ablauf und Abrechnung festlegt. Das Orakel wird als Provider plus Symbol benannt: Um Provider zu werden, ist eine Governance-Abstimmung erforderlich, während das Symbol eine beliebige vom Lister angegebene Zeichenkette ist. Ein Trader zahlt zunächst Quote-Token wie USDC auf ein Subkonto ein und wählt dann eine Seite, indem er eine Order platziert. Ein BUY wettet darauf, dass das Ereignis eintritt, und sperrt P * Q als Margin; ein SELL wettet darauf, dass es nicht eintritt, und sperrt (1 - P) * Q, wobei Q die Menge in Kontrakten und P der Einstiegspreis im Bereich [0, 1] ist. Die Seite, die auf das wahrscheinlichere Ergebnis wettet, hinterlegt daher die größere Margin. Der EndBlocker, der Hook, den die Chain am Ende jedes Blocks ausführt, gleicht ein BUY und ein SELL zum gleichen Preis zu einer LONG- und einer SHORT-Position ab. Da sich die beiden Sperren immer zu genau Q summieren, ist ein frisch abgeglichenes Buch konstruktionsbedingt vollständig finanziert.

Bei Ablauf veröffentlicht das Orakel einen Abrechnungspreis S im Bereich [0, 1], und jede Position wird mit margin ± (S - entry) * Q aus dem Markt-Pool ausgezahlt. Zahlungen zwischen Teilnehmern sind streng nullsummig, und jede Auszahlung wird nach unten auf null begrenzt, sodass eine Position niemals negativ werden kann und niemals liquidiert werden muss. Eine Position kann auch vorzeitig geschlossen werden, indem eine entgegengesetzte Order mit margin = 0 platziert wird, wodurch ihre Margin plus ihr realisierter Gewinn freigegeben wird, ausgezahlt aus der Margin, die der eintretende Eröffner sperrt. Die Margin jeder Position bleibt bei dem Wert, der beim Einstieg gesperrt wurde, sodass sich nach einem vorzeitigen Schließen die im Buch stehenden Margins nicht mehr zum Pool addieren müssen.

Ein Markt, dessen Symbol kein Provider veröffentlicht, erreicht die Abrechnung völlig ohne Preis. Das Modul verfügt für diesen Fall über einen Fallback: Die Abrechnung fällt in einen Rückerstattungspfad, implementiert durch getBinaryOptionsSocializedLossDataWithRefundFlag(), der den Markt auflöst, anstatt ihn abzurechnen. Jede Position wird einfach mit ihrer Margin erstattet, da der Pfad jede Position zu ihrem eigenen Einstiegspreis schließt, sodass keine Position einen Gewinn oder Verlust verbucht – solange das Buch noch das enthält, was die Positionen beanspruchen. Die Rückerstattungen werden aus dem Marktguthaben und, bei einem Fehlbetrag, aus dem diesem Markt zugeordneten Versicherungsfonds finanziert.

Ein Markt und ein Versicherungsfonds sind separate Objekte, die jeweils durch eine eigene Nachricht erstellt werden und jeweils eine Denomination tragen: Ein Markt wird in einem Token notiert, und ein Fonds hält das Token, mit dem er erstellt wurde. Sie werden über die Identität gepaart: Ein Fonds sichert den Markt ab, dessen ID mit seiner eigenen übereinstimmt. Beide IDs sind keccak256-Digests von Identitätsfeldern. Das exchange-Modul selbst ist ein einziges Sammelkonto der Bank, dessen Guthaben pro Markt und pro Fonds eine reine Integer-Buchhaltung darstellen.

Schwachstellenanalyse

Die fehlerhafte Komponente ist die Behandlung von Binäroptionen im exchange-Modul von injective-core, behoben in Commit b994d6b6 [1]. Zwei miteinander verkettete Defekte erlauben es einem Fonds, der eine Denomination hält, einen Markt abzusichern, der in einer anderen notiert ist.

Defekt 1: Identifikatoren werden aus einer nicht getrennten Verkettung abgeleitet. NewBinaryOptionsMarketID(), das die ID eines Marktes berechnet, wenn dieser Markt gestartet wird, und CreateInsuranceFund(), das die ID des Marktes berechnet, den ein neuer Fonds absichern soll (für expiry = BinaryOptionsExpiryFlag = -2), leiten diese ID beide aus demselben Ausdruck ab:

return crypto.Keccak256Hash([]byte((BINARY_OPTIONS_MARKET_ID_PREFIX +
    oracleType.String() + ticker + quoteDenom + oracleSymbol + oracleProvider)))

Es gibt keine Feldtrennzeichen und keine Längenpräfixe, sodass die Grenzen zwischen den Feldern in den gehashten Bytes keine Spuren hinterlassen. CreateInsuranceFund() bildet die eigenen Felder eines Versicherungsfonds auf diese Slots ab, wobei oracle_base den oracleSymbol-Slot und oracle_quote den oracleProvider-Slot belegt. Ein Fonds-Tupel und ein Markt-Tupel können daher byte-identische Preimages erzeugen, während sie diese Bytes unterschiedlich auf die Felder aufteilen, und die beiden Objekte teilen sich dann eine ID. Die Registrierung akzeptiert diese gemeinsame ID als Verbindung zwischen ihnen, sodass ein Fonds zum Versicherungsfonds eines Marktes werden kann, dessen quoteDenom er nicht hält.

Defekt 2: Auszahlungen werden nie gegen die Denomination des Marktes geprüft. PayDeficitFromInsuranceFund() verschiebt rohe Coins aus dem Fonds in der Denomination, die der Fonds hält, und schreibt dann dieselbe rohe Ganzzahl dem Marktguthaben gut, ohne jemals insuranceFund.DepositDenom mit der Quote-Denomination des Marktes zu vergleichen. Da die Buchhaltung des Moduls aus einfachen Ganzzahlen besteht, sind eine rohe Einheit INJ und eine rohe Einheit USDC auf diesem Pfad nicht zu unterscheiden, obwohl dieselbe Ganzzahl für Werte steht, die sich um einen Faktor in der Größenordnung von 10^11 unterscheiden. Der Fix-Commit fügt die fehlende Prüfung auf diesem Pfad hinzu, sowohl auf der Zufluss- als auch auf der Abflussseite, sodass ein Fonds nur noch Märkte absichern kann, die in der von ihm gehaltenen Denomination notiert sind:

Derselbe Commit deaktiviert außerdem den Handel und die Abrechnung von Binäroptionen im Injective-Mainnet dauerhaft und entfernt damit den Rückerstattungspfad als Angriffsfläche.

Angriffsanalyse

Alle Schritte wurden von einer einzigen Wallet über drei ihrer eigenen Subkonten (...037c, ...037d und ...037e) mit Q = 15.930 ausgeführt.

Das kollidierende Paar wurde konstruiert, indem verschoben wurde, wo die Feldgrenzen liegen, während die verketteten Bytes identisch blieben. Der ticker und quoteDenom des Fonds (X und inj) buchstabieren den Ticker Xinj des Marktes, und oracle_base des Fonds (eine Contract-Adresse und ein Orakel-Symbol, aneinandergeklebt) buchstabiert die quoteDenom des Marktes gefolgt von dessen oracleSymbol:

Slot in der Verkettung Fonds (MsgCreateInsuranceFund) Markt (MsgInstantBinaryOptionsMarketLaunch)
Präfix -BINARY-OPTIONS-MARKET- -BINARY-OPTIONS-MARKET-
oracleType.String() Provider Provider
ticker X Xinj
quoteDenom inj erc20:0xa00C...235a
oracleSymbol erc20:0xa00C...235aNO_PRICE_FOR_REFUND...297, gefüllt aus oracle_base des Fonds, wobei beide Teile in diesem einen Feld zusammengepackt sind NO_PRICE_FOR_REFUND...297
oracleProvider Frontrunner, gefüllt aus oracle_quote des Fonds Frontrunner

Beide ergeben 0x9793a39f82993cdedb0c82c614102d5aba2451f29709dc9a6f7df191020b4efc. Das Orakel mit dem Namen NO_PRICE_FOR_REFUND war so konfiguriert, dass es niemals einen Preis veröffentlicht, was die Abrechnung zwangsläufig auf den Rückerstattungspfad lenkt.

Die folgende Analyse basiert auf der Transaktion 0x6ae9cb...51dcf8.

  • Schritt 1: In einer atomaren Transaktion bei Block 181024772 erstellte der Angreifer den kollidierenden, in INJ denominierten Versicherungsfonds sowie den in USDC denominierten Binäroptionsmarkt, stattete den Fonds mit 12.744.000.000 roh INJ aus (im Wert von etwa 0,000000063 USD) und zahlte 30.267,02 USDC über die drei Subkonten ein. Die Staubeinzahlung war so bemessen, dass ihre rohe Ganzzahl mit dem Fehlbetrag übereinstimmt, den der Angreifer zu erzeugen plante. Jedes Subkonto erhielt genau die Margin, die es später benötigen würde:
Subkonto Einzahlung (USDC) Damit finanzierte Margin
037d 1.593,001593 BUY von 15.930 zu 0,10, sperrt 1.593 (Schritt 2)
037c 14.337,001593 SELL von 15.930 zu 0,10, sperrt 14.337 (Schritt 2)
037e 14.337,014337 BUY von 15.930 zu 0,90, sperrt 14.337 (Schritt 3)
Gesamt 30.267,017523 -
  • Schritt 2: In derselben Transaktion platzierte 037d ein BUY von 15.930 zu 0,10 und 037c ein SELL von 15.930 zu 0,10. Der EndBlocker glich sie zum gleichen Preis zu einer LONG-Position für 037d mit 1.593 Margin und einer SHORT-Position für 037c mit 14.337 Margin ab. Die Gesamtmargin im Buch beträgt 1,0Q = 15.930, genau das, was der Markt-Pool hält, sodass das Buch von jedem normalen, vollständig besicherten Markt nicht zu unterscheiden ist.

  • Schritt 3: Zwei Blöcke und 1,1 Sekunden später, in Transaktion 0x012c17...2af694 bei Block 181024774, schloss 037d seine Long-Position zu 0,90 mit margin = 0 und erhielt 1.593 + (0,90 - 0,10) * 15.930 = 14.337. Diese Auszahlung stammte aus der Margin, die der eintretende Eröffner 037e sperrte, der ein BUY von 15.930 zu 0,90 platzierte und 14.337 sperrte. Der realisierte Gewinn von 0,8Q = 12.744 liegt nun im verfügbaren Guthaben von 037d außerhalb des Markt-Pools, während beide verbleibenden Positionsmargins im Buch bleiben: Die Verbindlichkeiten belaufen sich auf 1,8Q = 28.674 gegenüber einem Pool, der noch 1,0Q hält.

  • Schritt 4: Die Abrechnung wird von der eigenen Uhr des Marktes gesteuert, nicht von einer Transaktion. Zu Beginn jedes Blocks greift das Modul jeden Markt auf, dessen Abrechnungszeitstempel überschritten ist, und rechnet ihn als Ganzes ab statt Position für Position. Dieser Markt wurde 18 Sekunden nach der Markterstellung ausgelöst, wobei beide Positionen noch im Buch standen: die SHORT-Position von 037c und die LONG-Position von 037e, jeweils 14.337 Margin. Das Orakel blieb stumm, sodass der Rückerstattungspfad Verbindlichkeiten von 1,8Q = 28.674 gegenüber idealisierten Vermögenswerten von 1,0Q = 15.930 berechnete und ein Defizit von 0,8Q = 12.744 meldete. Dieses Defizit existiert nur innerhalb der Buchhaltung des Rückerstattungspfads. Unter einem einzigen Preis S hängt die Auszahlung jeder Seite nur von S ab und nicht davon, wo sie eingestiegen ist: Die Short-Position erhält (1 - S) * Q und die Long-Position S * Q, was sich exakt zum Q im Pool summiert. Der Rückerstattungspfad zahlt stattdessen zum jeweiligen Einstiegspreis jeder Seite aus, sodass sich die Einstiege nicht aufheben: Der Short-Position wurde (1 - 0,10) * Q ausgezahlt und der Long-Position 0,90 * Q, jeweils 14.337. Die Short-Position erhielt ihre volle Margin, als hätte sich der Preis nie von 0,10 entfernt – genau das 0,8Q, das der Angreifer bereits in Schritt 3 abgehoben hatte.

  • Schritt 5: PayDeficitFromInsuranceFund() glich das Defizit aus, indem 12.744.000.000 roh INJ aus dem kollidierenden Fonds abgezogen und 12.744 USDC dem Markt-Pool gutgeschrieben wurden. Da das Defizit als gedeckt gemeldet wurde, wurde der Abschlag durch sozialisierten Verlust auf die verbleibenden Positionen übersprungen und jede Position mit ihrer vollen Margin erstattet. Das Defizit selbst kostet niemanden etwas: Es wird aus dem Versicherungsfonds des Marktes gedeckt oder, falls dieser nicht ausreicht, durch den Abschlag. Was diesen Fall profitabel machte, war, dass der an den Markt gebundene Fonds INJ-Staub statt USDC hielt.

  • Schritt 6: In Transaktion 0xcb33ad...152eff bei Block 181024803 hob der Angreifer 43.010.985.663 roh USDC, also 43.010,99 USDC, ab – gegenüber den eingezahlten 30.267,02 USDC. Der Nettogewinn beträgt 12.743,97 USDC, bei etwa 21 Sekunden von der ersten bis zur letzten Transaktion.

Der oben beschriebene Zyklus ist eine repräsentative Runde. Der Angreifer wiederholte ihn über 299 kurzlebige Binäroptionsmärkte, die innerhalb eines 19-Stunden-Fensters erstellt wurden, jeweils gebunden an ein Orakel, das so konfiguriert war, dass es niemals einen Preis veröffentlicht, und jeweils mit Ablauf- und Abrechnungszeitstempeln, die nur Sekunden auseinanderlagen [2]. Die Nettogewinne aus diesen Runden summieren sich zu den etwa 4,8 Mio. USD, die bei diesem Vorfall verloren gingen.

Fazit

Dieser Vorfall kombiniert eine Identifikator-Kollision mit einer fehlenden Denominationsprüfung auf dem Auszahlungspfad. Ein Fonds soll den Markt absichern, dessen Identität er entspricht. Aber eine ID, die durch das Aneinanderreihen von Identitätsfeldern gebildet wird, hält nicht mehr fest, wo ein Feld endet und das nächste beginnt, sodass zwei unterschiedliche Feldmengen dieselbe ID ergeben können, und die Paarung bindet einen Fonds an einen Markt, dem er in Wirklichkeit nicht entspricht. Nichts nachgelagert fängt diese Fehlzuordnung ab, weil der Pfad, der auf einen Versicherungsfonds zurückgreift, um ein Marktdefizit zu decken, Beträge vergleicht, aber niemals Denominationen. Der Angreifer nutzte die beiden Defekte gemeinsam, um innerhalb eines von ihm kontrollierten Marktes ein Phantom-Defizit zu erzeugen, es mit einem Fondsguthaben im Wert eines Bruchteils eines Cents zu begleichen und mit einer vollständigen Rückerstattung von Margins davonzugehen, die der Pool nie besaß.

Allgemeiner gesagt sollte ein Identifikator, der Bedeutung trägt, aus einer strukturerhaltenden Kodierung abgeleitet werden, mit expliziten Trennzeichen oder Längenpräfixen für jedes Feld variabler Länge, damit zwei unterschiedliche Feldtupel nicht auf denselben Digest abgebildet werden können.

Erste Schritte mit Phalcon Explorer

Tauchen Sie in Transaktionen ein, um klug zu handeln

Jetzt kostenlos testen

Weitere Vorfälle dieser Woche

Ankr FLOW

Am 31.08.2026 wurde der Liquid-Staking-Dienst von Ankr auf Flow EVM ausgenutzt. Ankr gibt zwei verschiedene Token gegen gestaktes FLOW, das native Token des Netzwerks, aus, und jedes wird über einen eigenen Einstiegspunkt geprägt. Einer dieser Pfade war abgeschaltet worden, aber ein zweiter Weg hinein überging die Prüfung, die die Pause durchsetzte, und der Umtauschkurs auf diesem Pfad war in der Zwischenzeit veraltet. Der Angreifer prägte darüber weit günstiger, als dieselben Token eingelöst werden konnten, und schleuste die Differenz dann durch den Rückzahlungspuffer von Ankr, einen Uniswap-V3-Pool und das Lending-Protokoll MORE Markets. Etwa 15,5 Mio. WFLOW (verpacktes FLOW), zum damaligen Zeitpunkt im Wert von rund 410.000 USD, wurden aus der MORE-Markets-Reserve abgezogen, und der Angreifer realisierte nach Slippage etwa 246.000 USD [3].

Hintergrund

Ankr FLOW ist ein Liquid-Staking-Dienst auf Flow EVM. FlowStakingPool leitet FLOW zur Validator-Staking-Funktion an Cadence weiter und repräsentiert die daraus resultierenden Positionen durch zwei Token: das nicht rebasende Zertifikat-Token ankrFLOW und das rebasende Bearing-Token aFLOWEVMb, das seinerseits durch ankrFLOW gedeckt ist.

Die beiden Token haben separate Einstiegspunkte. Der Zertifikatspfad läuft über stakeCerts() und unstakeCerts() in _stakeCerts() und _unstakeCertsFor(); der Bearing-Pfad läuft über stakeBonds() und unstakeBonds() in _stakeBonds() und _unstakeBondsFor(). Das Prägen auf dem Bearing-Pfad hat einen zweiten externen Einstiegspunkt, stakeBondsWithCode(), der einen Partnercode für Ankrs Empfehlungsprogramm entgegennimmt und dann dasselbe interne _stakeBonds() aufruft. Jeder Pfad liest seinen eigenen Eintrag aus dem InternetBondRatioFeed, dem Contract, der das Umtauschverhältnis zwischen FLOW und jedem Token veröffentlicht.

FlowStakingPool hält außerdem einen FLOW-Puffer für sofortige Rückzahlungen. Über den Pool hinaus wurde ankrFLOW in einem Uniswap-V3-Pool ankrFLOW/WFLOW gehandelt und als Sicherheit bei MORE Markets akzeptiert, einem Lending-Protokoll nach Aave-V3-Art. MORE Markets begrenzt die Kreditvergabe auf ein Beleihungsverhältnis (Loan-to-Value, LTV), das pro Asset festgelegt ist, und bietet e-Mode-Kategorien (Efficiency Mode) an: Gruppen von Assets, deren Preise sich voraussichtlich gemeinsam bewegen, für die ein höherer LTV gilt, sobald ein Kreditnehmer die Kategorie aktiviert.

Schwachstellenanalyse

Der fehlerhafte Contract ist FlowStakingPool (0xfe81...287a), der das Zertifikat-Token ankrFLOW (0x1b97...14bdb) und das Bearing-Token aFLOWEVMb (0xd6fd...f8d4a) gegen Verhältnisse prägt, die aus dem InternetBondRatioFeed (0x3201...de38f) gelesen werden.

Zwei Defekte überschneiden sich. Erstens erreicht stakeBondsWithCode() _stakeBonds(), ohne den bondStakingUnpaused-Modifikator, den stakeBonds() durchsetzt, sodass der Bearing-Token-Pfad auch nach seiner Deaktivierung erreichbar blieb. Zweitens wurde über 71 wöchentliche Verhältnis-Update-Batches zwischen dem 29. April 2025 und dem 27. August 2026 nur der aktive ankrFLOW-Eintrag aktualisiert, sodass der aFLOWEVMb-Eintrag bei 1,0 verblieb.

Die beiden Verhältnisse bepreisten dieselbe zugrunde liegende Stake-Position daher unterschiedlich:

Richtung Funktionen Verhältnis Umrechnung
Prägen _stakeCerts() / stakeCerts() 0,833437 1 FLOW zu 0,833437 ankrFLOW
Prägen _stakeBonds() / stakeBondsWithCode() 1,0 1 FLOW zu 1 aFLOWEVMb
Einlösen _unstakeCertsFor() / unstakeCerts() 0,833437 1 ankrFLOW zu ~1,19985 FLOW
Einlösen _unstakeBondsFor() / unstakeBonds() 1,0 1 aFLOWEVMb zu 1 FLOW

Da aFLOWEVMb durch ankrFLOW gedeckt ist, erzeugte das Prägen über den Bearing-Pfad ein gedecktes ankrFLOW pro eingezahltem FLOW, während der Zertifikatspfad 0,833437 erzeugte. Die Einlösung über den Zertifikatspfad zahlte weiterhin ~1,19985 FLOW pro ankrFLOW.

Angriffsanalyse

Die folgende Analyse basiert auf der Transaktion 0x2b2e6e...3f66c9.

  • Schritt 1: Der Angreifer beschaffte sich Startkapital mit einem Rundlauf zwischen den beiden Pfaden. Er nahm einen Flash-Loan über 5.000 ankrFLOW aus dem Uniswap-V3-Pool ankrFLOW/WFLOW, löste ihn über unstakeCerts() für ~5.999,25 FLOW ein, zahlte 5.000,50 FLOW über stakeBondsWithCode() ein, um 5.000,50 aFLOWEVMb zu prägen, das durch dieselbe Menge ankrFLOW gedeckt war, und rief unlockShares() auf, um dieses ankrFLOW freizugeben, um den Kredit und dessen Prämie von 0,50 ankrFLOW zurückzuzahlen. Etwa 998,75 FLOW blieben als Arbeitskapital übrig.

  • Schritt 2: Der Angreifer wiederholte einen Uniswap-V3-Swap 50 Mal. Jeder Zyklus tauschte ankrFLOW gegen WFLOW mit einem Preislimit, prägte das dem Pool geschuldete ankrFLOW innerhalb des Swap-Callbacks, indem FLOW über stakeBondsWithCode() und unlockShares() geleitet wurde, und packte anschließend das WFLOW-Ergebnis für den nächsten Zyklus aus. Über die 50 Zyklen hinweg erhielt der Pool ~38.634.755,38 ankrFLOW und zahlte ~46.265.167,78 WFLOW aus, wodurch sich das Guthaben des Angreifers von ~998,75 FLOW auf ~7.631.411,14 FLOW erhöhte.

  • Schritt 3: Der Angreifer wandelte ~38.601,95 FLOW über den Bearing-Pfad um und löste das resultierende ankrFLOW über unstakeCerts() ein, wodurch der ~46.316,57 FLOW-Rückzahlungspuffer, den FlowStakingPool noch hielt, ausgeleert und ~7.714,62 FLOW hinzugefügt wurden.

  • Schritt 4: Der Angreifer wandte sich MORE Markets zu. Er aktivierte die e-Mode-Kategorie 1 ("Wrapped native tokens"), die ankrFLOW und WFLOW als korrelierte FLOW-Assets behandelte und den LTV für ankrFLOW von 78,5 % auf 97 % anhob. Er zahlte ~7.639.125,76 FLOW über stakeBondsWithCode() ein, gab das entsprechende ankrFLOW frei, stellte es als Sicherheit bereit und lieh sich ~5.668.483,10 WFLOW. Durch das Auspacken dieses Kredits und das erneute Einspeisen über denselben Pfad (eine einzige Runde des Loop-Borrowing) wurde eine gleiche Menge ankrFLOW hinzugefügt, sodass die Sicherheiten auf ~13.307.608,86 ankrFLOW stiegen und einen zweiten Kredit über ~9.819.641,05 WFLOW unterstützten, was eine Gesamtverschuldung von ~15.488.124,15 WFLOW ergab – etwa 97 % des Sicherheitenwerts zum Orakel-Verhältnis von ~1,19985 WFLOW.

Die Sicherheiten aus Schritt 4 brachten mehr ein, als ihre Prägung kostete: Ein FLOW prägte ein ankrFLOW auf dem Bearing-Pfad, das Orakel bewertete dieses ankrFLOW mit ~1,19985 WFLOW, und der e-Mode erlaubte eine Beleihung von 97 % dagegen, sodass die bereitgestellten ~13,31 Mio. ankrFLOW ~15,49 Mio. WFLOW an Schulden unterstützten – ~1,16 WFLOW für jedes eingesetzte FLOW. Der Angreifer recycelte nur einmal, weil der zweite Kredit die WFLOW-Reserve leerte.

Diese ~15,49 Mio. WFLOW sind die Bruttokreditaufnahme, und das ist auch das gemeldete 15,5 Mio. WFLOW, das aus der MORE-Markets-Reserve abgezogen wurde. Etwa 5,67 Mio. WFLOW davon wurden ausgepackt und als zusätzliche Sicherheit recycelt, statt als liquider Ertrag einbehalten zu werden; nachdem der zweite Kredit über ~9.819.641,05 WFLOW ausgepackt worden war, hielt der Angreifer ~9.819.641,05 FLOW als Auszahlung. Zugeordnet nach der Herkunft des Werts stammten ~7.630.412,39 FLOW dieser Auszahlung aus dem Uniswap-V3-Pool, ~8.713,37 FLOW aus FlowStakingPool und ~2.180.515,29 FLOW aus MORE Markets.

Fazit

Eine Zustandsprüfung, die einen Einstiegspunkt schützt, aber nicht dessen Pendant, ist hier die Grundursache: Ein Prägepfad, der deaktiviert worden war, blieb aufrufbar, und sein Verhältnis wurde über sechzehn Monate wöchentlicher Aktualisierungen hinweg nicht erneuert. Jedes über diesen Pfad geleitete FLOW erzeugte daher ankrFLOW zu einem Preis, den der Zertifikatspfad niemals geboten hätte, und der Angreifer schleuste diese Diskrepanz durch einen Uniswap-V3-Pool, den Rückzahlungspuffer des Staking-Pools und einen Lending-Markt und wandelte bei jeder Station günstiges ankrFLOW in WFLOW-Liquidität um.

Pausensperren müssen an jedem Einstiegspunkt durchgesetzt werden, der die deaktivierte Logik erreicht, nicht nur an dem, der voraussichtlich aufgerufen wird, und ein Verhältnis-Feed, der einen ruhenden Pfad bedient, sollte entweder aktuell gehalten werden oder revertieren. Lending-Protokolle sollten außerdem vermeiden, einem Liquid-Staking-Token, dessen Prägepreis unabhängig von seinem Orakelpreis festgelegt wird, einen hohen e-Mode-LTV zu gewähren; eine gemeinsame Überwachung von Prägekosten, Einlösewert und Orakelpreis würde diese Divergenz aufdecken.


Aquifer

Am 31.08.2026 wurde Aquifer, ein proprietärer Market-Maker-AMM auf Solana, für etwa 2,47 Mio. USD über 212 erfolgreiche Swaps ausgenutzt, verteilt auf USDC, USDT, HYPE, cbBTC, CASH und dreizehn weitere Token [4]. Jeder Swap wird als zwei Token-Transfers abgewickelt, jeweils einer in jede Richtung, und Aquifer ließ den Aufrufer auswählen, welches Programm jeden dieser Transfers ausführen würde, ohne diese Wahl jemals zu überprüfen. Der Angreifer benannte für den Transfer, der Aquifer hätte bezahlen sollen, ein eigenes Programm, das Erfolg meldete, ohne dabei irgendetwas zu bewegen; der Transfer in die andere Richtung lief über das echte Token Program und lieferte reale Assets aus den Tresoren von Aquifer.

Hintergrund

Aquifer ist ein Prop-AMM, was bedeutet, dass ein professioneller Market Maker sein eigenes Inventar bereitstellt und Kauf- und Verkaufskurse pflegt, anstatt Swaps entlang einer konstanten Produktkurve zu bepreisen, wie es Pools nach Art von Uniswap V2 tun. Aquifer leitet einen Preis aus seinem Kurs- und Risikozustand ab und rechnet den Handel dann zwischen den Token-Konten des Nutzers und seinen eigenen Tresoren ab.

Auf Solana ist ein Token Program ein ausführbares Programm, das Operationen wie Transfer, Mint und Burn implementiert. Tokenkeg ist das ursprüngliche SPL Token Program, und Token-2022 ist sein erweiterbarer Nachfolger; jedes verwaltet viele verschiedene Token statt eines einzigen Assets. Ein Mint Account identifiziert einen Token-Typ und speichert dessen Supply, Dezimalstellen und Berechtigungen, während ein Token Account das Guthaben eines Inhabers für ein Mint speichert; beide werden vom Token Program verwaltet, das sie besitzt. Die Tresore von Aquifer sind Token-Konten, die von Aquifer-PDAs kontrolliert werden.

Ein Trader handelt, indem er die swap-Instruktion von Aquifer aufruft und die Konten übergibt, die sie berühren wird, einschließlich für jeden der beiden Transfers des Token Program, das ihn ausführen soll. Aquifer bewegt diese Token durch Cross-Program Invocation (CPI): Es erstellt eine Transfer-Instruktion und übergibt sie an das durch Instruction.program_id benannte Programm. Transfer-förmige Instruktionsdaten bewegen nur dann echte SPL-Token, wenn das korrekte Token Program sie ausführt.

Schwachstellenanalyse

Das fehlerhafte Programm ist Aquifer (AQU1FR...Tz45). Es liegt kein veröffentlichter Quellcode vor, der dem bereitgestellten Bytecode entspricht, daher wurde die folgende Analyse aus dem Disassembly des Programms rekonstruiert: fn_-Namen kennzeichnen interne Funktionen anhand ihrer Code-Offsets, und keiner der hier verwendeten Namen, swap eingeschlossen, stammt von den Entwicklern. Das Programm enthält eine Allowlist-Funktion, fn_49740(), die nur Tokenkeg und Token-2022 akzeptiert, aber nichts auf dem swap-Pfad ruft sie auf. Bei der Verarbeitung eines swap erstellt das Programm beide Transfer-Instruktionen über fn_45f20() und fn_46bf8() unter Verwendung einer fest codierten Tokenkeg-Konstante, die die interne Prüfung zwangsläufig erfüllt, und überschreibt anschließend vor der Ausführung die program_id jeder Instruktion mit dem vom Aufrufer angegebenen Token Program:

// Semantische Rekonstruktion des Codes, den das Programm bei einem Swap ausführt; construct_transfer()
// steht für fn_45f20() und fn_46bf8(), und die Allowlist fn_49740() wird niemals erreicht.
let checked_program = TOKENKEG_ID;

let mut output_instruction = construct_transfer(checked_program, output_accounts);
let mut input_instruction = construct_transfer(checked_program, input_accounts);

// Ungeprüfte Aufrufer-Eingaben ersetzen den Wert, der geprüft wurde.
output_instruction.program_id = caller.token_program_b.key;
input_instruction.program_id = caller.token_program_a.key;

// Jeder invoke() übergibt die Transfer-Instruktion an das vom Aufrufer benannte Programm.
invoke(output_instruction)?;
invoke(input_instruction)?;

Hierbei bezeichnet TOKENKEG_ID TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA. Der Wert, der die Validierung besteht, ist somit niemals der Wert, der ausgeführt wird. Erschwerend kommt hinzu, dass das Programm den vom Tresor empfangenen Betrag nach Rückkehr der Input-CPI nicht überprüft, sodass eine CPI, die erfolgreich ist, ohne etwas zu transferieren, als Zahlung akzeptiert wird.

Angriffsanalyse

Der Vorfall besteht aus 212 erfolgreichen Angriffstransaktionen. Die folgende Analyse basiert auf der Transaktion 4pBV1G...T3bf, einem repräsentativen Beispiel.

  • Schritt 1: Der Angreifer rief swap mit einem nominalen Input von 4.957,497101 USDC auf, für den Aquifer einen Output von 195.849,433667 KMNO berechnete. Für das KMNO-Bein gab er Tokenkeg an; für das USDC-Bein gab er sein eigenes Programm DMBpPM...NRgb68 zusammen mit einem gefälschten Input-Konto 9gsKJc... an, ein von diesem Programm besessenes Konto, dessen 165 Bytes ein SPL-Token-Konto nachahmen, das das USDC-Mint, die Autorität des Angreifers und ein u64::MAX-Guthaben trägt.

  • Schritt 2: Die Output-CPI erreichte Tokenkeg und transferierte 195.849,433667 KMNO aus dem KMNO-Tresor von Aquifer an das Token-Konto EUjkGc... des Angreifers, das vom Signer 7fTe9p...4gRk7J kontrolliert wird.

  • Schritt 3: Die Input-CPI erreichte DMBpPM...NRgb68 mit USDC-Transfer-förmigen Daten. Dieses Programm gab Erfolg zurück, ohne dass USDC von der gefälschten Quelle 9gsKJc... in den echten USDC-Tresor 7ULN1Y... von Aquifer bewegt wurde.
  • Schritt 4: Aquifer akzeptierte beide CPI-Rückgaben, sodass der Swap atomar committet wurde.

Die resultierenden Guthabenänderungen für diese Transaktion sind wie folgt.

Konto Vorher Nachher Änderung
Aquifer-KMNO-Tresor 9BHsZp...FHSqG 604.968,018277 KMNO 409.118,584610 KMNO -195.849,433667 KMNO
Angreifer-KMNO-Konto EUjkGc... 0 KMNO 195.849,433667 KMNO +195.849,433667 KMNO
Aquifer-USDC-Tresor 7ULN1Y... 1.620.342,341679 USDC 1.620.342,341679 USDC 0 USDC

Diese Zahlen beschreiben nur dieses Beispiel für eine Transaktion, nicht den Gesamtschaden des Vorfalls.

Fazit

Die Grundursache ist eine ungeprüfte Aufrufer-Eingabe auf dem Abwicklungspfad, nicht eine Preis- oder Orakelmanipulation: Der Swap-Pfad validierte eine Token-Program-Konstante und ersetzte sie dann vor der Ausführung der Instruktion durch eine vom Aufrufer angegebene, sodass es dem Aufrufer überlassen blieb, welches Programm den Transfer ausführte, der Aquifer hätte bezahlen sollen. Ohne eine Guthabenprüfung nach dem Transfer im Tresor erfüllt ein Programm, das Erfolg zurückgibt, ohne Token zu bewegen, die Zahlung, während der Transfer in die andere Richtung reale Assets liefert.

Jede CPI sollte an das Token Program gebunden werden, dem das bewegte Mint gehört, aufgelöst aus dem Mint Account und nicht aus vom Aufrufer angegebenen Konten entnommen, und das Guthaben des Tresors sollte vor und nach dem Input-Transfer gelesen werden, sodass der Swap zurückgesetzt wird, sofern der Tresor nicht tatsächlich den zitierten Betrag erhalten hat.


Notional Finance

Am 03.-04.09.2026 (UTC) wurde Notional Finance V1 auf Ethereum für etwa 1,73 Mio. USD ausgenutzt, abgezogen als 69.257,37 DAI und 1.658.524,86 USDC. Bevor einem Konto die Aufnahme von Schulden gestattet wird, bewertet das Protokoll alles, was dieses Konto hält und schuldet, und eine unsichere numerische Umwandlung auf diesem Pfad ließ eine Schuld in der richtigen Größenordnung auf null zusammenschrumpfen. Die Prüfung ließ daher ein Konto passieren, dessen Verbindlichkeit verschwunden war, während der große Anspruch, den es geschaffen hatte, unangetastet auf einem anderen vom Angreifer kontrollierten Contract lag. Der Angreifer hatte diesen gefälschten Anspruch so getimt, dass er zur nächsten Fälligkeit des Protokolls, Mitternacht UTC, fällig wurde, und rechnete ihn wenige Minuten später ab, um das DAI und USDC abzuheben, das das Protokoll noch hielt.

Hintergrund

Notional Finance V1 ist ein Festzins-Lending-Protokoll auf Ethereum. Es repräsentiert Zahlungsströme zu vordefinierten Fälligkeiten mit fCash: Ein CASH_RECEIVER ist eine positive Position, die zur Fälligkeit Anspruch auf den Erhalt von Assets hat, und ein CASH_PAYER ist eine negative Position, die verpflichtet ist, diese zu zahlen. Die fCash- und anderen Positionen jedes Kontos werden in seinem Portfolio erfasst, wobei ein Asset durch seine Cash-Gruppe zusammen mit seiner Fälligkeit identifiziert wird; die Cash-Gruppe legt die Währung fest, in der abgerechnet wird. Der Nominalwert eines einzelnen Assets, der Betrag, für den es zur Fälligkeit abgerechnet wird, ist ein uint128.

ERC1155Trade.safeTransferFrom() erstellt ein fCash-Paar zwischen zwei Konten. Der Aufruf ist wie ein ERC-1155-Transfer geformt, aber es wechselt nichts den Besitzer: Er ruft Portfolios.mintfCashPair() auf, um zwei gegenläufige Positionen zu erstellen, eine positive für den Empfänger und eine gleich große negative für den Zahler. Jede Seite wird durch _upsertAsset() in das entsprechende Portfolio geschrieben, das eine neue Position nur dann in einen bestehenden Eintrag einfügt, wenn sowohl Cash-Gruppe als auch Fälligkeit übereinstimmen, wobei die beiden Nominalwerte über eine durch SafeUInt128 geprüfte Addition addiert werden.

Die Solvenz wird beim Zahler über freeCollateral() geprüft, das die Escrow-Cash-Guthaben des Kontos mit seiner Portfoliobewertung kombiniert und die Einträge pro Währung zu einem vorzeichenbehafteten int256 summiert. Jedes Währungsguthaben wird dann zu dem für diese Währung geltenden Wechselkurs in ETH umgerechnet, wobei der Kurs und die Dezimalskalierung als ganzzahlige Divisionen angewendet werden, und die endgültige freie Sicherheit muss nicht-negativ sein. Zur Fälligkeit wird eine fCash-Position über Escrow.portfolioSettleCash() in das Cash-Guthaben des Kontos abgerechnet, und ein positives Cash-Guthaben kann dann als entsprechendes zugrunde liegendes Asset aus dem Escrow abgehoben werden.

Schwachstellenanalyse

Die fehlerhaften Contracts sind der Einstiegspunkt ERC1155Trade (0xbba8...ef08), der fCash-Paare ohne Nominalwertgrenze prägt, und der Escrow (0x9abd...f683), dessen Sicherheitenbewertung in _convertToETH() zwei arithmetische Defekte trägt, die eine Schuld auf null bewerten können.

Erstens kann eine ungeprüfte verengende Umwandlung eine große Schuld auf null trunkieren. Die Funktion wandelt balance.abs() direkt über eine rohe Typumwandlung in uint128 um und prüft nie, ob der Wert in den Zieltyp passt. Die beiden Typen liegen weit auseinander: Ein vorzeichenbehaftetes int256 reicht bis 2^255 - 1, während uint128 bei 2^128 - 1 endet. Ein Guthaben von exakt -2^128 passt daher bequem in int256, und balance.abs() liefert unverändert 2^128. Es ist die Typumwandlung, die versagt: 2^128 liegt einen Schritt jenseits dessen, was uint128 fassen kann, und wickelt sich um zu 0, sodass die anschließende Bewertung mit einem Nullguthaben arbeitet und die gesamte Schuld aus der Berechnung der freien Sicherheit herausfällt. Dieselbe Funktion verwendet SafeCast.toUint128() für die spätere Umwandlung des berechneten ETH-Werts, was bei einem außerhalb des Bereichs liegenden Ergebnis revertieren würde, während die frühere Umwandlung eine direkte Typumwandlung bleibt und stillschweigend trunkiert.

Zweitens kann eine ganzzahlige Division kleine Schulden auf null runden. Die Divisionen durch er.rateDecimals und baseDecimals trunkieren ihre Reste, sodass auch eine hinreichend kleine Schuld mit 0 bewertet und aus der freien Sicherheit ausgeschlossen wird.

Angriffsanalyse

Die folgende Analyse basiert auf der Transaktion 0xe1589a...25d60a.

  • Schritt 1: Um 23:58:47 UTC am 3. September 2026 rief der Angreifer safeTransferFrom() auf ERC1155Trade auf, um ein fCash-Paar mit einem Betrag von 1 zu prägen, unter Verwendung von cashGroupId = 2 und dem Fälligkeitszeitstempel 1788480000 (4. September 2026, 00:00 UTC), 73 Sekunden im Voraus und die näher liegende der beiden offenen Fälligkeiten des Protokolls. Während des Prägens verzeichnete _upsertAsset() die negative fCash-Verbindlichkeit auf dem Contract des Angreifers und den positiven Anspruch auf dem Empfänger-Contract, und Portfolios prüfte sofort die freie Sicherheit des Contracts des Angreifers. Dieser Contract hielt in keiner Währung ein Guthaben, sodass jede positive Bewertung der neuen Verbindlichkeit die Prüfung hätte scheitern lassen. Der zweite Defekt deckte dies ab: Beim aktuellen Wechselkurs übersteht eine Schuld von 1 die beiden ganzzahligen Divisionen nicht, sodass sie mit null bewertet wurde und die Prüfung bestand.

  • Schritt 2: Der Angreifer rief safeTransferFrom() erneut auf, um ein zweites Paar mit einem Betrag von uint128.max (340.282.366.920.938.463.463.374.607.431.768.211.455) zu prägen. Dieses Paar verwendete erneut cashGroupId = 2, trug aber den Fälligkeitszeitstempel 1796256000 (3. Dezember 2026, 00:00 UTC), die andere offene Fälligkeit, und sandte seine positive Seite an einen anderen Empfänger-Contract. Die negative Seite landete erneut auf dem Contract des Angreifers, neben der aus Schritt 1. Ein einzelnes Prägen kann niemals 2^128 - 1 überschreiten, immer eine Einheit unter dem Wert, der trunkiert, sodass es zwei Positionen braucht, um ihn zu erreichen. Die unterschiedliche Fälligkeit hielt die beiden in getrennten Einträgen, außerhalb der Reichweite der geprüften Addition, die bei einer Zusammenführung revertiert hätte; die gemeinsame Cash-Gruppe brachte sie bei der Bewertung dennoch in denselben Währungs-Slot, wo die Einheit aus Schritt 1 die Summe auf exakt -2^128 trieb.

  • Schritt 3: Während der Sicherheitenprüfung rief der Escrow-Proxy convertBalancesToETH() auf. Das aggregierte negative Guthaben erreichte exakt -2^128, wurde in _convertToETH() übergeben und auf null trunkiert, sodass die in ETH denominierte Verbindlichkeit des Kontos als null gemeldet wurde.

  • Schritt 4: Da die Schuld aus der Sicherheitenbuchhaltung verschwunden war, hielt der zweite Empfänger-Contract eine große positive fCash-Position, die das Protokoll als verfügbare Sicherheit behandelte. Noch innerhalb derselben Transaktion prägte er gegen diese Sicherheit zwei weitere fCash-Paare und übergab die positive Seite an zwei weitere Empfänger-Contracts: 69.257,37 unter cashGroupId = 2, das in DAI abrechnet, und 1.658.524,86 unter cashGroupId = 3, das in USDC abrechnet. Beide Zahlen stammten aus balanceOf-Aufrufen, die der Angreifer zu Beginn der Transaktion beim Escrow getätigt hatte, sodass jeder Anspruch auf ein Guthaben zugeschnitten war, das der Escrow tatsächlich hielt. Jeder trug die Fälligkeit 1788480000, 73 Sekunden entfernt.

  • Schritt 5: Um 00:01:35 UTC am 4. September 2026, 95 Sekunden nach dieser Fälligkeit, rechnete der Angreifer die beiden fälligen Ansprüche in Transaktion 0xc3f3e3...a24efa ab und hob ~69.257,37 DAI und ~1.658.524,86 USDC vom Escrow ab. Die Mittel wurden später an 0x8aaf...3be6 weitergeleitet.

Fazit

Der Prägepfad kennt keine Nominalwertgrenze, und zwei arithmetische Defekte in der Sicherheitenbewertung ließen jeweils eine Solvenzprüfung passieren: Rundung ließ ein Konto, das nichts hielt, seine erste Verbindlichkeit eingehen, und eine stillschweigende verengende Umwandlung bewertete dann eine Schuld exakt der richtigen Größe mit null, sodass die zweite Prüfung bei einem tief insolventen Konto bestand. Die gefälschte positive Position auf dem Empfänger-Contract wurde dann als verfügbare Sicherheit behandelt, was es dem Angreifer erlaubte, sie in Ansprüche aufzuteilen, die zu den Guthaben des Escrows passten, und das DAI und USDC, das er noch hielt, abzuheben.

Vorzeichenbehaftete Guthaben müssen vor jeder verengenden Umwandlung bereichsgeprüft werden, und eine Umwandlung, die ihre Eingabe nicht darstellen kann, sollte revertieren statt trunkieren. Allgemeiner sollte eine Solvenzprüfung niemals eine von null verschiedene Schuld als null melden, egal ob die Arithmetik sie durch eine Typumwandlung oder einen Rundungsschritt verliert. Die Anwendung derselben geprüften Typumwandlung, die diese Funktion bereits weiter unten verwendet, oder die Begrenzung des Nominalwerts, den eine einzelne Paarprägung erzeugen kann, hätte diesen Exploit jeweils für sich allein gestoppt.

Erste Schritte mit Phalcon Security

Erkennen Sie jede Bedrohung, warnen Sie bei Relevantem und blockieren Sie Angriffe.

Jetzt kostenlos testen

Referenzen

[1] https://github.com/InjectiveFoundation/injective-core/commit/b994d6b603eb53a38312e547f7bbe3c69d40495b

[2] https://mpost.io/injective-exploited-for-4-9m-via-market-id-collision-in-binary-options-settlement-logic/

[3] https://x.com/flow_blockchain/status/2094506622429307061

[4] https://bitquery.io/investigations/aquifer-solana-hack-2-5-million

Über BlockSec

BlockSec ist ein Full-Stack-Anbieter für Blockchain-Sicherheit und Krypto-Compliance. Wir entwickeln Produkte und Dienstleistungen, die Kunden dabei helfen, Code-Audits durchzuführen (einschließlich Smart Contracts, Blockchain und Wallets), Angriffe in Echtzeit abzufangen, Vorfälle zu analysieren, illegale Gelder zurückzuverfolgen und AML/CFT-Pflichten zu erfüllen – über den gesamten Lebenszyklus von Protokollen und Plattformen hinweg.

BlockSec hat mehrere Blockchain-Sicherheitspapiere auf renommierten Konferenzen veröffentlicht, mehrere Zero-Day-Angriffe auf DeFi-Anwendungen gemeldet, mehrere Hacks blockiert, um mehr als 20 Millionen Dollar zu retten, und Kryptowährungen im Wert von Milliarden gesichert.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit