2021 年 12 月 6 日
介绍
符合 团队要求我们审查和审计一组合同,最终目标是改进共同治理合同并赋予它们更大的灵活性。我们查看了代码,现在发布我们的结果。
系统总览
该系统依赖于三个主要合约:
- A
SafeGuard
合同模板。该合同是admin
的Timelock
合同,并在之上添加了一层模块化角色Timelock
的行动。该合约定义了多个角色,这些角色对提案的状态(排队、取消和执行)具有单独的责任和访问权限。 - A
SafeGuardFactory
合约部署了一个新的SafeGuard
以及相应的新Timelock
合同。然后它在内部设置时间锁地址SafeGuard
签订合同并注册新的SafeGuard
到Registry
. - A
Registry
其中包含已部署的列表SafeGuards
与它们对应的 版本号.
SafeGuardFactory
基本上会产生一个 新 SafeGuard
每当它被调用时。 A SafeGuard
是一个环绕 Timelock
操作 这为每个操作添加了不同且独立的角色。角色是通过使用 OpenZeppelin 来构建的 AccessControlEnumerable
合约为多重签名钱包和业务用例提供了更大的灵活性和兼容性,其中多个地址可以具有相同的共享角色。
更新: 在 PR#10,Tally 团队决定删除 Registry
合同。部署的防护措施列表现在存储在 SafeGuardFactory
合同,在 safeGuards
可枚举集及其版本存储在 safeGuardVersion
映射。
角色
SafeGuard
合同定义了以下角色:
更新: CREATOR_ROLE
作为问题 L02 的修复,该角色已被删除。
范围
我们审核了提交 b2c63a9dfc4090be13320d999e7c6c1d842625d3
的 safeguard
存储库。范围内的智能合约 contracts
目录。但是,那 mocks
目录被视为超出范围。
假设
该系统不可升级。这 Registry
地址已设置 在构造函数中 的 SafeGuardFactory
和每个 SafeGuard
可以有 Timelock
仅设置一次。这意味着如果一个新的 Registry
部署了一个新的 SafeGuardFactory
也必须部署。如果 Timelock
实施变更,旧的 SafeGuard
它将变得过时,并且必须部署新的。
此外,该系统严重依赖于 Timelock
合同 这被认为超出了本次审计的范围。该团队尚未最终确定该方案的实施 Timelock
合同。在撰写本报告时, 化合物的时间锁实施 正在项目中使用。
两名审计员在一周内对代码库进行了审计,在此我们展示我们的调查结果。
严重程度
没有。
高严重性
[H01] ETH可以锁在里面 Timelock
合同
Tally
团队最初的实施基于 GovernorBravoDelegate
复合合同。
在本次审计过程中, Tally
团队发现 限制 在Compound的调控器中,ETH直接发送到 Timelock
无法供治理提案使用,尽管它不会永久卡住,但需要复杂的解决方法才能检索。
这是因为州长实施要求将提案的所有价值附加为 msg.value
由触发执行的帐户,不以任何方式使用 Timelock
以太坊基金。
后来在 SafeGuard
履行 团队已经意识到这个问题,并且正在修复它。
解决问题时,考虑使用该方法 被 OpenZeppelin 库针对同一问题采用.
更新: 已在提交中修复 7337db227edda83533be586135d96ddac4f5bf29
.
[H02] SafeGuardFactory 可以被冻结
Registry
合同旨在跟踪所有 SafeGuards
该 SafeGuardFactory
产生。它具有外部 register
功能 用于此目的。
在同一时间,在 SafeGuardFactory
在其构造函数中,有局部变量的赋值 registry
值到输入值。不可能改变的值 registry
变量,因此,如果一个新的 Registry
部署后,还必须部署新工厂。
SafeGuardFactory
有 createSafeGuard
功能, 负责第一 部署一个新的 SafeGuard
, 然后 一个新的 Timelock
与地址 SafeGuard
as admin
, 然后设置 timelock
的变量 SafeGuard
合同,最后 注册 SafeGuard
在注册表中.
问题是任何调用 createSafeGuard
攻击者可以直接注册新的确定性地址,从而迫使其失败 SafeGuard
在其创建之前。每当签订合同时 创造一个 new
例,其随机数增加,并且可以通过原始合同地址及其随机数来确定新合约实例的部署地址。因此,攻击者可以预先计算出新地址所在的许多地址。 SafeGuards
将被部署并在中注册这些地址 Registry
通过调用 register
功能。这将导致调用 createSafeGuard
至 还原 自 Registry
已经包含地址。
为了避免外部参与者公开呼吁 Register
合同,考虑限制对 register
函数专门接受调用 SafeGuardFactory
.
更新: 固定在 PR#10。 Tally 团队已删除 Registry
合同。
中等严重程度
没有。
严重程度低
[L01]注释掉代码
Registry
合同包括 注释掉的代码行。为了提高可读性,请考虑将其从代码库中删除。
更新: 固定在 PR#10 并承诺 7fd27df16fc879d990d36a167a0b6e719e578558
.
[L02] SafeGuard 管理员可以将创建者角色分配给任何地址
SafeGuard
合同定义了a的角色 CREATOR_ROLE
顾名思义,它被分配给保障措施的创建者。
然而,通过调用 此 grantRole
的功能 AccessControlEnumerable
合同 在 OpenZeppelin 合约库中,管理员可以将此角色授予任何地址。这可能会引起混乱,因为 的创造者 SafeGuard
只能是 SafeGuardFactory
.
在整个代码库中,此角色仅用于限制用户与 setTimelock
功能 的 SafeGuard
合同。通过设计,系统确保 setTimelock
功能 只能被调用一次从 字幕可视电话用于 SafeGuardFactory
合同.
考虑删除 CREATOR_ROLE
角色来自 SafeGuard
合同并使用 onlyOwner
变化 ,在 setTimelock
功能。
更新: 固定在 PR#10.
[L03]接口定义和实现不正确
ISafeGuard
接口没有定义 queueTransactionWithDescription
功能 在实施 SafeGuard
合同,同时它定义了 __abdicate、__queueSetTimelockPendingAdmin 和 __executeSetTimelockPendingAdmin 功能,但没有实现。
为了提高代码库的正确性和一致性,请考虑重构 ISafeGuard
接口完全匹配 SafeGuard
实施。
更新: 已在提交中修复 7fd27df16fc879d990d36a167a0b6e719e578558
.
[L04] 缺少文档字符串
代码库中的一些合约和函数缺乏文档。例如, 一些功能 ,在 SafeGuard
合同。
此外,一些文档字符串使用非正式语言,例如 上方的 setTimelock
函数在 SafeGuard
合同.
这阻碍了审查者对代码意图的理解,而这对于正确评估安全性和正确性至关重要。此外,文档字符串提高了可读性并易于维护。他们应该明确解释函数的目的或意图、函数可能失败的场景、允许调用它们的角色、返回的值和发出的事件。
考虑彻底记录作为合约公共 API 一部分的所有函数(及其参数)。实现敏感功能的函数,即使不是公开的,也应该清楚地记录下来。编写文档字符串时,请考虑遵循 以太坊自然规范格式 (国家规范)。
更新: 部分固定在 PR#10。适当的文档字符串已添加到整个代码库的各种函数中。但是,除了当前的更改之外,请考虑进行以下更改:
- 地址
description
作为@param
在上面的文档字符串中queueTransactionWithDescription
功能 - 地址
@param
,在 文档字符串 上方的createSafeGuard
功能SafeGuardFactory
合同 - 地址
@return
在上面的文档字符串中的函数SafeGuardFactory
合同。
[L05]无用或重复的代码
代码库中有些地方的代码要么是重复的,要么是不需要的。一些例子是:
- 29-32行 的
Registry
合同是没有用的,因为_add
的功能EnumerableSet
合同 已经执行这些检查 与已设置的值相对应。 - 62行, 67, 73 和 78 的
SafeGuard
合约都在重复相同的操作。考虑将其封装到内部函数中以避免重复代码。 - 62-63行 和 67-68 of
SafeGuard
被重复。考虑将它们封装到单个内部函数中。 - 用法
gasleft
指定在函数调用中应转发多少气体executeTransaction
是不必要的。这是因为,在执行时,剩余的所有气体将用于继续执行。如果这不是为了明确,请考虑删除gas
来自调用的参数。
考虑应用建议的修复来生成更清晰的代码并提高代码库的一致性和模块化性。
更新: 固定在 PR#10 并承诺 7fd27df16fc879d990d36a167a0b6e719e578558
.
注释和其他信息
[N01]风格不一致
代码库中有些地方,风格的差异影响了可读性,使代码更难以理解。一些例子是:
-
Registry
整个合约中的文档字符串使用不同的样式。 -
SafeGuard
合约发出事件时queueTransactionWithDescription
被调用,但处理事务的其他函数中不会发出任何事件。 - 在
SafeGuard
合同,有时 折扣值 用作命名参数,有时 _价值 用来。
考虑到一致的编码风格可以增加项目可读性的价值,请考虑在 linter 工具(例如 Solhint)的帮助下强制执行标准编码风格。
更新: 固定在 PR#10 并承诺 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N02] 缺少许可证
代码库中的以下合约缺少 SPDX 许可证标识符。
为了消除编译器警告并提高代码库的一致性,请考虑添加许可证标识符。在这样做时考虑参考 开发工具 指导方针。
更新: 固定在 PR#10 并承诺 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N03]未固定OpenZeppelin合同的依存关系
为了防止意外行为,以防在以后的更新中发布重大更改 OpenZeppelin 合约库,请考虑将此依赖项的版本固定在 的package.json 文件中。
更新: 固定在 PR#10.
[N04] Solidity 编译器版本未固定
在整个代码库中,请考虑固定版本 Solidity编译器 到最新的稳定版本。这应该有助于防止由于未来版本不兼容而引入意外错误。在选择特定版本时,开发人员应考虑项目所需的编译器功能和 已知错误列表 与每个 Solidity 编译器版本相关联。
更新: 固定在 PR#10.
[N05] 拼写错误
在整个代码库的不同实例中,这个词 role
拼写错误为 rol
。一个这样的例子是 中的文档字符串 constructor
的 SafeGuard
合同.
考虑更正这些拼写错误以提高代码的可读性。
更新: 部分固定在 PR#10。虽然拼写为 role
已更正,注释“将管理角色设置为定义的管理地址”应为“将管理角色设置为定义的管理地址”。此外,“执行”在 SafeGuard
合同在 行69, 行82, 行96 和 行110 并且“可用”拼写错误 行70, 行83, 行97, 行111。另外,考虑替换非正式词语,例如 “要” in SafeGuard
与正式的替代词签订合同,例如“去”。
[N06] 将 uint 声明为 uint256
代码库中多次出现声明变量的情况 uint
数据类型而不是 uint256
, 例如, eta
在变量 QueueTransactionWithDescription
活动 的 SafeGuard
合同。
为了明确起见,所有实例 uint
应声明为 uint256
.
更新: 固定在 PR#10 并承诺 7fd27df16fc879d990d36a167a0b6e719e578558
.
[N07]未使用的导入
SafeGuard
合同进口 console
合同但从未使用它。
为了提高代码的可读性,请考虑删除所有未使用的导入。
更新: 固定在 PR#10.
结论
已发现一个高漏洞和其他几个小漏洞,并提出了建议和修复。
- &
- ACCESS
- 账号管理
- 横过
- 操作
- 行动
- 额外
- 地址
- 管理员
- 所有类型
- 已经
- 尽管
- API
- 的途径
- 围绕
- 审计
- 基本上
- 作为
- 虫子
- 商业
- 呼叫
- 例
- 原因
- 更改
- 充
- 码
- 编码
- 相当常见
- 复合肥产线
- 混乱
- 考虑
- 包含
- 继续
- 合同
- 合同的
- 可以
- 创造者
- 电流
- data
- 处理
- 设计
- 开发
- 不同
- 发现
- 阐述
- ETH
- 活动
- 事件
- 例子
- 工厂
- 特征
- 终于
- 姓氏:
- 固定
- 高度灵活
- 发现
- 功能
- 资金
- 未来
- 天然气
- 给予
- 目标
- 治理
- 管理者
- 方针
- 有
- 帮助
- 此处
- 高
- 创新中心
- HTTPS
- 实施
- 增加
- 增加
- 接口
- IT
- 已知
- 语言
- 最新
- 自学资料库
- 执照
- Line
- 清单
- 本地
- 锁定
- 看着
- 制作
- 匹配
- 模块化
- Multisig
- 其他名称
- 当下
- 过程
- 项目
- 提案
- 国家
- 发布
- 寄存器
- 发布
- 报告
- 知识库
- 成果
- 检讨
- 保安
- 集
- 设置
- 共用的,
- 智能
- 智能合同
- 坚固
- 州/领地
- 样式
- 系统
- 通过
- 始终
- 次
- 工具
- 跟踪时
- 交易
- 最新动态
- us
- 用户
- 折扣值
- 漏洞
- 钱包
- 周
- WHO
- 中
- 话
- 写作