该文档是OpenZeppelin对1inch Fusion和Limit Order Protocols的代码审计报告。
TypeDeFiTimeline从 2025-04-21至 2025-04-25语言Solidity问题总数8 (7 已解决)严重性问题0 (0 已解决)高风险问题0 (0 已解决)中风险问题0 (0 已解决)低风险问题2 (2 已解决)说明 & 补充信息6 (5 已解决)
OpenZeppelin 审计了 1inch/fusion-protocol 仓库,提交哈希为 c0197a5。
审计范围包括以下文件:
contracts
└── SimpleSettlement.sol
此外,1inch/limit-order-protocol 仓库也经过了审计,提交哈希为 cf8e50e。
审计范围包括以下文件:
contracts
└── extensions
├── AmountGetterBase.sol
├── AmountGetterWithFee.sol
└── FeeTaker.sol
该项目引入了一个结算合约 ( SimpleSettlement.sol
) 用于去中心化交易,通过一个可配置的收费机制、一个荷兰式拍卖风格的速率调整和一个基于时间的taker白名单来增强功能。该合约与 AmountGetterBase.sol
、AmountGetterWithFee.sol
和 FeeTaker.sol
集成,以计算费用、调整价格和验证白名单。
结算合约由解析器(taker)在限价订单协议中的交易执行期间调用。它用于计算费用、处理荷兰式拍卖价格调整以及验证基于时间的taker白名单,从而确保安全高效的结算。
有两种类型的费用,在创建订单时配置:
两种费用都由 AmountGetterWithFee.sol
计算,并在结算期间由 FeeTaker.sol
转移。taker承担这两种费用,因为这些费用要么减少了净收到的代币,要么增加了支付的代币。
SimpleSettlement.sol
实现了荷兰式拍卖机制,其中交换价格随时间降低以鼓励快速执行。价格曲线由速率增量定义 - 在特定时间戳(例如,1000 秒)设置的预定义价格调整(例如,100 wei)。这些编码在 SimpleSettlement.sol
中的 pointsAndTimeDeltas
数组中。在结算期间,拍卖增量(有效价格调整)通过在两个速率增量之间基于当前区块链时间戳进行线性插值来计算。
例如,如果一个速率增量点在 1000 秒时为 100 wei,下一个在 2000 秒时为 200 wei,则在 1500 秒时,拍卖增量为 150 wei。可选择地,基于估计的 gas 价格( block.baseFee
)的 gas 增量会减少 taker 支付的有效价格。在 SimpleSettlement.sol
的 _getAuctionBump
中实现,gas 增量从拍卖增量中扣除,随着 gas 价格可变性的增加而增加,以抵消 taker 的损失并鼓励及时填写订单,如 1IP-43 中投票决定。
可选的白名单限制了哪些地址可以作为taker,时间检查点控制访问。每个列入白名单的地址都与一个时间戳( allowedTime
)相关联,并且随着检查点的到达,符合条件的taker数量会增加。例如,一旦 block.timestamp
超过其 allowedTime
,新地址将变得符合条件。这在 SimpleSettlement.sol
合约的 _isWhitelistedPostInteractionImpl
函数中实现。
安全模型通过经过审计的合约( SimpleSettlement.sol
、AmountGetterBase.sol
、AmountGetterWithFee.sol
、FeeTaker.sol
)和输入验证来确保安全、高效的 gas 交易。主要方面包括:
EIP-712
签名,并在链上验证以防止篡改。扩展的安全性取决于以下假设:
SimpleSettlement.sol
中执行交易而不操纵 whitelistData
(taker 资格)或 pointsAndTimeDeltas
(拍卖价格曲线)。恶意taker可能会扰乱结算,但会因声誉和费用激励而受到阻止。SimpleSettlement._getAuctionBump
中的正确 pointsAndTimeDeltas
配置:
uint8
最大值)。pointsAndTimeDeltas
的第一个字节指定点的数量。FeeTaker._postInteraction
中的正确 extraData
结构:
_CUSTOM_RECEIVER_FLAG
,则 extraData
包括一个 20 字节的 feeCustomReceiver
地址,该地址未以其他方式包含在内。在整个代码库中,发现了多个缺少文档字符串的实例:
AmountGetterBase.sol
中,getMakingAmount
函数AmountGetterBase.sol
中,getTakingAmount
函数IAmountGetter.sol
中,IAmountGetter
接口IOrderMixin.sol
中,IOrderMixin
接口考虑彻底记录所有属于任何合约公共 API 的函数(及其参数)。实现敏感功能的函数,即使不是公共函数,也应明确记录。编写文档字符串时,请考虑遵循 Ethereum Natural Specification Format (NatSpec)。
更新:已在 pull request #364 中解决。
在整个代码库中,发现了多个不完整的文档字符串的实例:
IAmountGetter.sol
中:
getMakingAmount
和 getTakingAmount
函数中,并非所有返回值都已记录。IOrderMixin.sol
中:
remainingInvalidatorForOrder
和 rawRemainingInvalidatorForOrder
函数中,未记录 maker
参数。SimpleSettlement.sol
中:
_getAuctionBump
和 _getRateBump
函数中,未记录 tail
返回变量。_getFeeAmounts
函数中,未记录任何返回变量。考虑彻底记录所有属于合约公共 API 的函数/事件(及其参数或返回值)。编写文档字符串时,请考虑遵循 Ethereum Natural Specification Format (NatSpec)。
更新:已在 "limit-order-protocol" 的 pull request #365 和 "fusion-protocol" 的 pull request #192 中解决。
函数修饰符的顺序应如下:visibility
、mutability
、virtual
、override
和 custom modifiers
。
SimpleSettlement.sol
中的 _getFeeAmounts
函数具有错误的修饰符顺序。
为了提高项目的整体可读性,请考虑按照 Solidity 风格指南 的建议重新排列函数修饰符。
更新:已在 pull request #193 中解决。
在智能合约中提供特定的安全联系人(例如电子邮件或 ENS 名称)可以显著简化个人在代码中发现漏洞时进行沟通的过程。这种做法非常有益,因为它允许代码所有者指定漏洞披露的沟通渠道,从而消除了因缺乏如何操作的知识而导致沟通不畅或未能报告的风险。此外,如果合约包含第三方库并且在这些库中出现错误,则其维护人员可以更轻松地就该问题联系到合适的人员并提供缓解说明。
在整个代码库中,发现了多个没有安全联系人的合约实例:
考虑在每个合约定义上方添加包含安全联系人的 NatSpec 注释。建议使用 @custom:security-contact
约定,因为它已被 OpenZeppelin Wizard 和 ethereum-lists。
更新:已确认,未解决。团队表示:
知道了
IAmountGetter
接口中 getTakingAmount
函数的文档字符串中的单词“making”应更改为“taking”。
考虑实施上述建议,以提高代码库的清晰度和可维护性。
更新:已在 pull request #366 中解决。
在 FeeTaker.sol
的 第 93 行 中,“accidently”应更正为“accidentally”。
考虑更正上述拼写错误,以提高代码库的可读性。
更新:已在 pull request #367 中解决。
在整个代码库中,发现了多个合约由于函数顺序不一致而偏离 Solidity 风格指南的实例:
FeeTaker.sol
中的 FeeTaker
合约IOrderMixin.sol
中的 IOrderMixin
合约SimpleSettlement.sol
中的 SimpleSettlement
合约为了提高项目的整体可读性,请考虑按照 Solidity 风格指南 (函数顺序) 的建议,标准化整个代码库中的顺序。
更新:已在 "limit-order-protocol" 的 pull request #368 和 "fusion-protocol" 的 pull request #194 中解决。
在 AmountGetterWithFee.sol
的 第 81 行 和 第 84 行 中,可以通过直接指定单个索引而不是使用切片运算符来简化 bytes1
类型转换。类似地,在 SimpleSettlement.sol
的 第 212 行 中,也可以通过直接访问所需的索引来简化 bytes1
类型转换。
考虑简化上述类型转换操作,以提高代码库的清晰度和可维护性。
更新:已在 "limit-order-protocol" 的 pull request #369 和 "fusion-protocol" 的 pull request #195 中解决。
经过审计的代码库为 1inch Fusion 和 Limit Order 协议引入了一个扩展,通过可配置的收费机制、荷兰式拍卖风格的费率调整和基于时间的taker白名单来增强其功能。
在审计期间未发现安全问题。但是,仍然提出了多项建议,以提高代码的可读性和清晰度,以便于未来的审计、集成和开发。
感谢 1inch 团队在整个审计期间的积极响应,并提供了有关经过审计的代码库的全面文档。
- 原文链接: blog.openzeppelin.com/1i...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!