本文总结了近期Web3领域中出现的三类安全漏洞:不一致的缩放漏洞、Stellar合约库中的Fungible Tokens实现DoS漏洞、以及ZKsync SSO账户在添加或删除执行Hook时出现的意外行为。文章通过分析具体案例,例如MBU Token遭受的攻击和Across Protocol中的错误缩放问题,强调了在多代币操作和扩展时保持谨慎的重要性,并分享了相应的经验教训。
介绍 欢迎来到臭名昭著的 Bug 摘要 #3——这是一份精选的关于近期 Web3 Bug 和安全事件的见解汇编。我们的安全研究人员在进行审计之余,会花时间了解安全领域的最新动态,分析审计报告,并剖析链上事件。我们相信这些知识对于更广泛的安全社区来说是宝贵的,为研究人员提供了一个磨练技能的资源,并帮助新手驾驭 Web3 安全的世界。加入我们,一起探索这批 Bug 吧!
缩放通常用于在不同 Token 之间的除法或单位转换期间管理精度。但是,不一致的缩放可能导致严重的 Bug,导致不正确的计算和重大的经济损失。下面,我们分析一个最近的链上事件和一个审计发现,以说明这个 Bug。
MBU Token - 不匹配的缩放
2025 年 5 月 11 日, MBU Token 合约 遭受了 黑客攻击,导致 200 万美元的损失。如图 图像 A 所示,攻击者将 0.001 BNB 存入合约,然后从 Oracle 获取 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 价格(也缩放了 1e18 倍)来计算 MBU Token 数量。但是,0x3039 函数错误地将额外的 1e18 缩放应用于除法之前的输入值。因此,当存入 BNB 时,铸造的 MBU Token 数量会膨胀 1e18 倍,而 USDT 存款会产生正确的金额。

图像 D
Across 协议 - Gas Token 数量计算中错误的十进制缩放
此 Bug 是在 我们的一次审计中 中发现的跨链协议。该 合约 处理目标链的自定义 Gas Token,但未能考虑不同的 Token 小数位数比例。它使用假设 18 位小数比例 的公式计算操作所需的 Gas Token 数量。但是,像使用 6 位小数位数的 USDC 这样的 Token 不会根据其实际小数位数比例进行调整。因此,合约使用 18 位小数比例的金额从资金提供者合约中提取资金,导致大量超额收费。对于 USDC,这导致提取的金额膨胀了 `10^(18-6)=10^12` 倍,从而造成重大的经济损失。
经验教训
在多 Token 操作和缩放时要格外小心。全面的测试,包括单元测试,可以快速识别这些不一致之处。
OpenZeppelin 团队一直在开发 Stellar 合约库,这是一组智能合约,旨在作为开发 Stellar 区块链应用程序的构建块。一项内部审计发现了一个 中等严重性问题,该问题可能会恢复超过 Stellar 允许的最大 TTL 扩展期的批准调用。Stellar 可以在有限的时间内存储合约数据,称为 生存时间 (TTL)。TTL 可以定期延长,如果未延长,则数据将在 TTL 过期后被存档或永久删除。
Fungible Token 的实现具有类似于 ERC-20 标准的批准机制。批准存储在临时存储中(即,它们在一段时间后过期并被永久删除)。在授予/更新批准时,用户可以指定批准有效的时长:这会相应地更新存储条目的 TTL。但是,Stellar 具有一个最大 TTL 值,临时存储条目可以扩展该值。尝试将条目的 TTL 增加超过最大值将导致代码崩溃,因此,任何长期批准(长于最长 TTL,为 1 年)都将恢复。
图像 E
ZKsync 引入了 SSO 帐户,这是一种可定制的智能帐户,可以通过任意机制验证交易。执行 Hook 可以附加到帐户,并且将在每次交易之前和之后运行。
如图 F 所示,将为每个 Hook 运行 preExecutionHook 函数,然后执行交易,并为每个 Hook 运行 postExecutionHook 函数。
图像 F
但是,Hook 列表未被缓存,如果列表在运行 Hook 之间更改,可能会导致意外行为。如果交易执行添加或删除了任何 Hook,则列表中的顺序可能会变得不同,从而导致以不同的顺序调用 postExecutionHook。此外,如果删除了 Hook,则由于访问越界存储,交易将恢复。
引入的修复程序缓存了 Hook 列表,同时确保 postExecutionHook 调用以相同的顺序运行,并且仅当 Hook 未被删除时才运行。
重要的是要强调,此内容的意图不是批评或指责受影响的项目,而是提供客观的概述,作为社区学习和更好地保护项目的教育材料。
- 原文链接: openzeppelin.com/news/th...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!