Der dritte Artikel unserer Reihe zur Erklärung des Fusion-Modus konzentriert sich auf die Onchain-Komponente der Swap-Auflösung.
In den beiden vorherigen Artikeln der Serie haben wir das Konzept eines Resolvers und die Offchain-Komponente des Swap-Auflösungsprozesses besprochen.
Machen wir dort weiter, wo wir aufgehört haben. Wir befinden uns in einer Phase des Swap-Auflösungsprozesses, in der das Backend des Resolvers „beschlossen“ hat, eine Fusion-Bestellung, die es vom 1inch-Relayer-Dienst erhalten hat, in einem bestimmten Block auszuführen, wobei eine bestimmte Menge des getauschten Vermögenswerts an den Benutzer zurückgegeben werden soll. Jetzt gehen wir den Onchain-Teil des Swap-Auflösungsprozesses durch. Aber zuerst beschreiben wir die Teilnehmer an diesem Prozess.
Der Onchain-Teil der Fusion-Swap-Ausführung umfasst recht komplexe Interaktionen zwischen den folgenden Blockchain-Entitäten:

Ein sehr wichtiger Hinweis: In einigen Fällen (nicht immer) führt ein Resolver mehrere Füllungen in einem Stapel durch, bis zu 32. Normalerweise gibt es mehrere Token-Guthaben im Arbeitsvertrag des Resolvers und das Backend kann mehrere Aufträge aus dem vom Relayer bereitgestellten „Stream“ übernehmen und eine Abfolge von Füllungen durchführen.
Wir gehen das folgende Szenario durch.
Ein Resolver wählte drei potenziell lukrative Aufträge des Relayers zur Ausführung aus:
100 DAI für mindestens 0,6 WETH
0,6 WETH für mindestens 100 DAI
0,01 WBTC für mindestens 36 UNI
Das Geschäftsziel des Resolvers besteht darin, alle 3 Swaps so auszuführen, dass die Benutzer mindestens den erwarteten Betrag erhalten. Wir lassen die möglichen Verdienststrategien der Resolver außen vor und vereinfachen die Berechnungen, damit Sie die Grundidee verstehen.
Nun stellt das Backend dem Arbeitsvertrag Informationen zu den ausgewählten Aufträgen zur Verfügung. Was passiert als nächstes?
NB: Dieses Diagramm ist eine Fortsetzung eines Diagramms aus dem Artikel, der der Offchain-Komponente der Swap-Auflösung gewidmet ist. Der Einfachheit halber beginnen wir jedoch mit Schritt 1.

Schritt 1
Der Worker-Vertrag (oder die Wallet) ruft die Methode settleOrders() des 1-Zoll-Abwicklungsvertrags auf und liefert die Auftragsinformationen in einem leicht komprimierten Byte-Format. Zum Speichern dieser Informationen werden die Argumente calldata und tokensAndAmounts verwendet.
Hier fallen Ihnen vielleicht ein paar interessante Details auf:
RateBump kommt vom Quotierer und bestimmt effektiv den Ertrag. Es handelt sich um die prozentuale Differenz zwischen dem aktuellen Auktionsbetrag und dem minimalen Auktionsbetrag. Wenn beispielsweise der RateBump-Wert 4_000_000 und auctionEndAmount (minimaler Ertrag) 500 beträgt, beträgt der aktuelle Auktionserlös 700.
totalFee ist eine Gebühr, die alle Resolver an die 1inch Foundation zahlen müssen (Wichtig: Derzeit wird diese Funktion nicht verwendet – Resolver zahlen keine Gebühren an die 1inch Foundation).
limitOrderProtocol ist eine Instanz des Protokolls, das im Abwicklungsvertrag über eine entsprechende Solidity-Schnittstelle deklariert wird. Es wird verwendet, um diesen Vertrag aus dem Abwicklungsvertrag aufzurufen.

Schritt 2
Der Abwicklungsvertrag ruft die Methode fillOrderTo() des Limit-Order-Vertrags auf und liefert die Daten einer von drei Bestellungen aus der Liste – sagen wir 100 DAI für mindestens 0,6 WETH:
Interaktion - hier wird die Information gegeben, dass sich noch 2 weitere Aufträge im Bulk befinden, die anschließend ausgeführt werden müssen.
Machende oder nehmende Beträge – buchstäblich wie viel zu zahlen oder wie viel zu bekommen ist. Nur einer dieser Beträge kann ungleich Null sein. Wenn Sie „makingAmount“ festlegen, geben Sie an, wie viel Sie als Resolver erhalten möchten. Alternativ bestimmen Sie durch Festlegen von „takingAmount“, wie viel Sie als Resolver verkaufen möchten. Einer wird auf Grundlage des anderen berechnet.
Ziel – die Adresse des Arbeitsvertrags, der die Quelltoken erhält.

Schritte 3-4
Der Limit-Order-Vertrag ruft den Quell-Token-Vertrag auf, um den Swap-Betrag unter Verwendung der ERC20-Solidity-Schnittstelle vom Benutzer an den Worker-Vertrag des Resolvers zu übertragen.
Ein Assembly-Teil, der für Menschen nicht sehr gut lesbar ist, bildet Calldata und ruft den Token-Vertrag auf. Die Assembly-Teile des Vertrags werden für Gaseffizienz und die Bereitstellung komplexer Daten erstellt.

Schritte 5-6
Der Limit-Order-Vertrag ruft den Abwicklungsvertrag mit einer Methode namens „fillOrderInteraction()“ zurück und sendet „interactiveData“, die Informationen zu weiteren Aufträgen im Batch enthalten (die zuvor in Interaktionen empfangenen Informationen). Auf der Abwicklungsseite dekodiert der Code „interactiveData“ und wandelt sie wieder in Interaktionen um.
Wenn der Stapel keine weiteren Bestellungen enthält (Szenario 1 unten), schließt er die Interaktion ab und ruft den Worker-Vertrag des Resolvers auf, um ihm „zu sagen“, dass er die Bestellungen auflösen soll. Dies ist möglich, weil der Worker-Vertrag unsere Schnittstelle namens IResolver importiert. In Solidity werden vertragsübergreifende Interaktionen normalerweise auf diese Weise durchgeführt. Was der Worker tut, werden wir in den Schritten 16–17 unten erläutern.
Wenn noch weitere Aufträge im Stapel verbleiben, ruft der Abwicklungsvertrag den Limit-Order-Vertrag erneut auf. Die beiden Verträge tauschen weiterhin Daten aus, bis alle Aufträge abgewickelt und alle Gelder von den Konten der Benutzer eingezogen wurden (in unserem Beispiel 100 DAI, 0,6 WETH und 0,01 WBTC).

Schritt 7
Wir sind fast fertig. Der Worker-Resolver-Vertrag hat alle Gelder von den Benutzern über die 1-Zoll-Abwicklungs- und Limit-Order-Verträge erhalten. Jetzt ist es an der Zeit, die Aufträge tatsächlich abzuwickeln!
Hier sind die Eigenschaften der Bestellungen:
Order 1: 100 DAI für mindestens 0,6 WETH
Order 2: 0,6 WETH für mindestens 100 DAI
Order 3: 0,01 WBTC für mindestens 36 UNI
Es sieht so aus, als könnten wir Auftrag 1 und Auftrag 2 buchstäblich ohne weitere Maßnahmen abgleichen. Wir senden also einfach 0,6 WETH, die wir vom Benutzer, der Auftrag 2 aufgegeben hat, gesammelt haben, an den Benutzer, der Auftrag 1 aufgegeben hat, und umgekehrt. Somit wurden Auftrag 2 von 3 mit den eigenen Mitteln der Benutzer abgewickelt.
Die letzte verbleibende Bestellung ist ein Tausch von 0,01 WBTC gegen 36 UNI. Der Worker-Vertrag hat keine UNI auf seinem Konto. Daher ruft der Worker-Vertrag den 1-Zoll-Aggregationsrouter-Vertrag auf dieselbe Weise auf, wie es jeder Benutzer bei einem Legacy-Tausch tut. Das Backend des Resolvers kann unsere Aggregations-API aufrufen, um eine optimale Route zu erhalten und diese zur Ausführung an den Worker weiterzuleiten. Der Router führt diesen Tausch aus und liefert 36 UNI an den Resolver.
In diesem vereinfachten Beispiel hat der Resolver nichts verdient, sondern Geld für Gas ausgegeben, um Daten zwischen Verträgen zu übertragen. Im wirklichen Leben würde das Backend des Resolvers, wie oben erwähnt, alle Ausgaben berücksichtigen und sicherstellen, dass die Trades für ihn profitabel sind und innerhalb des vom Quoter-Service bereitgestellten Rahmens bleiben. Der Resolver würde auch versuchen, den Swap für den Benutzer maximal profitabel zu machen.
Schritte 8-11
Nachdem der Worker-Resolver nun die Zieltoken hat, muss er auf den Rückruf reagieren und sie an den Abrechnungsvertrag übertragen. Aber Moment mal … Warum kann er die Token nicht direkt an den Benutzer senden?
Nein, das ist aufgrund der Art und Weise der Architekturimplementierung nicht möglich. Denken Sie daran, dass Schritt 5 dieses Ablaufs ein Rückruf an die Methode fillOrderTo() ist, die vom Abwicklungsvertrag für den Limit-Order-Vertrag aufgerufen wird. Die Funktion wird also immer noch ausgeführt!
Da der Anrufer der Abwicklungsvertrag war, wird er in dieser Konfiguration als Abnehmer der Bestellung betrachtet. Daher soll diese Instanz eine Antwort vom Resolver und die übertragenen Token erhalten. Anschließend erteilt sie dem Limit-Order-Vertrag ihre Zustimmung, der wiederum transferFrom() zum Ziel-Token-Vertrag aufruft und der Swap-Betrag landet schließlich im Wallet des Benutzers. Wir sind fertig!
Ein Etherscan-Beispiel aus dem echten Leben
Als letzte Übung betrachten wir einen realen Fall eines Fusion-Swaps: 1INCH zu DAI, aufgelöst durch den Seawise-Resolver, und seine ERC20-Token-Übertragungen. Für ein optimales Ergebnis müssen Sie das Bild unten mit dem Diagramm oben vergleichen und die Schritte abgleichen.

In Schritt 4 ruft der Limit-Order-Vertrag „transferFrom()“ für den 1-INCH-Token-Vertrag auf, um das Quell-Token von der Maker-Adresse (0x90…9044) an die Resolver-Adresse zu übertragen.
Die Schritte 5 und 6 werden in dieser Liste nicht aufgeführt, da sie keine ERC20-Token-Übertragungen beinhalten.
In Schritt 7 tauscht Seawise als Resolver 1INCH in DAI im Uniswap-Pool als Liquiditätsquelle.
In Schritt 8 überträgt Seawise DAI in den 1-Zoll-Abwicklungsvertrag.
Die Schritte 9 und 10 werden hier ebenfalls übersprungen, da es sich hierbei um interne Rückrufantworten zwischen den Verträgen des Resolvers und den 1-Zoll-Verträgen handelt.
Schließlich überträgt der 1-Zoll-Abwicklungsvertrag in Schritt 11 die Ziel-Token an den Hersteller.
Sehen Sie sich diese Transaktion gerne auf Etherscan an:
https://etherscan.io/tx/0x55e621337837f4f69f0c398ad5e9072a24811bbfd8cb2b208d621b940c9689b5
