iZiFinance 是一个利用 zkSync 的去中心化金融协议,zkSync 是以太坊的一个二层扩容解决方案。zkSync 可以在以太坊上实现快速和低成本的交易,同时保留了一层网络的安全性和可组合性。然而,在 zkSync 上进行智能合约开发时,gas 优化仍然是一个重要的方面,因为它影响了协议的性能和盈利能力。
在这个分析中,我们将检查 iZiFinance 的一个核心合约,iZiSwapPool.sol,并找出一种通过消除一个多余的表达式来减少 gas 消耗的简单方法。
iZiSwapPool合约
The iZiSwapPool 合约实现了 iZiFinance 上的流动性池和代币交换的逻辑,它遵循了 IiZiSwapPool 接口,该接口定义了合约的函数和事件。其中一个函数是 modifyFeeChargePercent,它允许合约的所有者调整每个池的费用收取百分比。费用收取百分比是一个参数,它决定了交换费用在流动性提供者和协议之间的分配。modifyFeeChargePercent 函数的代码如下:

该函数接受一个 uint24 类型的参数,叫做 newFeeChargePercent,它表示要设置的新的费用收取百分比。它还有一些修饰符和 require 语句,以确保只有所有者可以调用该函数,并且 newFeeChargePercent 是有效的。代码分析这段合约代码是用 Solidity 写的,表示一个修改费用收取百分比的函数。它似乎是以一种安全的方式设计的,考虑到在进行实际修改之前应用的限制(第 534-536 行)。
然而,第 535 行 require(newFeeChargePercent >= 0, "FP0"); 实际上是不必要的。这是因为在 Solidity 中,uint(无符号整数)数据类型不能为负。uint24 是一个无符号整数类型,范围是从 0 到 2^24 - 1。
因此,检查 newFeeChargePercent 是否大于或等于 0 是同义反复,因为根据定义,一个无符号整数不能小于 0。因此,这一行构成了一个同义反复,可以在不影响代码功能或引入任何安全漏洞的情况下安全地移除。紧接着它的那一行,require(newFeeChargePercent <= 100, "FP0");,就足以确保 newFeeChargePercent 在期望的范围内(0-100)。
中心化风险
我们还发现了一些可能损害协议安全性和用户资产安全的中心化风险。

安全建议
对于iZiFinance项目方来说,这里有 10 条安全小提示以保护用户的链上资产免受中心化风险的影响。
- 对 setFarm() 和 setWrapToken() 等关键函数施加时间锁,只允许在未来指定的时间进行修改,给社区时间讨论和达成共识
- 要求多个钱包地址的多重签名批准才能调用 enableFeeAmount() 和 newPool() 等影响费用和奖励的函数
- 为 expandObservationQueue() 和 collectFeeCharged() 等函数实现基于角色的访问控制,限制只有指定角色才能调用
- 在合约部署时,使 startBlock、endBlock、rewardPerBlock 等核心参数不可变,不允许后续更改
- 建立一个 DAO 治理结构,要求对敏感函数的调用需要社区提案和投票
- 采用模块化架构,分离职责,避免任何单个模块过度集中化
- 建立一个带有多重签名认证的紧急停止机制,如果出现问题,可以暂停协议
- 定期进行外部安全审计,并及时处理发现的问题,以降低中心化控制风险
- 在开发过程中,采用模糊测试和其他方法来识别和消除中心化控制漏洞
- 遵循最小特权原则,只给予角色和账户必要的最小权限
这些中心化风险源于合约所有者可能对合约的参数和函数有过度的控制,这或许能让所有者操纵协议或伤害用户。我们也希望这篇分析能为改进 iZiFinance 的智能合约提供一些有用的见解和安全建议。
Follow Us
Twitter: @MetaTrustLabs
Website: metatrust.io
所有评论