看到“攻击者通过预言机虚假价格抽走金库”这样的新闻,普通人的第一反应通常是:他是不是随便拿一个钱包,伪造一笔交易,就让平台相信价格涨了十倍?
答案是否定的。普通钱包只能证明“这笔链上交易是我发的”,不能让自己变成平台认可的价格发布者。Ostium 事件真正值得关注的地方,是协议认可的预言机签名能力被盗用或滥用后,合约缺少足够的第二道防线,让“带有真签名的假数据”变成了可以从金库结算的真实利润。
截至 2026 年 7 月 20 日,Ostium 尚未公开完整的官方复盘。公开资料能够确认授权签名被用于异常价格报告,但还不能确认究竟是私钥泄露、签名服务遭入侵、接口权限缺失,还是其他特权链路被控制。
预言机不是预测未来,而是区块链的“报信员”
智能合约不能像普通程序一样随意访问新闻网站、交易所或股票行情接口。它只认识链上的交易和状态,因此无法自行判断黄金、股票或比特币现在多少钱。
预言机的工作,就是把这些链外信息带进区块链:
交易所、股票市场等外部数据
↓
预言机采集并整理
↓
授权 signer 用私钥签名
↓
智能合约验证签名
↓
按照报告价格开仓、平仓或结算
可以把智能合约想成一个不能上网的保险柜。预言机站在外面观察行情,把“现在黄金是 2400 美元”写在纸上盖章,再交给保险柜。保险柜不认识外面的市场,只能根据预先写好的规则判断公章是否有效。
这里很容易混淆两个概念:
签名真实:确实由协议授权的地址签署
数据真实:报告内容确实符合外部市场行情
密码学签名主要解决第一件事,并不会自动解决第二件事。
假价格怎样变成真 USDC
Ostium 是永续合约交易平台,流动性金库会承担一部分交易对手风险。用户盈利时,协议需要按照内部认可的价格计算盈亏并付款。
如果攻击者已经能够获得授权预言机对虚假数据的有效签名,概念上的过程就会变成:
- 攻击者建立一个交易仓位。
- 协议按照预言机报告记录开仓或结算价格。
- 被滥用的签名能力提交远离真实市场的价格。
- 合约验证出“签名者确实在授权名单里”,于是接受报告。
- 攻击者平仓,协议计算出并不存在的巨大账面盈利。
- 流动性金库按照合约逻辑支付真实 USDC。
例如,真实市场可能只从 100 涨到 101,但协议内部如果错误地接受了 1000 的价格,就可能按“100 买入、1000 卖出”计算盈利。攻击者没有真的把整个市场推高十倍,只是让这个协议自己的账本相信价格涨了十倍。
这也解释了为什么此类事件会出现循环开平仓:如果虚假报告能够覆盖多次订单,而协议又没有单次利润上限、异常价格熔断或资金流速限制,虚假账面利润就可能被反复兑换成金库里的真实资产。
普通钱包为什么不能直接做到
钱包私钥和预言机 signer 私钥承担的是不同职责:
普通钱包私钥:证明交易是谁发的、由谁支付 Gas
预言机 signer 私钥:证明价格报告来自协议认可的数据发布者
在相关合约中,调用者首先要经过 forwarder 权限检查,报告还要通过授权 signer 检查。普通用户即使知道函数名、参数格式和完整 calldata,也不能随意指定链上的 msg.sender,更不能让自己的签名恢复成另一个授权地址。
所以,复制公开交易或自己填写一个“价格涨十倍”的参数,通常只会让交易回滚。除非协议还存在权限注册错误、签名绕过、公开可滥用的签名接口、可重放报告或治理权限失控等额外问题,否则普通钱包无法凭空获得这项能力。
实际部署代码漏掉了哪道检查
安全机构指向的 OstiumPrivatePriceUpKeep 实际部署实现,主要检查了资产标识、订单是否过旧,以及报告时间是否早于订单:
if (
expectedFeedId != reportFeedId
|| block.timestamp > order.timestamp + maxOrderAgeSeconds
|| timestamp < order.timestamp
) {
revert InvalidPrice(orderId);
}
这段判断没有限制报告时间不能明显晚于当前区块时间,例如缺少类似下面的未来时间上限:
timestamp <= block.timestamp + allowedClockSkew
相关 OstiumVerifier 则主要负责恢复签名地址、查询它是否位于授权名单中,然后原样返回报告数据。报告中包含 feedId、时间戳、价格、买卖价和市场状态,但验证器没有负责判断价格是否偏离独立市场数据,也没有把报告绑定到具体 orderId、用途和一次性 nonce。
因此,一份带有授权签名的未来时间报告可能获得比预期更大的可使用窗口。这里的问题并不是椭圆曲线签名算法被破解,而是协议把“授权身份”承担的信任范围放得太大。
GitHub 代码和链上代码还不一样
Ostium 的公开 GitHub 快照使用了更严格的条件:
order.timestamp != timestamp
也就是报告时间必须与订单时间完全相等。但安全机构指向的实际部署合约使用的是 timestamp < order.timestamp,只拒绝早于订单的报告,没有拒绝未来报告。
这是一条很重要的开发者经验:审计线上协议时,GitHub 仓库只是参考,真正控制资金的是链上部署的字节码和与之匹配的验证源码。
不过,即使恢复成时间完全相等,也不能单独解决授权 signer 可以签署任意价格的问题。时间校验只能缩小重放窗口,价格真实性仍需要独立验证。
损失数字为什么有多个版本
截至本文核验时,各安全机构给出的数字并不一致:Blockaid 提到约 1800 万 USDC 支付,SlowMist 统计约 1186 万 USDC,Cyvers 估算约 2370 万美元,PeckShield 则提到约 2400 万美元。
不同数字可能来自不同地址范围、观察窗口和毛损失或净损失口径。在 Ostium 公布最终复盘前,不应该把任何一个第三方数字写成已经确认的最终损失。同样,“预言机私钥被盗”目前也是安全机构的判断之一,不是已经完成官方取证的结论。
更安全的设计应该怎样做
预言机系统不能只依赖“一个地址签名正确”。至少还应考虑:
- 使用多 signer 阈值签名,避免单个密钥决定全部价格;
- 把签名绑定到链 ID、合约地址、资产、订单 ID、操作用途和 nonce;
- 同时检查报告不能过旧,也不能明显来自未来;
- 限制同一报告或 nonce 只能消费一次;
- 与独立价格源比较偏差,出现异常跳价时拒绝结算;
- 设置单笔、单区块和单账户的盈利与赔付上限;
- 监控未来时间报告、相同报告重复使用和短时间循环开平仓;
- 提供 signer、forwarder 快速撤销和自动暂停机制;
- 持续核对公开源码、编译产物和实际部署字节码是否一致。
Chainlink 的官方文档也特别提醒:链上签名验证能够确认报告的来源和完整性,但应用合约仍然负责判断这些数据是否适合用于具体交易。本次公开分析指向的是 Ostium 自定义的私有预言机路径,不应简单表述成“Chainlink 被攻破”。
最后总结
Ostium 事件可以浓缩成一句话:
预言机权限失控
+ 合约过度相信单一签名
+ 时间、价格和赔付风控不足
= 虚假账面利润被兑换成真实 USDC
对于普通用户,最重要的理解是:攻击者不是用自己的普通钱包随便写了一个价格,而是获得或滥用了协议认可的特殊签名能力。对于开发者,更重要的教训则是——签名只能证明“谁说的”,不能证明“他说的一定是真的”。
公开资料与链上入口
- Blockaid 事件预警
- Ostium 联合创始人公开说明
- SlowMist 分析
- Cyvers 预警
- PeckShield 资金追踪
- Arbitrum 核心交易
- OstiumPrivatePriceUpKeep 链上验证源码
- OstiumVerifier 链上验证源码
- Ostium 智能合约公开仓库
- Chainlink 链上报告验证文档
本文资料核验于 2026 年 7 月 20 日。事件仍可能出现新的官方复盘、损失统计和修复信息,后续应以 Ostium 官方披露及链上记录为准。




