本文讨论了DeFi智能合约中的一种常见安全漏洞——双向舍入,解释了该漏洞如何导致交易者通过回合交易获利,介绍了避免这一漏洞的代码修复方法,并展示了sec3 Pro如何自动检测这类漏洞。通过实例分析,提供了对此问题的深刻见解和解决方案。
在过去的几个月中,我们观察到 DeFi 应用中越来越多的漏洞,它们都符合一个常见模式:双向取整。
如果一个智能合约有一个或多个双向函数(例如,在一对代币之间进行兑换或铸造/赎回一种代币),并且该函数在两个方向上对算术结果使用相同的取整操作,则该函数可能容易受到双向交易攻击。
在本文中,我们解释双向取整的关键问题,并展示 sec3 Pro 如何自动检测这种取整漏洞。
原因很简单:双向取整可能允许攻击者利用四舍五入错误通过往返交易来获得 免费利润:
尽管每次往返交易中利润都很小(步骤 1–2),但往返可能会重复多次,最终导致协议重大损失。
让我们考虑一个实际的双向取整例子,在 spl token-lending 程序中(最初由 Neodyme 发现,见“如何成为百万富翁,0.000001 BTC 为单位”):
第 65 行:deposit_liquidity 调用 liquidity_to_collateral
第 77 行:redeem_collateral 调用 collateral_to_liquidity
函数 liquidity_to_collateral 和 collateral_to_liquidity 是一对 双向函数,分别由 deposit_liquidity 和 redeem_collateral 调用。
在每个方向上,给定一个输入 collateral_amount 或 liquidity_amount,这些函数计算 liquidity_amount 或 collateral_amount。
但是,在两个方向上,这些函数在内部使用相同的取整操作 try_round_u64:
第 558 行:collateral_to_liquidity 调用 try_round_u64
第 571 行:collateral_to_liquidity 调用 try_round_u64
由于通过输入 collateral_amount 和 liquidity_amount 可以控制向上或向下取整,因此双向交换可以变得可盈利。
修复双向取整的问题取决于代码的语义,但在大多数情况下可以很简单:
amount_out.try_floor_u64(
fee.try_ceil_64()?
上述修复(即,向 amount_out 添加 floor() 操作,以及向 fee 添加 ceil() 操作)确保 amount_out 始终向下取整,并且 fee 始终向上取整,因此往返交易不再可盈利。
例如,在 spl token-lending 中的修复应用了 try_floor_u64() 操作以确保结果始终向下取整:
collateral_to_liquidity 的双向取整错误修复
liquidity_to_collateral 的双向取整错误修复
注意: 双向取整漏洞不一定需要两个不同的函数,但可以存在于处理双向交易的单个函数中,例如 swap。
sec3 Pro 是 Solana 智能合约的卓越安全分析服务。为了检测双向取整问题:
该工具首先查找智能合约中所有的双向函数,包括依赖项。对于每个双向函数,它定位取整签名(例如,通常是整数乘法后跟除法),如果任何取整操作的结果未始终如一地向上或向下取整,则该工具会标记潜在漏洞。
以下是 Sec3 Pro 在我们的例子中报告的双向取整的屏幕截图。sec3 Pro 可在 https://pro.sec3.dev 访问。
sec3 是一家安全研究机构,旨在为数百万用户准备 Solana 项目。sec3 的 Launch Audit 是一项严格的研究人员主导的代码检查,调查并认证主网级智能合约;sec3 的持续审计软件平台 X-ray 与 GitHub 集成,逐步扫描拉取请求,帮助项目在部署前巩固代码;sec3 的后续部署安全解决方案 WatchTower 确保资金安全。sec3 正在为 Web3 项目构建基于技术的可扩展解决方案,以确保协议在扩展时保持安全。
要了解更多有关 sec3 的信息,请访问 https://www.sec3.dev
- 原文链接: sec3.dev/blog/bidirectio...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!