Panoptic 协议在8月25日发现一个严重漏洞,攻击者可以利用该漏洞从 PanopticPool 智能合约中盗取所有资金。
最近的安全事件之前和期间发生了什么,以及接下来会发生什么。
8 月 25 日,Cantina 的一位研究人员报告了 Panoptic 核心协议中的一个严重漏洞,该漏洞可能使攻击者能够通过欺骗仓位列表并绕过抵押品检查,从而耗尽 PanopticPool 智能合约中的所有资金。 在确认漏洞后,我们立即启动了 72 小时的紧急响应:通知用户提取资金,成功协调自愿提取超过 400 万美元,并在 8 月 28 日执行了白帽救援行动,从而保护了主网和 L2 上超过 98% 的剩余风险资金。
所有被救援的资金都已转移到 vault.panoptic.eth,并将通过 Merkle-root 声明系统全额返还给用户。没有用户资金损失。
8 月 25 日星期一,我们收到来自 Cantina 研究人员的报告,声称 Panoptic 核心协议中存在一个严重漏洞,该漏洞可能使任何人都能耗尽锁定在 PanopticPool 智能合约中的几乎所有资金。
Panoptic 团队立即在周一晚上花费了 4 个小时来测试 Cantina 报告中的说法。 Cantina 研究人员提供了一个硬编码的仓位 ID 欺骗列表(spoof),该列表似乎绕过了 PanopticPool 智能合约内部的检查。 为了测试我们是否可以使用新的仓位重现此攻击,我们编写了一个 Python 脚本来实现 欺骗 挖掘,依赖于 Bellare & Micciancio 的研究。 我们确认我们的 Python 脚本可以生成新的列表并执行新的攻击,并且研究人员的发现是有效的。
至此,我们已经确认该漏洞是真实存在的,并且用户的实时资金面临风险。 我们在周一晚上 10:30 与我们的 Cantina 事件响应团队以及 SEAL 911 合作,创建了作战室。 在接下来的 2 天里,我们采取了以下行动。
到周三中午,大多数用户资金已被提取,不再面临风险。 在那时,很明显下一步是尝试挽救仍然存在于 Panoptic 协议中的资金。
我们开始为每个市场设计白帽救援攻击。 我们将为每个 Panoptic 市场部署一个攻击者合约,该合约将 i) 使用闪电贷在 Panoptic 池中存入大量代币,ii) 借入最大数量的代币以开设 Panoptic 仓位,iii) 使用 欺骗 仓位列表提取借入的代币,以绕过抵押品要求,从而有效地耗尽每个市场中的所有资金。
在改进 Cantina 报告的概念验证以确保可以在一次操作中挽救每个市场的资金后,我们接下来按 TVL 对所有实时 Panoptic 市场进行排名,为每个市场挖掘 欺骗 列表,并测试每个市场的攻击者以确保:
所有攻击者开发都在一个开发人员的机器上隔离完成。 我们避免上传到 Github 或其他协作工具,以避免泄露攻击。 到周四下午,我们已经准备好所有攻击者脚本,并计划在当天结束前使用 forge 脚本广播每次攻击。
我们计划通过 mainnet Flashbots RPC 端点进行部署,以确保白帽攻击不会广播给其他构建者,并且如果事务在模拟中恢复,则不会广播该事务。
我们设法将 2 个 mainnet 攻击装入一个事务中,以挽救高达 38.3 万美元的 USDC、WETH 和 WBTC。 所有其他攻击都将通过每个事务一次攻击的方式执行。 大多数风险资金都在 mainnet 上,因此首要任务是首先执行该白帽攻击。
当我们最初尝试在 mainnet 上执行白帽攻击时,我们的 forge 脚本遇到了来自 Flashbots 的速率限制,因为该攻击需要比 Flashbots 的事务提交 API 允许的更多的状态读取。 我们联系了 Flashbots 团队,询问他们是否可以提高我们的速率限制,以适应执行 forge 脚本的初始计划。 他们非常乐于助人和响应迅速,使我们能够在联系后不久执行攻击。
在 Aug-28-2025 05:55:23 PM EDT 的区块 23242436,我们执行了 mainnet 白帽攻击:https://etherscan.io/tx/0x67a45dfe5ff4b190058674d7c791bbdc48e889f319f937c24fa13a5f9093f088
我们让整个 Panoptic 团队参加了一个实时的 Google 会议,确认攻击成功,监控攻击者合约中存在的资金以及市场 TVL 按预期下降。 我们确认 mainnet 白帽攻击成功,然后我们继续对最大的 Unichain 和 Base 市场进行白帽攻击。
由于超过 98% 的客户资金已经得到保护,团队可以大大松一口气了。 当晚晚些时候,我们返回对 L2 上的另外 5 个市场进行白帽攻击。 剩余市场的 TVL 足够小,可以直接从国库进行补偿,但我们也欢迎想要去检索这些资金的白帽攻击者。 所有白帽救援资金随后都转移到 vault.panoptic.eth。
更新:所有用户资金都已成功救出,可供重新分配。请 在此处 申领你的资金。
用户将能够在下周末之前申领被救出的资金,在我们设置好 Merkle-root 申领系统 之后。 我们将把所有被救出的代币转账到具有存储的 merkle 根的专用合约中,然后使用户能够从合约中申领回他们的代币。
我们将提供一个链下系统,用于为每个用户地址生成正确的 Merkle 证明,从而使每个用户都可以通过有权访问的代币证明来调用此专用合约,并接收其资金的转移。
我们将上传一个 CSV 文件到我们的 Github 页面,其中包含我们计算的每个帐户的可申领资金。 我们要求任何受影响的用户向 support@panoptic.xyz 发送电子邮件或在 Discord 上创建支持单,以解决有关你的重新分配配额的争议。 我们的目标是使每个人都 100% 完整,实物 - 我们不会将任何基础资产兑换为 USDC 或采取类似行动。
此外,我们还向 Cantina 记者确认,他们将获得最高的 250,000 美元,以表彰他们负责任地披露此漏洞。 我们非常感谢他们的研究,以及在此紧张时期我们收到的来自几个团队的实时帮助:
我们要感谢我们的社区的支持,以及我们的合作伙伴和审计师的尽职调查。 我们对导致此漏洞的 V1 中的设计决策承担全部责任。
防止此类攻击的保护措施将包括验证用户在与 PanopticPool 交互时实际上拥有他们声称拥有的仓位,而不是仅检查仓位列表指纹输出。 本着公开学习的精神,我们想分享我们从这次事件中吸取的更一般的教训:
尽早发现漏洞。 对于每个审计发现,你都需要花时间放慢速度并扩大每个报告发现的可能损害。我们收到了来自 2024 年 4 月 Code4rena 竞赛的两份报告,可能导致我们发现此问题 - 一份 描述了某人如何通过 欺骗 仓位列表来清算其他用户,而他们本身并不偿付能力,另一份 描述了用户如何在无力偿债的情况下继续铸造期权。两者都没有完全将 欺骗 方法放在一起,但两者都强调了 TokenId 在指纹识别过程中如何验证的弱点,以及完全检查 TokenId 列表的完整性的弱点。如果我们自己花时间尝试提出一种仓位列表 欺骗 方法,我们可能已经能够预见到这个漏洞。
做好执行完美恢复的准备。 执行白帽攻击的开发运营非常棘手。你可能认为你已做好准备 - 你之前已执行过协议部署甚至治理行动,并且可以推测使用相同的工具来执行你的白帽攻击。但是编写智能合约只是成功的一半:黑帽可能会发现你的白帽攻击的方式有很多种 - Github 窥探、受感染的开发机器、RPC 侦听、mempool 监视、恢复监视。作为安全准备工作的一部分,你必须有一个安全、经过测试的执行计划,该计划解决了隔离的开发环境、安全广播方法 (如 Flashbots) 以及跨多个链的协调。安全准备工作必须扩展到代码之外,以包括整个救援操作管道。
不要低估社区恢复的重要性。 虽然技术白帽操作保护了大部分资金,但我们快速联系用户并与之协调的能力避免了潜在的灾难。在 48 小时内,我们成功联系了控制超过 405 万美元存款的用户,社区成员、协议创始人和甚至我们的 Discord 版主都在追踪多重签名所有者方面发挥了重要作用。协议的安全性还在于维护准确的用户联系信息、建立强大的社区关系以及在危机发生之前准备好清晰的通信渠道。
始终使用可用的工具和方法。 我们选择推出我们自己的加密哈希聚合方案,而没有对现有方法进行适当的研究。我们建立了一种指纹识别方法,该方法依赖于将哈希值 异或 在一起 (XORing),从而实现无序的仓位列表并使更新仓位列表具有 gas 效率。此方法称为 XHASH。如果我们进行了适当的研究,我们就会知道 XHASH 的问题。更一般地说,Panoptic 团队的专业知识在于去中心化金融。我们应该专注于为期权交易协议开发最佳规则,并依靠密码学专家来提供我们需要的经过实战检验的安全原语。
以紧迫和清晰的方式进行沟通。 一些用户延迟采取保护措施,因为我们最初的消息没有充分传达情况的严重性。至少在一个案例中,用户认为“调查”一词意味着该漏洞尚未得到确认,因此坚持了一个仓位而不是立即采取行动。这说明了危机沟通消除犹豫的重要性:消息必须毫不怀疑问题的严重性、行动的紧迫性以及用户所需的准确步骤。
最后,关于 Panoptic 作为协议和产品的后续步骤的一些说明。 我们很快将重新推出 Panoptic V2,这是一个从根本上解决此漏洞的升级,同时还发布了计划中的强制执行机制、PLP 经济学和仓位管理灵活性的改进。 我们仍然致力于构建一个安全的期权协议,并将在未来几周内分享有关 V2 架构和我们增强的安全措施的更多详细信息。
请注意以下安全提示:
首先,我们必须了解 Panoptic 中如何表示仓位。
在 Panoptic 中,你持有的每个仓位都可以描述为打包的 uint256。
我们将存储 uint256 的 256 位分成几个部分。
在每个部分中,我们存储有关你的仓位的信息 - 我们在此处使用 8 位来存储一个 leg 的期权比率的 uint8 数字,在那里使用一位来表示它是看涨期权还是看跌期权,等等。
完整的架构可以在 TokenId.sol 中找到。
// TOKENID 的打包规则:
// 这是 token Id 如何打包到包含仓位信息的位组成部分中的。
// 位模式通常为:
//
// (第 3 个 leg 的行权价刻度)
// | (第 2 个 leg 的宽度)
// | |
// (8)(7)(6)(5)(4)(3)(2) (8)(7)(6)(5)(4)(3)(2) (8)(7)(6)(5)(4)(3)(2) (8)(7)(6)(5)(4)(3)(2) (1) (0)
// <---- 48 位 ----> <---- 48 位 ----> <---- 48 位 ----> <---- 48 位 ----> <- 16 位 -> <- 48 位 ->
// Leg 4 Leg 3 Leg 2 Leg 1 刻度间距 Uniswap 池模式
//
// <--- 最高有效位 最低有效位 --->
//
结果数字是一个唯一的仓位 ID,当解码时,它会告诉我们定义期权仓位所需的一切信息。
每个用户最多可以持有 25 个这样的仓位。 但是为了提高 gas 效率,我们不会直接将数字仓位 ID 列表存储在 Panoptic 智能合约中。 相反,我们:
这应该意味着,每当用户采取影响其帐户的清算能力或活动仓位列表的操作时,我们的合约都会准确地了解用户的未平仓仓位。
Panoptic v1(和 v1.1)中 Panoptic 仓位列表的指纹是使用以下代码 生成 的:
function updatePositionsHash(
uint256 existingHash,
TokenId tokenId,
bool addFlag
) internal pure returns (uint256) {
// 通过将现有哈希与新的 tokenId 进行异或来更新哈希
uint256 updatedHash = uint248(existingHash) ^
(uint248(uint256(keccak256(abi.encode(tokenId)))));
// 如果 addFlag=true,则递增高 8 位(leg 计数器),否则递减
uint256 newLegCount = addFlag
? uint8(existingHash >> 248) + uint8(tokenId.countLegs())
: uint8(existingHash >> 248) - tokenId.countLegs();
unchecked {
return uint256(updatedHash) + (newLegCount << 248);
}
}
该代码执行以下操作:
accumulatedFingerprint。accumulatedFingerprint 的高 8 位包含所有仓位的总 leg 数,而低 248 位存储每个仓位的 keccak 哈希的异或。这里有两个关键缺陷需要注意。
我们没有验证传递的仓位是有效的期权仓位,实际上可以由 Panoptic 铸造。具体来说,这些 uint256 的 leg 计数可以包含 0。
欺骗 仓位 ID 列表的挖掘实际上可以非常有效地完成,因为我们依赖于将哈希值 异或 在一起。

... 第一个向量 h_0 乘以系数 x_0,第二个向量 h_1 乘以系数 x_1,依此类推。
uint 并 keccak 它们。输入向量的数量也可以任意大,因为你只会选择其中的一个子集 - 即收到系数 1 的向量。因此,我们现在已经解决了寻找这些 欺骗 TokenId 列表的问题:
我们严重依赖 Bellare & Micciancio 的研究来了解将哈希输出 异或 在一起的这种不安全性。好奇的读者可能想研究一下 David Wagner 的 k-tree 算法 及其 开源实现,以获得更完整的通用生日问题描述。
我们将这种 欺骗 搜索实现为一个 Python 脚本,该脚本将发布 在此处。它是在紧要关头构建的,并且可以进行多个优化。但是,即使在低预算的笔记本电脑上,我们也能够找到任意真实仓位的 欺骗 列表,因为高斯消元法可以在多项式时间内执行,从而可以对所有池进行白帽攻击。
通过 欺骗 你持有的 PanopticPool 仓位的能力,你通常可以:
0 余额,并且导致该仓位没有抵押品要求。研究人员提供的一个有形的例子是一种执行以下步骤的攻击:
最终,这就是白帽攻击者合约所做的,使用链下生成的硬编码 欺骗 列表。
Mainnet EOA:https://etherscan.io/address/0xa1F0A9d51b592ee074eD6987006976908631503B
Base EOA:https://basescan.org/address/0xa1F0A9d51b592ee074eD6987006976908631503B
加入不断增长的 Panoptimist 社区,并通过在我们的 社交媒体平台 上关注我们,成为第一个听到我们最新更新的人。要了解更多关于 Panoptic 和所有关于 DeFi 期权的信息,请查看我们的 文档 并访问我们的 网站。
- 原文链接: panoptic.xyz/blog/positi...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!