本篇文章总结了近期Web3领域出现的一些安全漏洞和安全事件,主要分析了不一致的Scaling问题,包括MBU Token由于Scaling不匹配导致攻击者获利200万美元,以及Across Protocol在Gas Token金额计算中错误的十进制Scaling导致超额收费。
欢迎来到# Notorious Bug 季刊 #3——一份精选的关于近期 Web3 Bug 和安全事件的分析汇编。我们的安全研究员们在进行审计之余,还会花时间了解安全领域的最新动态,分析审计报告,以及剖析链上事件。我们相信这些知识对于更广泛的安全社区来说是宝贵的,它为研究人员提供了一个磨练技能的资源,并帮助新手探索 Web3 安全的世界。加入我们,一起探索这批 Bug 吧!
缩放通常用于在不同 Token 之间的除法或单位转换期间管理精度。然而,不一致的缩放可能导致严重 Bug,造成不正确的计算和重大的财务损失。下面,我们分析一个最近的链上事件和一个审计发现,以说明这个 Bug。
MBU Token - 不匹配的缩放
在 2025 年 5 月 11 日,MBU Token 合约遭受了一次攻击,导致 200 万美元的损失。如图 A所示,攻击者向合约存入了 0.001 BNB,合约随后从预言机获取 BNB/USDT 和 MBU/USDT 的价格。尽管收到了准确的价格,但合约铸造了大量的 MBU Token,远远超过了存入的 BNB 的价值,使攻击者得以获利。
图 A
检查 deposit
函数(需要注册)可以发现问题(图 B)。
图 B
deposit
函数旨在计算与存入资产价值等值的 MBU Token 数量。它首先调用 0x371b
函数(图 C)来计算存入资产的 USDT 价值。
图 C
如果存入的 Token 是 USDT,该函数直接返回该数量不进行缩放。如果是 BNB,它返回 USDT 的价值,缩放 1e18 倍。然后将此值传递给 0x3039
函数(图 D),该函数通过将输入值除以 MBU/USDT 价格来计算 MBU Token 的数量,MBU/USDT 价格也缩放了 1e18 倍。然而,0x3039
函数错误地在除法之前对输入值应用了额外的 1e18 缩放。因此,当存入 BNB 时,铸造的 MBU Token 数量会膨胀 1e18 倍,而 USDT 存款则会产生正确的数量。
图 D
Across Protocol - Gas Token 数量计算中的错误的小数位缩放
这个 Bug 是在我们的一次审计中发现的,该审计是关于一个跨链协议。这个合约处理目标链的自定义 Gas Token,但未能考虑不同的 Token 小数位缩放。它使用一个假设18 位小数缩放的公式来计算操作所需的 Gas Token 数量。然而,像 USDC 这样使用 6 位小数的 Token 没有针对它们的实际小数位进行调整。因此,该合约使用 18 位小数缩放的数量从一个出资合约中提取资金,导致严重的超额收费。对于 USDC,这导致提款膨胀了 10^(18-6)
= 10^12
倍,造成了巨大的经济损失。
经验教训
对于多 Token 操作和缩放要格外小心。全面的测试,包括单元测试,可以快速识别这些不一致之处。
OpenZeppelin 团队一直在开发Stellar 合约库,这是一组智能合约,旨在作为为 Stellar 区块链开发应用程序的构建块。一项内部审计发现了一个中等严重程度的问题,该问题可能导致调用回滚,因其延长批准的时间超过了 Stellar 允许的最大 TTL 扩展期。Stellar 可以在有限的时间内存储合约数据,这被称为 Time to Live (TTL)。TTL 可以定期延长,如果未延长,数据将在 TTL 到期后被存档或永久删除。
Fungible Token 的实现具有类似于 ERC-20 标准的批准机制。批准存储在临时存储中(即,它们会在一段时间后过期并被永久删除)。在授予/更新批准时,用户可以指定批准的有效时间:这会相应地更新存储条目的 TTL。但是,Stellar 具有最大 TTL 值,临时存储条目可以通过该值进行扩展。尝试将条目的 TTL 增加超过最大值会导致代码崩溃,因此,任何长期批准(长于最大 TTL,即 1 年)都将回滚。
图 E
ZKsync 引入了 SSO 账户,这是一个可定制的智能账户,可以通过任意机制验证交易。执行Hook可以附加到一个账户,并且会在每次交易之前和之后运行。
如图 F 所示,preExecutionHook
函数为每个Hook运行,然后是交易执行,最后是每个Hook的 postExecutionHook
函数。
图 F
但是,Hook列表没有被缓存,如果列表在运行Hook之间被更改,这可能会导致意外行为。如果交易执行添加或删除任何Hook,列表中的排序可能会变得不同,导致 postExecutionHook
以不同的顺序被调用。此外,如果一个Hook被删除,由于访问越界存储,交易将回滚。
引入的修复方案缓存了Hook列表,同时确保 postExecutionHook
调用以相同的顺序运行,并且仅在Hook未被删除的情况下运行。
重要的是要强调,此内容背后的意图不是批评或指责受影响的项目,而是提供客观的概述,作为社区学习的教育材料,并在未来更好地保护项目。
- 原文链接: blog.openzeppelin.com/th...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!