该文档是对 UMAprotocol 中 Oracle 相关合约升级的审计报告,主要关注 Oracle 请求中辅助数据的压缩,以降低 Gas 消耗。
TypeDeFiTimeline自 2025-04-03至 2025-04-04语言SolidityTS/JSTotal Issues4 (4 已解决)严重风险问题0 (0 已解决)高风险问题0 (0 已解决)中风险问题0 (0 已解决)低风险问题1 (1 已解决)注释 & 补充信息3 (3 已解决)客户报告问题0 (0 已解决)
我们审核了 UMAprotocol/protocol
仓库的 Pull Request #4816。范围包括 OracleBaseTunnel
(OracleRootTunnel
继承自它)、OracleChildTunnel
和 OracleSpoke
的 Solidity 合约更改,packages/scripts/src/admin-proposals
中的脚本,以及 packages/core/test/hardhat
中的测试更改。
此外,我们还审核了提案 (UMIP-185) 中概述的计划,该计划旨在用于在 Ethereum、Polygon、Optimism、Arbitrum、Base 和 Blast 网络上执行升级。
在处理以太坊主网以外的链上的 Oracle 请求时,额外的辅助数据会附加到桥接数据中。 这些数据旨在由链下组件解析并转发到以太坊主网。 提议的更改包括在桥接到以太坊主网时压缩 Oracle 请求的辅助数据,方法是仅发送数据的哈希以及元数据( childBlockNumber
,childOracle
,childRequester
,childChainId
),如提案中所述。 这旨在降低链下组件和用户(投票者)的 gas 成本。 升级涉及部署新版本的 OracleRootTunnel
、OracleChildTunnel
和 OracleSpoke
合约,并通过治理更新相关的系统参数。
新的请求 ID 使用 requester
地址计算。 同样,hasPrice
和 getPrice
使用 msg.sender
作为 requester
来检索价格。 因此,如果将来升级 OptimisticOracleV2
实现,则新的合约实例将无法访问通过先前实现提交的价格。
由于此问题仅在替换 OptimisticOracleV2
合约时发生,请考虑是否可能出现这种情况,以及是否需要在 OracleSpoke
或 OracleChildTunnel
中进行更改。
更新: 通过从子请求 ID 派生中删除 requester
,在 pull request #4816 的 commit 3b1a2b4 中已解决。 团队声明:
在我们看来,唯一的理论上的缺点是,有人可以通过从 OOv1 请求/提议/争议相同的 id/time/辅助数据来抢先 OOv2 争议,这将使 DVM 投票者难以弄清楚请求的真实来源。 但是,有人可能会争辩说这不是绝对必要的,因为答案不应取决于谁在提问。 并且这种攻击在实践中是不可能的,因为我们的 OO 实现附加了
ooRequester
字段,因此你无法欺骗辅助数据。 因此,我们选择通过使用相同的继承的_encodePriceRequest
方法来简化操作,并可能使其更容易处理未来的 OO 升级。
可以更新一些注释以提高清晰度:
“its” 可以更改为 “it is” here。
“ancillary data” 可以更改为 “compressed ancillary data” here,因为 parentRequestId
是 根据压缩数据计算的。
更新: 在同一 pull request 的 commit 8e05fe6 中已解决。
OracleSpoke
合约的 resolveLegacyRequest
函数 允许为任何 childRequester
设置价格,只要旧版请求已解决。 因此,ResolvedLegacyRequest
事件可能会多次发出。 也可以通过这种方式设置新的价格条目,但它们由 keccak256
哈希索引,从而避免了潜在的冲突。
考虑重复的事件广播对链下组件是否可能存在问题。
更新: 已解决。 团队声明:
先前的
OracleSpoke
未在其盖时间戳的辅助数据中包含 requester,因此我们无法将resolveLegacyRequest
限制为任何单个 requester。 只能可能硬编码已知的 requester 地址并检查它们,但即使这样仍然可能发出多个ResolvedLegacyRequest
事件。 但是,这不应影响 OO 的功能,因为此事件的主要原因是检查特定的旧版子请求是否已解析为新格式。 链下可以为已知的有效 requester 重新计算priceRequestId
并相应地过滤事件。
验证脚本 缺少对在执行升级后是否未保留 CONTRACT_CREATOR
角色 的检查。
考虑添加一个验证步骤,以确保不保留任何不必要的角色。
更新: 在 commit e452d64 中已解决。
考虑在 fork 环境中运行 DAO 提案模拟,并在升级后评估状态的正确性。
更新: 模拟在 fork 环境中升级的脚本已包含在内,以及验证。
目前,唯一可用于 Oracle 请求和解析的端到端测试是为 Polygon 网络执行的测试。 但是,不存在 rollup 链的相应端到端测试。 即使现有的单元测试广泛覆盖了代码库,我们建议也添加端到端测试,以提高跨链机制的覆盖率、配置验证以及新更改的回归测试。
更新: 团队声明:
我们感谢该建议,并将为利用中心辐射型机制的 rollup 网络的 Oracle 请求/解析流程创建端到端测试。
审核的 pull request 和提案介绍了压缩 Oracle 请求中辅助数据的更改,旨在减少 gas 消耗。 仅发现了一些小问题,所有问题都已解决。 审核了 DAO 提案,并确认其包含 UMIP 中概述的所有必要步骤,以使用新的合约实现升级所需的组件。
- 原文链接: blog.openzeppelin.com/um...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!