DEFI - 标题 - Umaprotocol

该UMIP定义了Across V3的更新协议规范,是对Across V2规范的主要改进。Across V3增加了对新功能的支持,同时简化了现有协议。该协议更新旨在更好地支持跨链桥的意图驱动未来,包括支持用户和中继者之间具有强制执行力的限时协议,使Across可以作为第三方高效、模块化的跨链结算系统使用,并允许存款人在指定时间内未完成中继的情况下直接在原始链上获得退款。

标题

  • UMIP 179
  • 标题:更新 ACROSS-V2 价格识别器以支持 Across v3
  • 作者 paul@across.to
  • 状态:最后征求意见
  • 创建时间:2023-02-17
  • Discourse 链接:N/A

摘要

此 UMIP 定义了 Across V3 的更新协议规范。它弃用了现有 Across 协议规范的特定部分,如 UMIP-157 中所述。

动机

Across v3 是对 Across v2 规范的重大改进,在简化现有协议的同时增加了对新功能的支持。

基本原理

Across 协议提议更新其规范,以更好地支持跨链桥接的基于意图的未来。这包括:

  • 支持用户和中继者之间具有强制执行时限的协议,以执行意图。
  • 使 Across 能够被第三方用作高效、模块化的跨链结算系统。
  • 允许存款人在中继未在存款时指定的时间范围内完成的情况下,在原始链上直接获得退款。
  • 通过消除对链上发布桥接转移的 realizedLpFeePct 组件的需求,降低中继者的风险敞口。
  • 支持中继者独占性以减轻链上 Gas 拍卖。

需要更新 ACROSS-V2 价格标识符的规范,以便 UMA DVM 验证 Across v3 提议的结算包是否有效。

技术规范

概述

UMIP-157 中的以下部分明确保留供 Across v3 使用:

数据类型

Across v3 引入了以下新的数据类型:

V3RelayData

V3RelayData 类型支持资金流入或流出 SpokePool 实例的转移。V3RelayData 定义如下: 名称 类型 描述
depositor address 在原始链上进行存款的地址。
recipient address 目标链上的接收者地址。
exclusiveRelayer address 可选择的独家中继者,可在独占截止日期前填补存款。
inputToken address 存款人于原始链上存入的代币。
outputToken address 接收者于目标链上收到的代币。
inputAmount uint256 存款人存入的 inputToken 数量。
outputAmount uint256 接收者收到的 outputToken 数量。
originChainId uint256 原始 SpokePool 的链 ID。
depositId uint32 唯一标识原始链上存款的 ID。
fillDeadline uint32 目标链上的 Unix 时间戳,在此时间戳之后,存款将不再被填补。
exclusivityDeadline uint32 目标链上的可选 Unix 时间戳,在此时间戳之后,任何中继者都可以填补存款。
message bytes 作为中继的一部分转发给接收者的可选数据。

FillStatus

RelayData -> FillStatus 的映射存储在每个 SpokePool 实例中。可以使用存款的哈希 V3RelayData 查询此映射,从而允许查询相应填补的状态。

名称 数值 描述
Unfilled 0 SpokePool 没有相应 V3RelayData 哈希的已知状态。
RequestedSlowFill 1 已为此 V3RelayData 哈希发出 SlowFill 请求。先前已发出相应的 RequestedV3SlowFill 事件。
Filled 2 已完成此 V3RelayData 哈希的填补(快速或缓慢)。

FillType

FillType 实例与每个 FilledV3Relay 事件一起发出(见下文)。

名称 数值 描述
FastFill 0 中继由中继者作为快速填补完成。
ReplacedSlowFill 1 最初请求通过慢速填补完成中继,但随后被中继者快速填补。
SlowFill 2 中继通过慢速填补完成。

V3RelayExecutionEventInfo

V3RelayExecutionEventInfo 实例与每个 FilledV3Relay 事件一起发出(见下文)。

名称 类型 描述
updatedRecipient address 正在转移的资金的接收者。这可能是原始存款中标识的 recipient,也可能是 RequestedSpeedUpV3Deposit 事件之后的更新 recipient
updatedOutputAmount uint256 完成填补的中继者发送给 updatedRecipient 的金额。
updatedMessage bytes 作为中继的一部分转发给接收者的数据。
repaymentChainId uint256 存款人为填补还款指定的链。
fillType FillType 已完成的填补的类型(参见上面的 FillType)。

V3SlowFill

V3SlowFill 实例与每个 FilledV3Relay 事件一起发出(见下文)。

名称 类型 描述
relayData V3RelayData V3RelayData 实例,用于将 SlowFill 与 V3FundsDepositedRequestedV3SlowFill 事件唯一关联。
chainId uint256 完成 SlowFill 的 SpokePool 的链 ID。
updatedOutputAmount uint256 作为 SlowFill 的一部分发送给 recipient 的金额。这通常应等于或大于 V3FundsDeposited outputAmount
repaymentChainId uint256 存款人为填补还款指定的链。
fillType FillType 已完成的填补的类型。
备注

updatedRecipient 字段通常设置为来自相应 V3FundsDeposited 事件的 recipient。如果中继者完成填补时附带 RequestedSpeedUpV3Deposit 事件,则 updatedRecipient 将设置为更新批准的地址。

事件

Across V3 定义了以下新事件:

  • V3FundsDeposited
  • RequestedSpeedUpV3Deposit
  • RequestedV3SlowFill
  • FilledV3Relay

V3FundsDeposited

V3FundsDeposited 事件为单个存款发出唯一的 V3RelayData。未定义其他字段。此事件的使用者应附加 originChainId,以避免无意中混合来自不同链的事件。

注意:

  • V3FundsDeposited outputToken 不需要是已知的 HubPool l1Token。在协议中,Across v3 从技术上支持任意代币互换。

RequestedSpeedUpV3Deposit

RequestedSpeedUpV3Deposit 发出指定以下字段: 名称 类型 描述
depositId uint32 要更新的相应 V3FundsDeposited 事件的 depositId。
depositor address 要更新的相应 V3FundsDeposited 事件的存款人。
updatedOutputAmount uint256 存款人批准的新 outputAmount。这应低于原始存款 outputAmount
updatedRecipient address 接收资金的新接收者。
updatedMessage bytes 要提供给接收者的新消息。
depositorSignature bytes 存款人授权上述更新字段的签名。

注意:

  • 中继者可以选择在填补中继时附加来自 RequestedSpeedUpV3Deposit 的更新请求,但没有义务使用更新请求。
  • exclusiveRelayer 标识的地址有权在 exclusivityDeadline 经过之前在目标链上完成中继。
  • 如果 exclusivityDeadline 设置为过去的时间戳,则任何地址都有资格填补中继。
  • fillDeadline 经过后发生的任何尝试填补都应被目标 SpokePool 拒绝。相应的存款应通过相关结算包中的原始 SpokePool 退还。

RequestedV3SlowFill

RequestedV3SlowFill 事件发出 V3RelayData。此事件在目标链上发出,旨在向提案人发出已请求慢速填补的信号。

注意:

  • 在目标链上 exclusivityDeadline 时间戳经过之前,不会发生 RequestedV3SlowFill 事件。
  • 一旦目标链上 fillDeadline 时间戳经过,就无法发出 RequestedV3SlowFill 事件。

FilledV3Relay

FilledV3Relay 事件通过添加以下字段来扩展 V3RelayData 类型: 名称 类型 描述
relayer address 在目标 SpokePool 上完成中继的地址。
repaymentChainId uint256 要更新的相应 V3FundsDeposited 事件的 depositId。
relayExecutionInfo V3RelayExecutionInfo 有效的 recipientmessageoutputAmount,以及执行的 FillType(FastFill、ReplacedSlowFill、SlowFill)。

注意:

  • 此事件的使用者应附加 destinationChainId 属性,以避免无意中混合来自不同链的事件。

根包提案

要求

根包提案应包含以下内容: 名称 类型 描述
bundleEvaluationBlockNumbers uint256[] 表示每个相应 chainId 提案结束区块的有序区块号数组。
poolRebalanceLeafCount uint8 poolRebalanceRoot 表示的 PoolRebalanceLeaf 实例的数量。
poolRebalanceRoot bytes32 表示构成提案的 PoolRebalanceLeaf 对象有序数组的 Merkle 根。
relayerRefundRoot bytes32 表示构成提案的 RelayerRefundLeaf 对象有序数组的 Merkle 根。
slowRelayRoot bytes32 表示构成提案的 SlowFillLeaf 对象有序数组的 Merkle 根。

池再平衡叶

PoolRebalanceLeaf 应包含以下内容:

名称 类型 描述
chainId uint256 PoolRebalanceLeaf 引用的 SpokePool chainId
bundleLpFees uint256[] 相应 l1TokenbungleLpFee 值的有序数组。
netSendAmounts uint256[] 相应 l1TokennetSendAmount 值的有序数组。
runningBalances uint256[] 相应 l1TokenrunningBalance 值的有序数组。
groupIndex uint256 指示是否应将相应的 RelayerRefundSlowRelay 根中继到相应的 SpokePool。
leafId uint8 PoolRebalanceLeaves 有序数组中 PoolRebalanceLeaf 的索引。
l1Tokens address[] HubPool l1Token 地址的有序数组。

注意:

  • 池再平衡叶的格式与 Across v2 相比没有变化。

中继者退款叶

名称 类型 描述
chainId uint256 RelayerRebalanceLeaf 引用的 SpokePool chainId
leafId uint8 RelayerRefundLeaves 有序数组中 RelayerRefundLeaf 的索引。
l2TokenAddress address[] RelayerRefundLeaf 使用的 SpokePool 代币。
amountToReturn uint256 要返回给 HubPool 的 l2TokenAddress 数量。
refundAddresses uint256[] 要由此 RelayerRefundLeaf 退款的地址的有序数组。
refundAmounts uint256[] 要退款给相应 refundAddressl2TokenAddress 数量的有序数组。

注意:

  • 中继者退款叶的格式与 Across v2 相比没有变化。
  • Across v3 扩展了 RelayerRefundLeaf 的实用性,以包括在 V3FundsDeposited fillDeadline 过期的情况下在原始链上发放存款人退款。

慢速中继叶

Across v3 SlowRelayLeaf 对象由 V3SlowFill 数据类型 定义。

注意:

  • 慢速中继叶的格式已从 Across v2 更新。

方法

标识 SpokePool 合约

可以通过查询 HubPool.crossChainContracts() 获得特定链的当前 SpokePool 地址。必须在查询中指定 chainId。如果发生 SpokePool 迁移,可以通过抓取 HubPool CrossChainContractsSet 事件来识别历史 SpokePool 地址。

将 SpokePool 代币解析为其 HubPool 等价物

为了在给定 SpokePool 代币的情况下识别等效的 HubPool 代币,应遵循以下步骤:

  1. 查找最新的 SetRebalanceRoute 事件,该事件的区块时间戳等于或早于相关的 HubPool 区块号,其中相关的 SpokePool 链 ID 和代币地址与 SetRebalanceRoute destinationChainIddestinationToken 字段匹配。
    • V3FundsDeposited 事件的情况下,通过将 quoteTimestamp 解析为 HubPool 区块号来识别相关的 HubPool 区块号。
  2. 从生成的 SetRebalanceRoute 事件中,选择关联的 l1Token 字段。
  3. SetPoolRebalanceRoute 事件中搜索相同 l1TokendestinationChainId,其时间等于或早于适用的 HubPool 区块号。
  4. 使用在步骤 2 中找到的 l1Token 值,搜索最新的 SetRebalanceRoute 事件,其时间等于或早于适用的 HubPool 区块号,其中 l1TokendestinationChainId 与提取的 l1Token 和 SpokePool 链 ID 匹配。如果找到匹配项,则地址匹配并被视为跨链等价物。

识别包区块范围

除了 UMIP-157 中的描述:

  • 如果检测到 RPC 提供程序数据不一致,提案人可以选择减少每个链的提案区块范围的大小,并且
  • 如果提案人无法安全地增加包区块范围,或者没有要提议的超出先前包区块范围的事件,则允许“软暂停”链。在这种情况下,提案人可以重复执行程序 DISABLED_CHAINS 通过从和到先前的包结束区块进行提议。

查找有效中继

为了计算中继者还款,应通过验证以下内容来认为在目标 SpokePool 上目标区块范围内发出的每个 FilledV3Relay 事件都有效:

  1. FilledV3Relay FillType 字段未设置为 SlowFill
  2. 组件 V3RelayData 准确映射到在相关 originChainId 上发出的相应 V3FundsDeposited 事件。这可以通过比较两个对象的哈希值来比较。

如果 V3FundsDeposited 事件指定 outputToken 0x0(即零地址),则应替换目标链上等效的 SpokePool 代币。为了确定 V3RelayData 的等效性,应使用更新/替换的 outputToken 代替 0x0。

查找过期存款

为了计算存款人退款,应通过验证以下内容来认为每个 V3FundsDeposited 事件都已过期:

  1. fillDeadline 时间戳在目标 SpokePool 上的目标区块范围内经过(即,fillDeadline 在目标链的包开始和结束区块的 block.timestamp 之间过期),
  2. 目标 SpokePool 上的 FillStatus 设置为 UnfilledSlowFillRequested

注意:

  • 过期存款应退还给原始 SpokePool 上的 depositor 地址。
  • 存款人退款应作为中继者退款程序的一部分发放。
  • fillDeadline 时间戳应解析为目标链上的区块号,以便确定其是否包含在目标区块范围内。

查找慢速填补请求

为了计算要发放给接收者的慢速填补,应通过验证以下内容来认为在目标 SpokePool 上目标区块范围内发出的每个 RequestedV3SlowFill 事件都有效:

  1. inputTokenoutputToken 地址在存款 quoteTimestamp 处等效,
  2. 相对于 destinationChainId 包结束区块号,fillDeadline 尚未经过,
  3. 相关 V3RelayData 哈希的目标 SpokePool FillStatus 映射为 SlowFillRequested
  4. RequestedV3SlowFill V3RelayData 与原始 SpokePool 上的相应 V3FundsDeposited 事件匹配,

注意:

  • 通过提供 V3FundsDeposited 事件发出的相关 V3RelayData 的完整副本来发出慢速填补请求。
  • 验证后的 RequestedV3SlowFill 事件的结果集应作为 SlowFills 包含在后续的根包提案中。

计算 LP 费用

每个有效的 FilledV3Relay 事件都需支付 LP 费用。计算 LP 费用的程序如 UMIP-136 添加 IS_RELAY_VALID 作为支持的价格标识符 中定义,但有以下修改:

  • 应使用 AcrossConfigStore 合约来标识正确的费率模型,而不是 RateModelStore 合约。
  • 应使用 HubPool liquidityUtilizationCurrent()liquidityUtilizationPostRelay() 函数,而不是 BridgePool 变体。
  • 应通过遵循上面概述的匹配程序,将事件 inputToken 从 SpokePool 地址映射到 HubPool l1Token 地址。
  • LP 费用在 originChainIdFilledV3Relay.repaymentChainId 之间计算,其中 relayExecutionInfo.FillType != SlowFill,否则计算 FilledV3Relay.destinationChainId

注意:

  • LP 费用通常被称为 V3FundsDeposited inputAmount 的倍数,在本文档的其他地方称为 realizedLpFeePct

计算包 LP 费用

SpokePool 和代币对的目标区块范围的包 LP 费用应通过对每个验证过的事件的适用 LP 费用求和来确定:

  • FilledV3Relay

计算中继者还款

对于验证过的 FilledV3Relay 事件,中继者还款金额应按如下方式计算:

  • (inputAmount * (1 - realizedLpFeePct)) / 1e18,其中 realizedLpFeePct 在 HubPool 区块号处,在 HubPool l1TokenoriginChainIdrepaymentChainId 集上计算,该区块号对应于相关的 V3FundsDeposited quoteTimestamp
  • 适用的费率模型应从 AcrossConfigStore 合约中获取,用于相关的 l1Token

计算存款退款

对于过期的 V3FundsDeposited 事件,存款人退款金额应计算为 inputAmount 单位的 inputToken

计算慢速填补更新的输出金额

为了计算要为 SlowFill 发放给接收者的金额,应通过应用以下程序将中继者费用清零:

  • updatedOutputAmount = (inputAmount * (1 - realizedLpFeePct)) / 1e18,其中 realizedLpFeePctoriginChainIddestinationChainId 之间的存款 quoteTimestamp 处计算。

约束:

  • 在确定 SlowFill 金额时,不应考虑 V3FundsDeposited outputAmount

注意:

  • V3FundsDeposited outputAmount 指定了标准填补的 recipient 要收到的确切金额,因此不包括任何已支付的中继者或 LP 费用。

查找开始运行余额

开始运行余额定义为截至先前成功(未争议)根包提案的累计运行余额。

每个唯一的 l1TokenrepaymentChainId 对的开始运行余额应按如下方式确定:

  1. 搜索先前的 RootBundleExecuted 事件,其中:
    1. RootBundleExecuted chainIdrepaymentChainId 匹配,并且
    2. l1Token 地址出现在 l1Tokens 数组中。
  2. 对于先前的事件,识别 l1Tokens 数组中 l1Token 的索引,并在 runningBalances 数组中查找相应的索引。
  3. 如果未识别出先前的 runningBalance,则开始运行余额应默认为 0。

计算运行余额和净发送金额

计算 l1TokenchainId 对的运行余额的程序应实施以下步骤:

  1. 将运行余额初始化为 0。

  2. 添加中继者退款:

    • 对于每组验证过的 FilledV3Relay 事件,将运行余额初始化为 0 并添加中继者还款。
  3. 添加存款退款:

    • 对于在目标区块范围内过期的每组 V3FundsDeposited 事件,对原始链上的存款退款总额求和。将该金额添加到该链的现有中继者退款中。
  4. 添加慢速填补:

    • 对于每组验证过的 RequestedV3SlowFill 事件,将每个慢速中继的 updatedOutputAmount 添加到该组的运行余额。
  5. 从未执行的慢速填补中减去过量:

    • 对于每组验证过的 FilledV3Relay 事件,其中 FillTypeReplacedSlowFill 并且当前包数据中没有具有相同中继数据哈希的有效 RequestedV3SlowFill 事件,从运行余额中减去 SlowFill updatedOutputAmount,因为该填补金额已转移,所以慢速填补将永远不会执行。
    • 对于上面标识的每个过期存款退款,其中存款中继数据的存款目标链上的 FillStatusRequestedSlowFill 且匹配的慢速填补请求不在当前包范围内,从运行余额中减去关联的 SlowFill updatedOutputAmount,因为超过 fillDeadline 后无法执行慢速填补。
  6. 添加所选 l1TokenchainId 对的开始运行余额。

  7. 根据 Computing Net Send Amounts 的结果,为每个 l1TokenchainId 对设置净发送金额并更新运行余额,如以下算法所述:

    
    spoke_balance_threshold = 此代币的 `spokeTargetBalances` 中的“threshold”值
    spoke_balance_target = 此代币的 `spokeTargetBalances` 中的“target”值

net_send_amount = 0

如果运行余额为正,则 Hub 欠 Spoke 资金。

if running_balance > 0: net_send_amount = running_balance running_balance = 0

如果运行余额为负,则从 Spoke 提取足够的资金到 Hub,以将运行余额返回到其目标

else if abs(running_balance) >= spoke_balance_threshold: net_send_amount = min(running_balance + spoke_balance_target, 0) running_balance = running_balance - net_send_amount



注意:
引用的 `SpokeTargetBalances` 如 [UMIP-157 代币常量](https://github.com/UMAprotocol/UMIPs/blob/pxrl/umip179/UMIPs/umip-157.md#token-constants) 中指定:

### 构建根包

#### 构建池再平衡根
每个唯一的 `chainId` 和 `l1Token` 对产生一个池再平衡叶,其中相应的 SpokePool 在目标区块范围内发出 `V3FundsDeposited`、`FilledV3Relay` 或 `RequestedV3SlowFill` 事件。

每个池再平衡叶应按如下方式构建:
1. 对于每个唯一的 `chainId` 和 `l1Token` 对:
    1. 根据上面概述的程序计算数组 `runningBalances`、`netSendAmounts` 和 `bundleLpFees`。
    2. 将 `groupIndex` 设置为 0。
2. 在每个池再平衡叶实例中,数组 `l1Tokens`、`runningBalances`、`netSendAmounts` 和 `bundleLpFees` 应:
    1 按 `l1Token` 排序,并且
    2 具有相同(非零长度。

如果单个池再平衡叶中包含的 `l1Token` 条目的数量超过 [`MAX_POOL_REBALANCE_LEAF_SIZE`](https://github.com/UMAprotocol/UMIPs/blob/7b1a046098d3e2583abd0372c5e9c6003b46ad92/UMIPs/umip-157.md#global-constants):
1. 应生成额外的池再平衡叶实例以容纳过量。
2. 应在叶的有序数组中维护 `l1Tokens`、`bundleLpFees`、`runningBalance` 和 `neSendAmounts` 的排序。
3. 应为每个后续叶递增 `groupIndex`。

池再平衡叶对象集应按以下顺序排序:
1、`chainId`,然后
2、`l1Tokens`。

应设置池再平衡叶 `leafId` 以指示其在有序数组中的位置,从 0 开始。

每个池再平衡叶的哈希应通过使用 Solidity 的标准流程 `keccak256(abi.encode(poolRebalanceLeaf))` 构建。

应构建池再平衡 Merkle 树,使其可以使用 [OpenZeppelin 的 MerkleProof](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/742e85be7c08dff21410ba4aa9c60f6a033befb8/contracts/utils/cryptography/MerkleProof.sol) 库进行验证。

注意:
- 有关如何构建这些类型的树的示例,请参见[此处](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/742e85be7c08dff21410ba4aa9c60f6a033befb8/test/utils/cryptography/MerkleProof.test.js)。

#### 构建中继者退款根
对于 SpokePool 和 `l1Token` 的每个唯一组合,应至少生成一个中继者退款叶满足以下任何条件:
- 有效的 `FilledV3Relay` 事件,或者
- 过期的 `V3Fundsdeposited` 事件,或者
- 负的运行余额净发送金额。

每个中继者退款叶应按如下方式构建:
- `amountToReturn` 应设置为 `max(-netSendAmount, 0)`。
- `l2TokenAddress` 应设置为在池再平衡根生成中考虑的相应 `l1Token` 的 L2 代币地址。
    - HubPool 和 SpokePool 代币映射应根据组中任何中继的最高 `quoteTimestamp` 进行。
    - 如果不存在中继,则应使用来自先前成功提案的相关代币映射。
- 应根据用于计算中继者还款的已定义程序生成 `refundAddresses` 和 `refundAmounts` 数组的每个元素。
    - 每个唯一地址应存在一个条目,其中包含任何未偿还的总和:
        - 中继者还款,和/或
        - 过期存款。
- `refundAddresses` 和 `refundAmounts` 数组应根据以下条件排序:
    1. `refundAmount` 降序,然后
    2. `relayerAddress` 升序(如果 `refundAmount` 值重复)。

如果中继者退款叶中包含的退款数量超过 [`MAX_RELAYER_REPAYMENT_LEAF_SIZE`]((https://github.com/UMAprotocol/UMIPs/blob/7b1a046098d3e2583abd0372c5e9c6003b46ad92/UMIPs/umip-157.md#global-constants) 退款:
1. 应生成额外的 `RelayerRefundLeaf` 实例以容纳过量。
2. 应在叶的有序数组中维护 `refundAddresses` 和 `refundAmounts` 的排序。
3. 对于给定的 `l2TokenAddress`,只有第一个叶应包含非零 `amountToReturn`。

中继者退款叶集应根据以下条件排序:
- chainId,然后
- `l2TokenAddress`,然后
- 叶子子索引(在 > [`MAX_RELAYER_REPAYMENT_LEAF_SIZE`](#global-constants) 还款的情况下)。

应根据上面建立的排序规则对中继者退款叶 `leafId` 字段进行编号,从 0 开始。

注意:
- 一旦构建了这些叶,它们就可以用于形成 Merkle 根,如上一节所述。

#### 构建慢速中继根
对于在目标 SpokePool 的目标区块范围内发出的每个有效的 `RequestedV3SlowRelay` 事件,应生成一个慢速中继叶。

每个慢速中继叶应按如下方式构建:
1. 将 `relayData` 设置为经过验证的 `RequestedV3SlowFill` 事件发出的 `V3RelayData` 数据。
2. 将 `chainId` 设置为来自相应验证过的 `RequestedV3SlowFill` 事件的 `destinationChainId`。
3. 将 `updatedOutputAmount` 设置为为 SlowFill 计算的更新数量。

慢速中继叶实例数组应根据以下条件排序:
1、`originChainId`,然后
2、`depositId`。

注意:
- 一旦构建了这些叶,它们就可以用于形成 Merkle 根,如上一节所述。
- 具有不同输出代币的存款(即,其中 outputToken 不是目标链上 inputToken 的等效项的存款)明确不符合慢速填补的条件。对于非等效代币的任何 `RequestedV3SlowFill` 事件实例都应忽略。

## 建议
- 提案人负责检测和减轻不正确或不一致的 RPC 数据。提案人应采取步骤在提案之前验证其 RPC 数据的正确性。
- 提案人应避免依赖存款 `outputAmount`,即使对于 `outputToken` 是已知 HubPool 代币的存款也是如此。在计算费用时,请确保 `realizedLpFee` **始终**从 `inputAmount` 中扣除,而不是尝试根据 `inputAmount` 和 `outputAmount` 之间的差额来推断它们。
- 建议中继者在目标链上进行填补时考虑原始链最终性保证。原始链重组可能会导致存款重新排序,从而使填补无效。

## Across v2 -> V3 过渡
Across v3 是 Across v2 的补充,增加了额外的逻辑支持新型存款、填补和慢速填补请求。在升级到 Across v3 时,将不再可能发出 Across v2 `FundsDeposited` 事件。为了支持服务的连续性并最大限度地减少第三方集成商的中断,可以通过 `FilledRelay` 事件来填充预先存在的 `FundsDeposited` 事件。在此期间,RootBundleProposals 将包含 Across v2 和 v3 的中继者还款和慢速填补叶。

当 ConfigStore 中的 VERSION 字段更新为 3 或更高时,本 UMIP 中定义的 V3 规则将适用。Across 包支持 V2 事件的能力可能会在未来的 VERSION 增量中停止。

## 实施
Across v3 实施可在 Across [contracts-v2](https://github.com/across-protocol/contracts-v2) 存储库中找到。

## 安全注意事项
Across v3 已通过 OpenZeppelin 审核。

注意:
- 如果已知特定的中继者退款无法执行,则提案人可以在提案之前做出充分的公开理由的情况下从包中删除它。这旨在处理不太可能发生的情况,例如中心化代币发行者将某个地址列入黑名单,该地址应获得退款。如果此叶保持不变,此列入黑名单的地址可能会阻止其他地址接收退款。

>- 原文链接: [github.com/UMAprotocol/U...](https://github.com/UMAprotocol/UMIPs/blob/pxrl/umip179/UMIPs/umip-179.md)
>- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
UMAprotocol
UMAprotocol
江湖只有他的大名,没有他的介绍。