2022 年 1 月 7 日
介绍
UMA 是一个允许用户在以太坊区块链上输入信任最小化的金融合约的平台。我们之前审核过 去中心化的预言机, 特定的金融合同模板, 一些临时拉取请求, 永久多方模板, 长期参与期间的各种增量拉取请求 和 受保桥梁.
在本次审计中,我们审查了新的治理提案合约、跨多个链扩展 UMA 生态系统的机制、根据链下规范向 ERC721 代币持有者分配奖励的机制,以及对保险桥的更新以支持 WETH在乐观链上。
审计的提交是 0c4cea3c3d5e48da6f8984b8ba3afdfea4ce47cc
范围包括以下合同:
oracle/implementation/Proposer.sol
cross-chain-oracle/*
(不包括测试合约和 Polygon 合约)financial-templates/optimistic-rewarder/*
(不包括测试合同)
我们还审查了对 Solidity 文件的更改 请求请求 3611.
假定所有外部代码和合同依赖项均按文档记录工作。
系统总览
目前的 Governance
合约允许风险实验室基金会提出可由 UMA 代币持有者批准的新治理行动。新的 Proposer
合约旨在扮演提议者的角色,允许任何人提出新的提议,只要他们提供保证金,如果提议失败,保证金将被牺牲。提出提案没有具体的激励措施。目的是确保只提出很可能被接受的行动。
新的跨链机制允许治理提案从以太坊主网传递到 Optimism 和 Arbitrum 链。这样,第一层的 UMA 治理机制就可以用来治理所支持的第二层链上的 UMA 合约。该机制还允许价格请求和决议在各层之间转发,因此第 1 层链上的乐观预言机可以通过主网数据验证机制来保护,就像第 2 层乐观预言机由 DVM 保护一样。
值得注意的是,这些消息是使用本机桥接机制发送的,这意味着它们受到相关第 2 层链的特性的限制。特别是,从第 2 层到第 1 层的消息可能需要一周或更长时间才能通过网桥。此外,UMA 治理机制支持包含多个有序交易的提案,但这仅仅限制了它们添加到桥中的顺序。其中一些事务可能在第 2 层以不同的顺序执行,或者根本不执行。
乐观奖励者合约只是为任何请求的人铸造 ERC721 代币。它还允许任何人将任意数据与任何代币关联起来,并存入各种 ERC20 代币作为奖励进行分发。任意数据的解释和代币持有者之间的预期奖励分配是使用未指定的链下程序确定的。任何人都可以声称,如果愿意存入债券,特定的 ERC721 代币将获得一系列奖励。标准的乐观预言机机制用于允许其他人对声明提出异议,这将由 DVM 解决。未及时提出争议的索赔被视为有效,合约将相应分配奖励。唯一的限制(为了简化会计)是预言机债券代币不能用作奖励代币。
最后,PR3611 修改了保险桥机制,以避免通过不支持的 Optimism 代币桥发送 WETH。相反,任何存入 Optimism 存款箱中的 L2 WETH 在通过桥之前都会被解包为 L2 ETH。在第 1 层,ETH 在转发到 WETH 桥池之前先转换为 WETH。
严重程度
[C01] 无法对无效奖励提出异议
当对奖励请求有争议时, OptimisticRewardBase
合同第一 触发提案 在 SkinnyOptimisticOracle
然后 对该提案提出异议。然而,该提案 设置过期时间 作为当前(争议)时间的偏移量,而争议 指定过期时间 作为原始奖励请求时间的偏移。在大多数情况下,这种差异将阻止预言机识别有争议的提案,这意味着有效的争议将不会被处理,无效的奖励请求将被接受。
考虑更新争议调用以正确指定要争议的提案。
[C02]反复解决提案
resolveProposal
的功能 Proposer
合同 只是验证 预言机已解决,但不检查债券是否已分配。这意味着同一个提案可以多次解决,从而导致重复的债券支付。解决现有提案后,请考虑标记或删除现有提案。
高严重性
没有。
中等严重程度
[M01]事件参数不正确
OptimisticRewarderBase
合同定义了一个 Requested
活动 这是从发射 requestRedemption
请求赎回时起作用。该事件被定义为发出 赎回到期时间 作为其最后一个参数。然而, 当事件被发出时,它的最后一个参数被错误地设置为 当前时间.
同样 Redeemed
活动 删除记录后读取过期时间,因此会错误地将其设置为零。
鉴于此事件可用于触发链外计算,请考虑适当更新发出的值。
严重程度低
[L01] 争议兑换后缺乏事件发射
OptimisticRewarderBase
合同定义了一个 Disputed
活动 如果赎回有争议,则会触发该事件。但是,该事件不会在内部或外部发出 OptimisticRewarderBase
合同。
考虑在发生敏感更改后发出事件 dispute
功能,以便于跟踪并通知链下客户跟踪合约活动。
[L02] 不一致的重入防护
Optimism_ParentMessenger
和 Arbitrum_ParentMessenger
合同不一致地适用 nonReentrant
修饰符。考虑将其纳入所有公共职能中。
[L03]误导性评论
以下是我们在审核过程中发现的一些误导性评论:
ChildMessengerConsumerInterface.sol
:- 线5 说“父信使”而不是“子信使”
GovernorSpoke.sol
:- 49-51行 链接到一个
Gnosis
文件,即使评论说该片段是从复制的Governor.sol
。此外,该片段与中的片段并不相同Governor.sol
- 49-51行 链接到一个
[L04] 缺少辅助数据标记
当询问价格时 OracleSpoke
合同、提供的辅助数据 被盖章 与子链标识符。但是,那 hasPrice
和 getPrice
函数在识别价格请求时不会标记辅助数据。这迫使调用合约自己应用标记,从而导致价格请求和价格检索机制之间的不一致。考虑将印章应用到 hasPrice
和 getPrice
功能。
[L05]缺少 NatSpec 参数
中的许多功能 OptimisticRewarderBase
合同 缺少 @return
自然规范评论中的参数。为了完整性考虑将其包括在内。
[L06]剩余津贴
为了调用乐观预言机, OptimisticRewarderBase
合同 授予它象征性的津贴,因此可以拉动债券支付。如果提案失败, 奖励兑换被取消 但津贴不会重置。因此,乐观预言机将保留不必要的剩余配额,直到下次触发争议为止。如果提案失败,请考虑撤销津贴。
[L07]退款地址无效
退款L2地址 Arbitrum_ParentMessenger
已初始化 合同所有者,即 L1 州长。同样, setRefundL2Address
有评论 指出应将其设置为州长。然而,当通过桥传递消息时,该值是 设置为L2用户,这是 Arbitrum 上在票证解决后接收多余资金的地址。由于在 Arbitrum 上无法访问 L1 州长地址,因此发送到该地址的任何资金都将丢失。
考虑将其设置为有效的 L2 地址。
[L08]更改子信使的机制
GovernorSpoke
和 OracleSpoke
每个合约都在构造函数中初始化子信使,但没有更新它的机制。这意味着当 儿童信使已更改,两个辐条合约都变得过时了。
由于辐条合约可能比信使更稳定,因此请考虑包含一种更新辐条上信使的机制。
注释和其他信息
[N01]更改债券代币
Proposer
合同包括 一种机制 业主可以更改提案保证金的规模。考虑他们是否也应该能够更改债券代币。请注意,这需要一种机制来在解决现有提案时识别正确的债券货币。
更新: 没什么大不了。 UMA对此问题的声明:
N01 建议启用提议者合约,将债券代币更改为 UMA 以外的其他代币。我们无意支持除 $UMA 之外的任何代币来实现此功能,因此选择不对此问题进行任何更改。此外,每个合约只有一个代币,使这一逻辑尽可能简单。最后,如果需要进行更改(例如,在代币迁移的情况下),我们只需使用另一个代币部署一个新的提议者合约,并发起一项迁移系统以使用该代币的提议。
[N02] 接口不完整
ChildMessengerInterface
没有指定 processMessageFromCrossChainParent
功能,即使它被认为是由父信使存在的。为了完整性考虑将其包括在内。
更新: 不固定。 UMA对此问题的声明:
我们故意选择让这个接口保持不一致,因为在 ChildMessengerInterface 中实现这个接口会破坏与 Polygon_ChildMessenger 的兼容性,因为 Polygon 处理来自其他链的消息的方法需要一些自定义逻辑,其中调用一个名为 _processMessageFromRoot 的内部方法。
[N03]接口错误
GovernorSpoke
合同错误 使用 ChildMessengerConsumerInterface
类型 来描述它的 messenger
多变的。考虑使用 ChildMessengerInterface
代替。
[N04]拉取代币到Store
在一个 之前的审计 我们质疑这样做的目的 Store
合同的 payOracleFeesErc20
功能 (第 L19 期)。 UMA团队 选择保留该功能 标准化接口以供未来可能的修改。由于该函数的目的没有完全指定,因此不清楚当 Proposer
合同 没收保证金。它可能应该在以下情况下使用: OracleHub
支付价格请求。考虑该函数是否应该在任一场景中使用。
更新: 已获承认。 UMA对此问题的声明:
N04建议在Proposer和OracleHub合约中使用Store的payOracleFeeErc20方法来支付费用,以与Store的使用情况保持一致。我们选择不使用此函数,因为这意味着需要导入额外的接口(用于商店)并需要将债券金额转换为固定点(这也需要额外的导入。为了保持代码简单干净我们选择不这样做。OZ 在 20 年 1 月审计阶段 2020 中对 payOracleFeeErcXNUMX 的反馈是有效的,即这种方法并不是真正有用,使得这种集成更难以推理。
[N05]代码中的TODO
代码库中有“TODO”注释,应在项目的问题积压中进行跟踪。例如:
- Line 37 of
Arbitrum_ParentMessenger
合同 - Line 25 of
Optimism_ChildMessenger
合同 - 线 83 和 146 of
OracleHub
合同。
在开发过程中,详细描述“TODO”注释将使跟踪和解决问题的过程变得更加容易。如果没有这些信息,这些注释可能会失效,并且在将系统发布到生产环境时,系统安全的重要信息可能会被遗忘。
这些 TODO 注释应该包含待执行任务的简短描述,以及项目存储库中相应问题的链接。
考虑更新 TODO 注释以添加此信息。为了完整性和可追溯性,可以添加签名和时间戳。例如:
// TODO: point this at an interface instead.
// https://github.com/UMAprotocol/protocol/issues/XXXX
// --mrice32 - 20211209
[N06]印刷错误
代码库包含以下印刷错误:
- 在
Admin_ChildMessenger
合同,impleenting
应该implementing
- 在
OptimisticRewarderBase
合同,timestap
应该timestamp
. - 在
OptimisticRewarderBase
合同,liveness liveness
应该liveness
. - 在
GovernorSpoke
合同,only called
应该only be called
. - 在
Optimism_ChildMessenger
合同:
[N07]未使用的进口
为了提高代码的可读性,请考虑删除以下未使用的导入:
[N08]L2交易排序
Governor
确保 提案内的交易按顺序执行。然而,当这些交易涉及跨链交易时,这仅仅保证它们以正确的顺序到达L1桥合约。在 Arbitrum 案例中,它们可能会在 L2 上最终确定之前重新排序。因此,应该构建治理提案以允许重新排序 L2 交易的可能性。
更新: 截至提交时已修复 0fb2e7b
in PR72。 该 GovernorHub
现在可以中继一系列 L2 事务。
结论
在代码库中发现了两个关键问题。已发现一个中等严重性问题和几个小漏洞,并提出了修复建议。
- &
- 2020
- 7
- 9
- 关于
- 基本会计和财务报表
- 横过
- 行动
- Ad
- 额外
- 地址
- 所有类型
- 允许
- 四月
- 审计
- 作为
- blockchain
- 盒子
- 桥
- 例
- 更改
- 孩子
- 索赔
- 码
- 注释
- 包含
- 合同
- 合同的
- 可以
- 交叉链
- 货币
- 电流
- data
- 分散
- 研发支持
- 不同
- 争议
- 分布
- 生态系统
- 发射
- 使
- ERC20
- ETH
- 复仇
- 燕窝块
- 活动
- 例子
- 预期
- 延长
- 费用
- 金融
- 姓氏:
- 发现
- 基金会
- 功能
- 资金
- 未来
- 治理
- 管理者
- 有
- 持有人
- HTTPS
- 鉴定
- 重要
- 包含
- 信息
- 积分
- 接口
- 问题
- IT
- 实验室
- 有限
- 友情链接
- 长
- 制作
- 中等
- 信使
- 最先进的
- 抵消
- 神谕
- 秩序
- 其他名称
- 业主
- 支付
- 相
- 平台
- Polygon
- 池
- 车资
- 过程
- 生产
- 项目
- 提案
- 提供
- 提供
- 国家
- 记录
- 知识库
- 检讨
- 奖励
- 风险
- 保安
- 集
- 设置
- 简易
- 尺寸
- So
- 坚固
- 有人
- 东西
- 个人陈述
- 商店
- SUPPORT
- 支持
- 支持
- 系统
- test
- 次
- 象征
- 令牌
- 可追溯分析仪
- 跟踪
- 交易
- 交易
- 过境
- 更新
- 用户
- 折扣值
- 企业验证
- 漏洞
- 周
- WHO
- 中
- 也完全不需要
- 工作
- 价值
- 零