Cross-Chain, DeFi und Smart Contracts · Lektion 2 von 6
DEX-Swaps, Sofortbörsen und Liquiditätsflüsse
13 Min. Lesezeit
Bei nahezu jeder Geldwäschespur wird irgendwann der Vermögenswert gewechselt. Wie dieser Wechsel erfolgt, entscheidet darüber, wie belastbar die nächste Verknüpfung sein kann. Ein Swap auf einer dezentralen Börse (DEX) wird in einer einzigen Transaktion aufgezeichnet, einschließlich des Pool-Ereignisses, der Token-Transfers und der Reserven davor und danach. Ein Cross-Chain-Swap-Protokoll kann das Ziel in die Ausgangsblockchain und den Ursprung in die Zielblockchain schreiben. Eine Sofortbörse oder ein OTC-Handelsdesk hinterlässt lediglich eine Einzahlung auf der einen und eine Auszahlung auf der anderen Seite. Diese Lektion zeigt, wie Sie jede Art von Swap als Beweismittel auswerten, was Liquiditätsereignisse offenlegen, welche Aufzeichnungen außerhalb der Blockchain existieren und welche Aussagen Sie über die jeweilige Verknüpfung treffen dürfen. Die allgemeine Dekodierung wird in Lektion 5.1 behandelt, die Zuordnung von Transaktionsschritten über verschiedene Blockchains hinweg in Lektion 5.3 und Bridges in Lektion 5.4.
Einen DEX-Swap auswerten
Pools, token0 und token1
Ein Paar nach dem Vorbild von Uniswap v2 ist ein Smart Contract, der zwei Token hält. Der Token mit der niedrigeren Adresse ist token0, der andere token1; die Reihenfolge wird bei der Erstellung festgelegt und hat nichts damit zu tun, welcher Token „der Preis“ ist. Jedes Ereignis gibt die Beträge in dieser Reihenfolge an. Ermitteln Sie daher token0, token1 und die Dezimalstellen beider Token, bevor Sie etwas umrechnen.
Das v2-Ereignis lautet Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to), topic0 0xd78ad95f…d822. Nach jeder Änderung der Reserven gibt das Paar außerdem Sync(uint112 reserve0, uint112 reserve1) aus. Ein dekodierter Swap in einem Paar, in dem token0 USDC (6 Dezimalstellen) und token1 WETH (18 Dezimalstellen) ist:
{
"event": "Swap",
"pair": "0x3f8a…e2d1",
"sender": "0x7a2c…48d0",
"to": "0xa1b2c3d4…9f0e",
"amount0In": "0",
"amount1In": "5000000000000000000",
"amount0Out": "14880819116",
"amount1Out": "0",
"next_log": {"event": "Sync", "reserve0": "2985119180884", "reserve1": "1005000000000000000000"}
}
Fünf WETH flossen hinein und 14.880,819116 USDC heraus, bei einem Ausführungspreis von 2.976,16 USDC pro WETH. Der sender ist in der Regel ein Router, nicht der Händler, und to gibt an, wohin die Ausgabe floss; bestätigen Sie den Händler anhand der Token-Transfers in derselben Transaktion.
Andere Pool-Designs
Uniswap-v3-Pools geben Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick) aus, topic0 0xc42079f9…ca67, wobei die Beträge aus Sicht des Pools mit einem Vorzeichen versehen sind: positiv in den Pool hinein, negativ aus ihm heraus. Ein Swap von 2 WETH gegen USDC zeigt amount0 = -5994120000 (5.994,12 USDC heraus) und amount1 = 2000000000000000000 (2 WETH hinein). Der Preis nach dem Swap ist price_raw = (sqrtPriceX96 ÷ 2^96)², in Basiseinheiten von token1 pro Basiseinheit von token0, multipliziert mit 10^(decimals0 − decimals1). Für sqrtPriceX96 = 1446501726624926496477173928747177 ist price_raw ≈ 333.333.333,33; multipliziert mit 10^−12 ergibt das 0,000333333 WETH pro USDC oder 3.000 USDC pro WETH (tick ≈ 196.256, da price_raw = 1,0001^tick). Ohne die Anpassung an die Dezimalstellen weicht der Preis um den Faktor 10^12 ab.
Uniswap v4 (2025) hält alle Pools in einem einzigen PoolManager, sodass die address des Logs nicht mehr den Pool identifiziert; dies übernimmt die indexierte Pool-id. Sein Swap-Ereignis (topic0 0x40e9cecb…112f) versieht Beträge aus Sicht des Nutzers mit Vorzeichen, also umgekehrt zu v3. Curve-Pools geben TokenExchange mit Coin-Indizes aus. Halten Sie für jedes Protokoll und jede Version einen eigenen Decoder vor, der an einer Transaktion mit bekanntem Ergebnis getestet wurde.
Vier Regeln für die Nachverfolgung
- Die Verknüpfung ist deterministisch, der Vermögenswert ändert sich. Eingabe und Ausgabe erscheinen in derselben Transaktion. Erfassen Sie beide Beträge, den effektiven Kurs und für einen Fiatwert die Preisquelle und den Zeitpunkt. Unabhängig davon, welche Nachverfolgungsmethode Sie anwenden (Lektion 3.3), ist die Ausgabe des Swaps der Erlös seiner Eingabe.
- Der Pool ist keine Gegenpartei. Ein Liquiditätspool ist ein Smart Contract, der die Mittel vieler Liquiditätsanbieter hält. Die Mittel gehen nicht „an“ den Pool-Eigentümer; verfolgen Sie die Ausgabe, nicht den Pool.
- Der Empfänger kann vom Absender abweichen. Router und Aggregatoren akzeptieren einen Empfängerparameter, sodass die Ausgabe in derselben Transaktion an eine neue Adresse ausgezahlt werden kann. Lesen Sie den dekodierten Aufruf oder die Transfers; gehen Sie niemals davon aus, dass der Aufrufer die Ausgabe erhalten hat.
- Saldieren Sie die Route. Ein Aggregator verteilt einen Auftrag innerhalb einer Transaktion auf mehrere Pools. Was die untersuchte Person verlassen hat und was beim Empfänger angekommen ist, sind die Fakten; die Route ist ein Detail.
DEX-Contracts haben keinen Betreiber, der Aufzeichnungen führt. Die von einer untersuchten Person verwendete Benutzeroberfläche kann jedoch einen solchen haben: Web-Frontends und Aggregator-APIs können IP-Adressen, User-Agents und Kursanfragen protokollieren, und Wallet-Anwendungen können Swaps über ihre eigenen APIs leiten. Die Aufbewahrung hängt vom Betreiber ab.
Eine Aggregator-Route saldieren
| logIndex | Token | Von | An | Betrag |
|---|---|---|---|---|
| 10 | WETH | Händler | Router | 10 |
| 11 | WETH | Router | Pool A (WETH/USDC) | 6 |
| 12 | USDC | Pool A | Router | 17.880 |
| 13 | WETH | Router | Pool B (WETH/DAI) | 4 |
| 14 | DAI | Pool B | Pool C (DAI/USDC) | 11.930 |
| 15 | USDC | Pool C | Router | 11.925 |
| 16 | USDC | Router | Händler | 29.805 |
Durch das Saldieren der Zu- und Abflüsse jeder Adresse lässt sich dies auf eine Aussage reduzieren: Der Händler verkaufte 10 WETH für 29.805 USDC, durchschnittlich 2.980,50 USDC pro WETH. Der Saldo des Routers ist null, und der Saldo jedes Pools entspricht seiner jeweiligen Reserveänderung.
-- Nettoänderung der Token je Adresse innerhalb einer Transaktion
SELECT address, token_address, SUM(delta) AS net_raw
FROM (
SELECT to_address AS address, token_address, amount_raw AS delta
FROM token_transfers WHERE transaction_hash = '0x9e1d…b7a4'
UNION ALL
SELECT from_address, token_address, -amount_raw
FROM token_transfers WHERE transaction_hash = '0x9e1d…b7a4'
) t
GROUP BY address, token_address
HAVING SUM(delta) <> 0;
Transfers von nativem ETH müssen aus den Traces ergänzt werden. In absichtsbasierten Systemen sendet ein Solver, nicht der Nutzer, die Transaktion, sodass tx.from den Solver bezeichnet; ermitteln Sie den Nutzer anhand der Handelsereignisse und Transfers des Abwicklungs-Contracts.
Liquiditätsflüsse, Preisauswirkung und MEV
Hinzufügen und Entfernen
Gestohlene Mittel einem Pool hinzuzufügen und später wieder zu entfernen, ist kein Swap: Der Einzahler erhält einen LP-Token oder eine Position, und beim Entfernen wird der Anteil zurückgegeben. Verfolgen Sie die Position, nicht den Kontostand des Pools.
| Protokoll | Hinzufügen | Entfernen | Eigentumsnachweis |
|---|---|---|---|
| Uniswap v2 | Mint(sender, amount0, amount1) plus LP-Token-Transfer von der Nulladresse | LP-Token an das Paar gesendet, Burn(sender, amount0, amount1, to), LP-Transfer an die Nulladresse | Fungibler LP-Token (der Paar-Contract) |
| Uniswap v3 | Pool-Mint mit Tick-Bereich; IncreaseLiquidity beim Positionsmanager | Pool-Burn (schreibt Token gut), dann Collect (zahlt sie aus); DecreaseLiquidity | Positions-NFT (ERC-721) |
| Uniswap v4 | ModifyLiquidity im PoolManager | Dasselbe Ereignis, negatives Liquiditätsdelta | Positionsaufzeichnungen, häufig ein NFT |
Zwei Fallstricke: In v3 zeigt das Mint des Pools den Positionsmanager als Eigentümer an. Verfolgen Sie daher den Positions-NFT bis zum tatsächlichen Liquiditätsanbieter. Außerdem bewegt ein v3-Burn keine Token; das Geld fließt erst bei Collect ab. Bei einem klassischen Rug Pull erstellt ein Deployer einen Token, fügt Liquidität hinzu, wartet auf Käufer und entfernt dann nahezu die gesamte Liquidität in einer einzigen Transaktion; die Burn- oder DecreaseLiquidity-Beträge messen, was entnommen wurde.
Preisauswirkung
Die Preisauswirkung vergleicht den Ausführungspreis mit dem Spotpreis des Pools unmittelbar vor dem Handel. Bei einem v2-Paar entsprechen die Reserven vor dem Swap den Reserven in dessen Sync-Ereignis abzüglich der Eingaben zuzüglich der Ausgaben. Beim obigen Swap: 2.985.119,18 + 14.880,82 = 3.000.000 USDC und 1.005 − 5 = 1.000 WETH, also ein Spotpreis von 3.000.
| Kennzahl | Wert |
|---|---|
| Spotpreis davor | 3.000,00 USDC pro WETH |
| Ausführungspreis | 2.976,16 (−0,79%) |
| Ausgabe ohne die Gebühr von 0,30% | 14.925,37, Preis 2.985,07 (−0,50%) |
| Spotpreis danach (aus Sync) | 2.970,27 (−0,99%) |
Von der Abweichung von 0,79% entfallen etwa 0,30% auf die Gebühr und 0,50% auf die reine Preisauswirkung; der Spotpreis veränderte sich etwa doppelt so stark wie der durchschnittlich gezahlte Preis, was für Pools mit konstantem Produkt normal ist. Eine starke Preisauswirkung in einem Pool mit geringer Liquidität deutet auf Verkaufsdruck hin, etwa wenn ein Angreifer einen gestohlenen Token massenhaft verkauft.
MEV-Muster
Maximal extrahierbarer Wert (MEV) weist erkennbare Muster auf. Bei einem Sandwich kauft Akteur X innerhalb eines Blocks und Pools Token T, ein Opfer kauft T, und X verkauft T unmittelbar danach. Häufig bezahlt X den Block-Builder direkt (ein ETH-Transfer an den Gebührenempfänger, sichtbar in Traces); definieren Sie den Akteur als den Bot-Contract, der die Ausgabe erhalten hat, da Bots ihre Absenderadressen wechseln. Atomare Arbitrage führt innerhalb einer Transaktion Swaps durch einen Kreislauf von Pools aus (WETH → USDC → DAI → WETH) und endet mit einer größeren Menge des Ausgangstokens. Just-in-time-Liquidität (JIT) besteht aus einem v3-Mint unmittelbar vor einem großen Swap sowie einem Burn und Collect unmittelbar danach, jeweils durch dieselbe Adresse. Treffer sind zunächst Kandidaten: Prüfen Sie Mengen und Gewinn und schließen Sie unverdächtige Erklärungen wie zwei voneinander unabhängige Arbitragehändler aus.
Cross-Chain-Swap-Protokolle: Memos als Beweismittel
Cross-Chain-Swap-Protokolle tauschen native Vermögenswerte über Vaults, die von den Knoten des Protokolls kontrolliert werden, zwischen Blockchains aus. THORChain ist das Referenzbeispiel. Seine Aufzeichnungen sind ungewöhnlich nützlich, weil beide Seiten Text enthalten, der die jeweils andere Seite benennt.
Auf der Eingangsseite sendet der Nutzer den Vermögenswert an den Vault des Protokolls: auf EVM-Blockchains über einen Router-Contract, der das Memo in seinem Einzahlungsereignis aufzeichnet; auf Bitcoin in einem OP_RETURN-Output, den die Protokolldokumentation auf 80 bytes begrenzt. Das Format des Swap-Memos lautet SWAP:ASSET:DESTADDR/REFUNDADDR:LIMIT/INTERVAL/QUANTITY:AFFILIATE:FEE (die Rückerstattungsadresse ist optional), bei einem Markt-Swap meist mit = abgekürzt. Auf der Ausgangsseite zahlt der Vault den Zielvermögenswert in einer Transaktion aus, deren Memo aus OUT: gefolgt vom Hash der Eingangstransaktion besteht; ein fehlgeschlagener Swap wird mit einem REFUND:-Memo erstattet, das denselben Hash enthält. Ein fiktives Paar:
Ethereum (eingehend, fiktiv)
tx 0x9a3f…c21e von 0x3f9c…a1d7 an Swap-Router 130.0 ETH
Memo des Einzahlungsereignisses "=:BTC.BTC:bc1q…r7w2::xx:20"
Bitcoin (ausgehend, fiktiv)
txid 6d0b…e45a von Vault bc1q…v9tn
vout 0 5.16800000 BTC bc1q…r7w2
vout 1 OP_RETURN "OUT:9A3F…C21E"
Das eingehende Memo benennt den Bitcoin-Empfänger; das ausgehende Memo benennt die Ethereum-Transaktion. Das Paar lässt sich auf beiden Blockchains über Ihre eigenen Knoten verifizieren, und die öffentlichen Aufzeichnungen des Protokolls liefern eine dritte, unabhängige Bestätigung. Drei Details sind wichtig:
- Zeitlicher Ablauf. Streaming-Swaps werden als Teil-Swaps über mehrere Blöcke ausgeführt, und Limit-Swaps können standardmäßig bis zu 43.200 Protokollblöcke (etwa drei Tage) in einer Warteschlange warten. Legen Sie Zeitfenster anhand der Memo-Parameter fest.
- Affiliates. Das Affiliate-Feld benennt über einen registrierten Kurznamen die Benutzeroberfläche oder Wallet, die die Transaktion erstellt hat: eine mögliche Quelle für Protokolldaten, auch wenn das Protokoll selbst keine hat.
- Referenz-Memos. Um Platz im Memo zu sparen, kann ein Memo vorab registriert und referenziert werden, beispielsweise durch eine im Betrag kodierte Referenz; Registrierungen laufen nach dem Parameter
MemolessTxnTTLab, standardmäßig nach 3.600 Blöcken (etwa sechs Stunden). Sichern Sie den Registrierungsdatensatz zusammen mit den Transaktionen.
Andere Protokolle verwenden andere Felder, aber die Methode ist dieselbe: Ermitteln Sie, was jede Seite über die andere aussagt.
Sofortbörsen und OTC-Handelsdesks
Sofortbörsen wandeln einen Vermögenswert ohne Konto in einen anderen um: Der Nutzer gibt eine Auszahlungsadresse an, erhält eine neue Einzahlungsadresse für den Auftrag, sendet Mittel und erhält eine Auszahlung, häufig auf einer anderen Blockchain. Viele bezeichnen sich als nicht verwahrend, weil sie keine Guthaben halten. Sie kontrollieren die Mittel jedoch zwischen Einzahlung und Auszahlung, weshalb die Spur dort abbricht. Zudem ist der Tausch eines virtuellen Vermögenswerts gegen einen anderen für einen Kunden oder in dessen Auftrag nach der in Empfehlung 15 verwendeten FATF-Definition eine VASP-Tätigkeit. Auf der Blockchain sehen sie wie jeder verwahrende Dienst aus: auftragsspezifische Einzahlungsadressen, Sammeltransfers und Auszahlungen aus einer Hot Wallet. Ohne Aufzeichnungen ist die Verknüpfung zwischen Einzahlung und Auszahlung eine Schlussfolgerung aus Betrag und Zeit (Lektion 5.3); mit Aufzeichnungen ist sie dokumentiert. Ein Dienst kann Folgendes vorhalten:
| Aufzeichnung | Beweiswert |
|---|---|
| Auftrags-ID, Erstellungszeitpunkt, Vermögenswerte und angebotener Kurs | Ordnet eine Einzahlungsadresse einem Auftrag zu |
| Einzahlungsadresse und Einzahlungs-txid | Bestätigt, welche Einzahlung zum Auftrag gehört |
| Auszahlungsadresse und Auszahlungs-txid | Macht aus der erschlossenen Verknüpfung eine aufgezeichnete |
| Rückerstattungsadresse | Häufig eine von der untersuchten Person kontrollierte Wallet; verknüpft weitere Aufträge |
| IP-Adresse, User-Agent, Spracheinstellungen | Ansatzpunkte für die Zuordnung (Lektion 4.7) |
| E-Mail-Adresse oder für den Support angegebene Kontaktdaten | Identifikator für weitere rechtliche Maßnahmen |
| Partner- oder Affiliate-ID | Identifiziert die Wallet oder Website, die den Auftrag übermittelt hat |
| Risikokennzeichnungen, Zurückhaltungen und Screening-Ergebnisse | Zeigt, ob der Dienst den Auftrag eingefroren oder hinterfragt hat |
Fordern Sie alle Aufträge an, die im betreffenden Zeitraum dieselbe Auszahlungsadresse, Rückerstattungsadresse oder IP-Adresse aufweisen, nicht nur den von Ihnen gefundenen: Der Verlauf offenbart häufig weitere Wallets der untersuchten Person. IP-Adressen können zu VPNs gehören, und Kontaktdaten sind nicht verifiziert. Die Zusammenarbeit verläuft häufig langsam. Senden Sie deshalb Ersuchen um Datensicherung, sobald die Einzahlung identifiziert ist (Lektion 1.4).
Ein OTC-Handelsdesk handelt Geschäfte außerhalb der Blockchain aus und wickelt sie über seine eigenen Adressen ab. Die Teiltransaktionen können auf unterschiedlichen Blockchains liegen, oder eine davon kann eine Banküberweisung sein, sodass häufig überhaupt keine On-Chain-Verknüpfung besteht; die Aufzeichnungen des Handelsdesks (Sorgfaltsprüfungen, Handelsbestätigungen, Abwicklungsanweisungen, Chatprotokolle, Bankverbindungen) bilden die einzige Brücke. Ein Broker, der über ein Konto bei einer größeren Börse handelt, fügt eine weitere Ebene hinzu: Die Börse sieht einen Kunden, den Broker (Lektion 6.5).
Welche Aussagen Sie über die jeweilige Swap-Verknüpfung treffen dürfen
| Verfügbare Beweismittel | Grundlage der Verknüpfung | Formulierung im Bericht |
|---|---|---|
| DEX-Swap innerhalb derselben Transaktion | Deterministisch (Grad A) | „In Transaktion T wurde X gegen Y getauscht und an Adresse B ausgezahlt“ |
| Cross-Chain-Memo auf beiden Blockchains | Auf beiden Blockchains deterministisch (Grad A), außerdem im Protokoll aufgezeichnet | „Das Protokoll zahlte Z im Zusammenhang mit Eingangstransaktion A an Adresse B aus“ |
| Sofortbörse, nur Betrag und Zeit | Schlussfolgerung (Grad D) | „Vereinbar mit“, unter Angabe der Kandidatenanzahl und der Rate zufälliger Übereinstimmungen |
| Sofortbörse mit Auftragsdatensatz | Durch Aufzeichnungen bestätigt (Grad B) | „Laut den Aufzeichnungen des Dienstes wurden mit Auftrag N Z an Adresse B ausgezahlt“ |
| OTC-Handelsdesk, keine Aufzeichnungen | Keine | „Das Ziel dieser Mittel ist nicht bekannt“ |
Die Grade entsprechen denen aus Lektion 3.2. Eine durch Aufzeichnungen bestätigte Verknüpfung ist nur so zuverlässig wie die Aufzeichnung: Nennen Sie den Ersteller, das Eingangsdatum und den Hash der Datei in der erhaltenen Form.
Prüfungsschwerpunkt: Reihenfolge von token0/token1 und Dezimalstellen; v2-Swap- und Sync-Ereignisse; vorzeichenbehaftete Beträge in v3 (positiv in den Pool hinein) und Umrechnung von sqrtPriceX96 mit Anpassung an die Dezimalstellen; PoolManager, Pool-ID und umgekehrtes Vorzeichen in v4; DEX-Swaps als deterministische Verknüpfungen mit Wechsel des Vermögenswerts, Pools als Nicht-Gegenparteien und Empfängerparameter; Saldieren einer Aggregator-Route und warum tx.from ein Router oder Solver sein kann; Positions-NFTs, Burn gefolgt von Collect und Rug Pulls; Preisauswirkung anhand der Reserven; Erkennungsmuster von Sandwich, Arbitrage und JIT; Cross-Chain-Memos, OUT: und REFUND: mit dem Hash der Eingangstransaktion, zeitlicher Ablauf von Swaps, Affiliates und Referenz-Memos; Sofortbörsen als VASPs und ihre Aufzeichnungen; OTC-Handelsdesks ohne On-Chain-Verknüpfung; Abstimmung der Formulierung auf die Grundlage der jeweiligen Verknüpfung.