在过去一周(2026/04/06 - 2026/04/12),BlockSec 检测并分析了四起攻击事件,估计总损失约为 92.86 万美元。下表总结了这些事件,详细分析将在后续小节中提供。
| 日期 | 事件 | 类型 | 估计损失 |
|---|---|---|---|
| 2026/04/05* | Denaria 事件 | 四舍五入不对称 & 不安全类型转换 |
~$16.56 万 |
| 2026/04/07 | HB Token 事件 | 业务逻辑漏洞 & 价格操纵 |
~$19.3 万 |
| 2026/04/07 | Squid Multicall 事件 | 任意调用 | ~$51.7 万 |
| 2026/04/11 | XBIT 事件 | 访问控制问题 | ~$5.3 万 |
*Denaria 事件未包含在上周报告中,在此为完整性加入。
Web3 最佳安全审计商
上线前验证设计、代码和业务逻辑
从本周开始,我们将在每份报告的开头突出显示一个事件。选择并非一定基于损失金额 — 也可能因为其新颖的协议设计、巧妙的攻击技术或为社区提供的更广泛教训。
本周焦点:Denaria 事件
永续 DEX Denaria 引入了基于复杂代码逻辑的新型会计机制。然而,审计后重构引入了四舍五入不对称性,可能产生一个细微的边缘情况,即负值,最终触发不安全类型转换并导致天文数字的价值提取。
2026 年 4 月 5 日,Denaria 在 Linea 上的永续 DEX 被利用,导致约 16.56 万美元损失。根本原因是 getLpLiquidityBalance() 中两个叠加的漏洞:审计后重构的 LP 余额会计引入了四舍五入不对称性,可能产生一个略微为负的中间值,以及一个不安全 int256 到 uint256 的类型转换,该转换并未回滚而是将负值静默地包装成接近最大值的无符号整数。攻击者通过单边 LP 存款和多头交易利用了这一点,然后从金库中提取了人为膨胀的盈亏。
背景
Denaria 是 Linea 上基于动态虚拟 AMM 的永续 DEX。它将交易和结算分为两个部分。PerpPair 市场管理用户头寸和 LP 会计,而 Vault 持有抵押品并结算已实现盈亏。
PerpPair 中的 LP 所有权不通过显式代币余额表示。相反,协议从包含两个簿记组件的内部会计矩阵中重建每个 LP 的状态,此处称为资产方和稳定币方。资产方跟踪 LP 在池子对价格变动的敞口份额,而稳定币方跟踪其在池子稳定币计价价值中的份额。这两个组件共同决定 LP 价值如何被跟踪和结算。
关键是,这些组件不以静态快照形式存储。每次发生交易,PerpPair 都会更新其全局流动性状态,并且每个 LP 的重建余额 derived from 累积全局值与 LP 的入点快照之间的差值。此会计机制是在审计后重构中引入的,该重构用直接余额跟踪取代了原始的基于份额的累加器。然而,重构后的减法路径引入了四舍五入不对称性,可能导致在特定交易序列下重建的 LP 组件变为略微为负。
漏洞分析
易受攻击的 PerpPair 合约(0xb683...36ae17)包含两个叠加的漏洞。
- 重构会计中的四舍五入不对称性。 引入直接余额跟踪的审计后重构在减法重建路径中产生了四舍五入不对称性。在特定交易序列下,四舍五入后的全局累积值可能略小于 LP 的入点快照,导致减法产生一个小的负结果而不是零。理论上,这个值应该是零或接近零;不对称性是该重构实现特有的漏洞,而不是减法会计本身的固有属性。

- 不安全有符号到无符号类型转换。 在
getLpLiquidityBalance()中,一个重建的 LP 余额组件在没有验证的情况下从int256转换为uint256。在 Solidity 中,将负的int256转换为uint256不会回滚;它会根据 2^256 取模包装该值,将 -1 这样的小负数变成接近最大值的无符号整数 (2^256 - 1)。由于此重建余额被用于calcPnL()进行结算,任何负输入都将被解释为巨额 LP 头寸,允许攻击者实现人为膨胀的利润并耗尽金库资金。


单独一个漏洞都不会被利用。四舍五入不对称性只产生一个微小的负值,在正常的 int256 算术中,这只会代表一个微不足道的误差。但一旦该负值到达未受保护的类型转换,它就包装成一个接近最大值的无符号整数。后续的边界检查随后将包装后的值限制在池子的总资产方流动性,有效地将溢出转化为对整个市场资产方的声明。
攻击分析
以下分析基于攻击交易 0xcb0744...0c606447。
-
步骤 1:攻击者通过 Aave 闪贷借入了
60,000USDC。 -
步骤 2:一个助手地址存入了
30,000USDC作为抵押品,并添加了一个仅限稳定币的19,980稳定币的 LP 头寸。仅在稳定币方进行存款,助手确保其资产方 LP 组件接近零,使其更容易进入负值区域。 -
步骤 3:第二个助手地址存入了
15,000USDC并开立了一个100,000名义上的多头头寸,导致liquidityM更新,引入了关键的四舍五入错误。相对于池子流动性的巨额名义头寸放大了每笔交易的四舍五入影响,将第一个助手的重建资产方余额略微降至零以下。 -
步骤 4:第一个助手随后调用了
realizePnL()。在 LP 余额重建过程中,负的lpAssetBalance被包装成接近最大的uint256。然后,该大数值被限制在市场全部资产方流动性,并产生了极度膨胀的利润。实际上,协议认为 LP 拥有整个市场的资产方。 -
步骤 5:攻击者从金库中提取了膨胀的盈亏。

相同的模式重复进行,直到耗尽剩余的金库流动性。偿还闪贷后,攻击者实现了约 16.56 万美元的利润。
结论
此次利用归根结底是由于在有符号到无符号转换中缺少边界验证。直接的修复很简单:将裸露的类型转换替换为 SafeCast.toUint256(),该函数在输入为负时会回滚而不是包装。
更广泛地说,此次事件说明了审计后重构绕过外部审查的风险。根据官方事后分析,四舍五入不对称性是在最终外部审计后引入的,当时团队用直接余额跟踪替换了原始累加器。虽然重构解决了溢出问题,但它创建了一个新的边缘情况,内部测试未能捕获。当协议重构核心会计逻辑时,新代码路径应被视为安全关键,并重新审计,特别是当重建的值直接用于盈亏结算或提款逻辑时。
HB Token 事件
2026 年 4 月 7 日,HB,一个在 BNB Chain 上带有嵌入式买卖钩的定制 ERC-20 代币,被利用,损失约 19.3 万美元。根本原因是奖励结算逻辑的缺陷:触发时,它调用 swapBack(),该函数直接从 PancakeSwap 对中移除 HB 储备,然后调用 sync() 来重新定价池子。攻击者买走对中大部分 HB 后,随后的 swapBack() 执行进一步减少了剩余的流动性并急剧抬高了现货价格。攻击者随后以不成比例的 USDT 金额出售了极少量的 HB 到扭曲的池子中,重复此循环直到池子被耗尽。
背景
HB 是 BNB Chain 上一个定制的 ERC-20 代币,在 _transfer() 中嵌入了买入和卖出钩。当用户从 AMM 对购买时,_handleBuy() 记录成本基础信息。当用户卖出时,_handleSell() 根据对的状态分支到不同的税费和结算路径。
该代币还包含一个奖励结算机制,可以触发 swapBack()。swapBack() 不执行常规的路由器中介交换,而是直接将 HB 从 PancakeSwap 对转移到 PROOF 地址,然后强制对通过 sync() 同步。这允许合约在常规 AMM 交易流程之外收缩对的 HB 储备并立即向上重新定价池子。
漏洞分析
HB 代币合约(0x62ce...87a4b0)的核心漏洞在于 swapBack() 是通过直接从 AMM 对获取奖励,而不是从金库或通过路由器中介交换。由于 swapBack() 可以通过奖励结算路径访问,非交易代码路径可以直接修改对的储备并改变现货价格。

当对的 HB 储备较低时,调用 swapBack() 会进一步减少剩余的 HB 并放大价格扭曲,使得有可能以极高的价格出售极少量的 HB。
攻击分析
以下分析基于攻击交易 0x19671f...d71594ed。
-
步骤 1:攻击者从 Venus 借入大量资金。
-
步骤 2:攻击者将约
1,496HB转入代币合约,增加了合约的HB余额,以便后续的swapBack()可以从对中提取更多金额。 -
步骤 3:通过向 PancakeSwap 对转移极少量的
HB,攻击者触发了_swapAndLiquify(),该函数将代币合约持有的约4,163HB兑换为10USDT,并增加了攻击者可领取的HB奖励。

- 步骤 4:然后,攻击者花费
72,117,360USDT购买了73,608,753HB,使对几乎没有剩余的HB流动性。

- 步骤 5:接下来,攻击者触发了奖励不足路径。为了满足奖励,代币调用了
swapBack(),该函数从 PancakeSwap 对中提取了额外的HB并强制执行sync(),急剧提高了HB价格。

- 步骤 6:攻击者直接将
USDT转入对以补充其USDT储备,然后以扭曲的价格仅用0.000582HB兑换了37,582,322USDT。
通过重复步骤 6 以扭曲的价格卖出 HB 代币,攻击者提取了池中几乎所有的 USDT。
结论
HB 代币事件说明了允许奖励逻辑直接修改 AMM 储备是多么危险。影响储备的函数永远不应能从奖励结算路径访问,协议应避免在安全敏感的控制流中混淆内部代币余额与 AMM 储备会计。任何依赖在内部扰动池子后进行现货 AMM 定价的设计都容易受到价格操纵。
Squid Multicall 事件
2026 年 4 月 7 日,一位 Squid 用户 在多个链上因与授权相关的事件损失了约 51.7 万美元。用户误将 SquidMulticall 合约授权给了预期中的 Squid Router。这允许攻击者调用无权限的 SquidMulticall.run() 函数来执行任意外部调用。攻击者因此可以使用对该合约授权的任何额度,执行针对已授权用户的代币 transferFrom() 调用。
背景
在 Squid 的正常流程中,用户应授权 Squid Router,而 SquidMulticall 仅作为执行助手。该助手合约设计用于执行路由逻辑的一部分批量调用,但不应是用户直接授权代币转账的支出方。
由于 ERC-20 额度检查仅针对支出方地址执行,任何结合了用户授权和无限制任意调用能力的合约都会成为危险的授权接收器:一旦授权,该合约就可以成为通用的代币提现向量,如果任何人都能控制它执行的调用。
漏洞分析
此次事件并非由智能合约漏洞引起。损失是由于两个条件的共同作用:一个错误的授权目标是 SquidMulticall 而不是 Router,以及 run() 的无权限设计接受来自任何调用者的任意目标和 calldata。
SquidMulticall 的目的是作为 Router 流程的下游步骤执行批量调用,其中输入由可信的路由逻辑构建。按预期使用时,无权限设计不会带来风险。但错误的授权彻底改变了这一点:一个 MEV 机器人检测到了活动的额度,调用了 run() 并使用了精心构造的 calldata 调用 transferFrom(受害者, 攻击者, 金额),并在每个链上耗尽了授权的代币,而无需受害者采取任何进一步行动。

攻击分析
该事件影响了BNB Chain、Arbitrum、Optimism、Avalanche 和 Base上的用户。以下分析基于攻击交易 0x81d0c4...9b1301e9。
-
步骤 1:受害者(0xacc0...f40e98)错误地授权了
SquidMulticall而不是预期的 Squid Router。 -
步骤 2:一个 MEV 机器人检测到此额度,并使用精心构造的 calldata 调用了
SquidMulticall.run()。 -
步骤 3:通过任意调用,
SquidMulticall调用了transferFrom(受害者, 攻击者, 金额)并将授权的资产从受害者的钱包中转移出来。

结论
此次事件说明了无权限的任意调用合约与面向用户的授权流程并存的风险。直接原因是错误的授权,并且由于 SquidMulticall 接受无限制的调用者、任意目标和任意 calldata,因此任何错误地指向它的授权都立即被完全利用。使用执行助手合约的协议应考虑添加调用者限制或约束这些函数允许的调用目标,以便错误的授权无法被轻易武器化。
XBIT 事件
2026 年 4 月 11 日,BNB Chain 上的 XBIT 代币被利用,损失约 5.3 万美元。根本原因是 XBITVault 中的一个开放式访问控制漏洞:transfer() 函数的授权检查是条件性的 — 仅当 xbitContract 非零时才强制执行 msg.sender == xbitContract,否则静默通过。由于从未调用 bindXBIT() 来初始化合约,因此该漏洞永久暴露,允许任意调用者从任何地址转移 XBIT 余额,包括 XBIT/USDT PancakeSwap 对。攻击者利用这一点耗尽了对中的 XBIT,然后反复将极少量的 XBIT 卖回池子以换取不成比例的大量 USDT。
背景
XBITVault 不是一个被动的金库合约。它是 XBIT 代币系统的余额和额度后端,公开了 transfer()、approve() 和 mintForXBIT() 等代币类函数。在预期设计下,所有者必须首先调用 bindXBIT() 来通过设置 xbitContract、pancakePair、pairContract 和 xbitDecimals 来初始化金库。初始化后,敏感的状态更改函数应仅由绑定的 XBIT 合约调用。换句话说,金库的安全模型依赖于在公开使用前的成功初始化。
漏洞分析
关键漏洞在于易受攻击的 XBITVault 合约(0xc879...42391a)中的条件性访问控制。transfer() 函数仅在 xbitContract != address(0) 时检查 msg.sender == xbitContract。这意味着当 xbitContract 未设置时,函数不会回滚,而是可以被任何人公开调用。由于余额存储在 _balances 中,只要源地址有足够余额,任何外部调用者都可以将 XBIT 从任何地址移动到任何其他地址。

预期的初始化路径是 bindXBIT(),但由于从未调用,金库一直处于未初始化且开放失败的状态。结果有效地提供了一个不受限制的任意余额转移原语。

攻击分析
以下分析基于攻击交易 0xbc877f...4df1b694。
-
步骤 1:通过不受限制的
transfer()函数,攻击者从XBIT/USDT对中转移了1,526,216.569XBIT,而未提供任何相应的USDT。 -
步骤 2:攻击者调用
sync()将对的XBIT储备压缩至仅 1-2 个单位。 -
步骤 3:在对几乎没有
XBIT流动性后,攻击者反复出售XBIT,从对中耗尽了约53,112USDT。

结论
此次事件是由于一个依赖初始化的访问控制检查以开放式失败方式运作。当 xbitContract 未设置时,transfer() 是不受限制的,由于从未调用 bindXBIT(),金库永久暴露了一个公开的任意余额转移原语。特权函数在初始化完成后应回滚,部署时绑定步骤应是链上强制的前提条件,而不是操作假设。
关于 BlockSec
BlockSec 是一个全栈区块链安全和加密合规提供商。我们构建产品和服务,帮助客户在协议和平台的整个生命周期中执行代码审计(包括智能合约、区块链和钱包)、实时拦截攻击、分析事件、追踪非法资金,并满足 AML/CFT 义务。
BlockSec 在顶级会议上发表了多篇区块链安全论文,报告了多个 DeFi 应用的零日攻击,阻止了多次黑客攻击营救了超过 2000 万美元,并保障了数十亿美元的加密货币。
-
官方 Twitter 账号:https://twitter.com/BlockSecTeam
-
🔗 BlockSec 审计服务 : 提交请求



