1inch Fusion

Fusion 掉期解析器:链上组件

这篇文章将重点介绍掉期解析器的链上部分。

让我们继续上次的话题。我们正处于掉期解析过程中的一个阶段,即解析器的后端 "决定 "在某个区块内,用一定数量的掉期资产来填补它从 1inch 中继器服务接收到的 Fusion 订单,并将其返还给用户。现在,我们来看看掉期解决过程的链上部分。但首先,我们要介绍一下这个过程的参与者。

Fusion 掉期执行的链上部分涉及以下区块链实体之间相当复杂的互动:

一个非常重要的注意事项:虽然并非总是如此,在某些情况下,解析器会在一个批次中进行多次填充,最多可达 32 次。通常情况下,解析器的Worker合约中有多个加密货币余额,后端可以从中继器提供的 "Stream" 中获取多个订单,并进行一系列填充。

接下来我们将讨论以下场景。

解析器从中继器中选择了 3 个可能有利可图的订单来填充:

100 DAI 换取至少 0.6 WETH

0.6 WETH 换取至少 100 DAI 

0.01 WBTC 换取至少 36 UNI 

解析器的目标是以用户至少获得他们期望的金额的方式执行所有 3 次掉期交易。我们将忽略解析器可能采取的盈利策略并简化计算,以便您能够理解总体思路。

现在,后端向Worker合约提供有关所选订单的信息。 接下来发生什么?

注:本图表是Swap解析器的链下组件部分文章中图表的延续。但为了便于理解,我们从步骤 1 开始。

步骤 1

Worker合约(或钱包)调用 1inch 结算合约的 settleOrders() 方法,以轻量级字节压缩格式提供订单信息;calldata 和 tokensAndAmounts 参数用于存储这些信息。

在这里,您可能会注意到一些有趣的细节:

  • rateBump 来自报价者,实际上决定了收益。它是当前出价金额与最小出价金额之间的百分比差。例如,如果 rateBump 值为 4_000_000,而 auctionEndAmount(最小收益)为 500,则当前出价金额为 700。
  • TotalFee 是所有解析器必须向 1inch 基金会支付的费用(重要提示:目前尚未启动此功能 - 解析器不会向 1inch 基金会支付任何费用)。
  • limitOrderProtocol 是通过相应的 Solidity 接口在结算合约中声明的协议实例,它用于从结算合约中调用该合约。

步骤 2

结算合约调用限价订单合约的 fillOrderTo() 方法,提供列表中 3 个订单之一的数据 - 比如说,100 DAI 换取至少 0.6 WETH:

  • Interaction - 其中包含批量订单中还有 2 个订单需要随后执行的信息。
  • Making or taking amounts - 即支付多少或获取多少。这些金额中只有一个可以是非零的。如果设置了 makingAmount,则指定您希望作为解析器收到的金额。或者,通过设置 takingAmount,您可以确定作为解析器出售的金额。其中一个将根据另一个进行计算。
  • Target - 将接收源加密货币的 Worker 合约的地址。

步骤3-4

限价单合约使用 ERC20 Solidity 接口调用源加密货币合约,将掉期交易金额从用户转移到解析器的 Worker 合约。

一个不太容易读取的汇编部分会形成 calldata 并调用加密货币合约。 该合约的配置是为了提高gas效率和传递复杂数据而创建的。

步骤 5-6

限价订单合约使用名为 fillOrderInteraction() 的方法回调结算合约,并发送包含批次中其他订单信息的 interactiveData(之前在交互中收到的信息)。在结算端,代码对 InteractiveData 进行解码,将其转换回 Interaction。

如果该批次中没有更多订单(以下第 1 种情况),它将最终完成 Interaction,并调用解析器的 Worker 合同,"告诉 "它解析这些订单。之所以能做到这一点,是因为 Worker 合同将导入我们名为 IResolver 的接口。在 Solidity 中,跨合约交互通常是以这种方式完成的。我们将在下文的步骤 16-17 介绍 Worker 的工作。

如果该批次中仍有其他订单,结算合约将再次调用限价订单合约。这两个合约将继续交换数据,直到所有订单都已结算,所有资金都已从用户账户中收回(在我们的示例中为 100 DAI、0.6 WETH 和 0.01 WBTC)。

步骤 7

现在已经基本完成了。Worker 解析器合约已通过 1inch 结算,限价订单合约收到了用户的所有资金。现在,是时候真正解析订单了!

以下是订单的属性:

订单 1:100 DAI 换取至少 0.6 WETH

订单 2:0.6 WETH 换取至少 100 DAI

订单 3:0.01 WBTC 换取至少 36 UNI

看上去我们无需采取任何额外行动,就能完全匹配订单 1 和订单 2。因此,我们只需安全地将从提交订单 2 的用户处收集的 0.6 WETH 发送给提交订单 1 的用户,反之亦然。这样,订3 个订单中的第 2 个订单已使用用户自有资金解决。

剩下的最后一个订单是用 0.01 WBTC 换取 36 UNI。Worker 合约的余额中没有任何 UNI。因此,Worker合约调用 1inch 聚合路由器合约的方式与任何用户在传统掉期交易中调用的方式相同。解析器的后端可以调用我们的聚合 API 来获取最佳路由,并将其传递给工作线程执行。路由执行此掉期交易,并将 36 个 UNI 传递给解析器。

在这个简化的示例中,解析器没有赚取任何收益,只是花费资金在gas上以在合约之间传输数据。在现实生活中,如上所述,解析器的后端会考虑到所有费用,确保交易对他们有利可图,并让交易保持在提供的框架内。解析器还将努力使用户在掉期交易中获得最大利润。

步骤 8-11

现在,当 Worker 解析器获得目标加密货币后,它们必须响应回调,并将加密货币转移到结算合约中。但是等等......为什么不能直接将加密货币发送给用户呢?

是的,由于架构的实现方式,他们不能这样做。请记住,该流程的第 5 步是结算合约向限价订单合约调用 fillOrderTo() 方法的回调。因此,该函数仍在执行中!

由于调用者是结算合约,在此配置中,它被视为订单的接受者。因此,该实例应该收到来自解析器的响应和转移的加密货币。然后,它会向限价订单合约提供批准,而限价订单合约又会向目标加密货币合约调用 transferFrom(),最终交换的金额就会进入用户的钱包。我们就大功告成了!

一个真实的 Etherscan 案例

作为最后一项练习,让我们回顾一下 Fusion 掉期交易的真实案例: 1INCH 到 DAI,由 Seawise 解析器解析,及其 ERC20 加密货币转账。为获得最佳体验,您需要将下图与上图对照,并匹配步骤。

步骤 4,限价订单合约调用 1INCH 加密货币合约上的 transferFrom() 将源加密货币从 Maker 地址(0x90...9044)转移到解析器地址。

步骤 5 和 6 没有反映在此列表中,因为它们不涉及任何 ERC20 加密货币的转移。

步骤 7,Seawise 作为解析器将 1INCH 交换到 Uniswap 池中的 DAI 作为流动性来源。

步骤 8,Seawise 将 DAI 转入 1inch 结算合约。

这里也跳过步骤 9 和 10,因为这两个步骤是解析器和 1inch 合约之间的内部回调响应。

最后,步骤 11,1inch 结算合约将目标加密货币转给 Maker。

欢迎在 Etherscan 上查看此交易

分享这篇文章

Copy icon Copy done!
top-bg top-bg-mobile