Back to Blog

第6号Cork协议事件:两个独立漏洞组合形成的毁灭性攻击链

Code Auditing
February 11, 2026
8 min read

2025 年 5 月 28 日,以太坊上的 Cork Protocol 遭到攻击 [1],导致约 1200 万美元的损失。根本原因是历史隐含收益率平均值 (HIYA) 在到期时间方面的价格操纵,以及 Uniswap v4 hook 回调中缺失访问控制的组合。由于 HIYA 风险溢价会随着到期时间的临近而呈指数级增加,后期的交易推高了 HIYA,导致新初始化的市场严重低估了 Cover Token (CT) 的价格。与此同时,CorkHook.beforeSwap 缺少 msg.sender 身份验证,允许使用精心构造的参数进行任意调用。攻击者利用这两个漏洞,提取了约 3,760e18 个 CT 和 DS,并将它们兑换为 wstETH,耗尽了协议储备。

0x1 背景

0x1.1 代币经济学

Cork Protocol [2] 引入了一种代币化风险的新原语,作为链上资产(如金库代币、生息稳定币和流动性质押/再质押代币)的可编程风险层。其基础组件是 Cork Pool,它是围绕市场构建的机制。每个 Cork Pool 都围绕一对资产构建:赎回资产 (Redemption Asset, RA) 和 挂钩资产 (Pegged Asset, PA)。

Cork Pool 接收被锁定的赎回资产存款。作为回报,两种代币被铸造并返回给存款人:脱钩掉期 (Depeg Swap, DS) 和 覆盖代币 (Cover Token, CT)。在设定的到期日之前,1 DS + 1 CT/PA 可以换回 1 RA;到期后,1 CT 可以按比例赎回池中剩余的 RA + PA。

PA+DS=RAPA + DS = RA

CT+DS=RACT + DS = RA

0x1.2 合约实现

DS 和 CT 均可交易。用户可以通过 CorkHook 使用基于自定义 AMM 曲线的 NormalSwap 来交易 CT 和 RA,而 DS 和 RA 则通过 RouterCorkHook 使用 FlashSwap 进行交易。

NormalSwap [自定义 AMM 曲线]:

x1tyt=kx^{1-t} y^{t} = k

FlashSwap [FlashSwapRouter.swapDsforRa]:该机制是此次攻击的核心。攻击者随后通过直接、未经身份验证的调用 beforeSwap(第 0x2.2 节)触发了此路径。

  1. 买方将 RA 转移到 Router

  2. 在第一次 beforeSwap 调用中,Router 计算出需要换出的 DS 数量。如果需要,它会从 Uniswap v4 池中借入 RA 和 CT,将借入的 CT 和协议的 DS 转换为 RA,保留所需的 RA,并将借入的 RA 归还给 Uniswap 池。

  3. 在第二次 beforeSwap 调用中,Router 通过 depositPsm 将 RA 分解为 CT 和 DS,将所有 DS 转移给用户,偿还借入的 CT 给 Uniswap 池,并将多余的 CT 退还给买方。

发行后的资金分配:

RA+CT:AMMRA+CT: AMM

DS:RouterDS: Router

0x1.3 新发行的定价机制

该协议采用 HIYA(历史隐含收益率平均值),计算公式为成交量 (vTv_T) × 风险溢价 (rTr_T) 的累计总和,用于衡量风险溢价并在到期时调整初始化价格。如果 HIYA 较高,协议会假定脱钩风险较高,从而导致 CT 的初始定价较低。

累计 HIYA=TrTvT累计\ HIYA = \sum_T r_T v_T

风险溢价 (rTr_T) 的计算包含两个要素:高 CT 价格与低 rt 值相关(这是符合直觉的),并且到期时间 T 具有指数级放大效应。接近到期时,T 趋近于零,导致指数 1/T1/T 迅速增长。这会将即使很小的 CT 价格变化放大为巨大的风险溢价数值。

rT=(F/pT)1/T1r_T = (F / p_T)^{1/T} - 1

  • FF 为 1

  • PTP_T 为 CT 的价格

  • TT 为标准化在 1 到 0 之间的距到期时间

以放大效应为例:如果 CT 的交易价格 pT=0.95p_T = 0.95(5% 的折扣),则 T=0.5T = 0.5(到期前一半时间)时的风险溢价为:

r0.5=(1/0.95)1/0.51=(1.053)210.108r_{0.5} = (1/0.95)^{1/0.5} - 1 = (1.053)^{2} - 1 \approx 0.108

T=0.01T = 0.01 时(接近到期),相同的 CT 价格产生:

r0.01=(1/0.95)1/0.011=(1.053)1001167r_{0.01} = (1/0.95)^{1/0.01} - 1 = (1.053)^{100} - 1 \approx 167

相同的 5% CT 折扣在接近到期时产生了约 1500 倍的风险溢价。这种指数级的敏感性正是操纵向量:在到期前不久执行的交换会不成比例地推高 HIYA,从而扭曲下一个市场的初始化价格。

0x2 漏洞分析

受影响的市场涉及以下代币:

角色 代币 描述
RA wstETH 赎回资产
PA weETH 挂钩资产
DS weETH8DS-2 脱钩掉期
CT weETH8CT-2 覆盖代币

为清楚起见,本报告剩余部分将根据代币的角色(RA、DS、CT)指代它们,而非常用名称,除非需要区分。

攻击者使用两种不同的方法从 AMM 和 Router 中提取了 DS 和 CT。由于 DS + CT 可以赎回为 RA,获取两者意味着可以直接提取利润。此次攻击包含两个组成部分。

0x2.1 覆盖代币提取:HIYA 操纵导致人为压低的市场初始化价格

当一个市场期限到期时,协议会使用上一期限的 accumulatedHIYA 来设置 AMM 中 CT/RA 的价格比率。较高的 HIYA 表示感知的脱钩风险较高,这会转化为较低的初始 CT 价格。

由于 HIYA 在每次掉期时都会更新并包含风险溢价(第 0x1.3 节),且风险溢价随着 T0T \to 0 呈指数级增长,在到期前不久执行的交换会将 accumulatedHIYA 放大几个数量级。攻击者通过在到期前调用 SwapRaForDs() 利用了这一点,产生了累积到 HIYA 中的巨大风险溢价。

当随后初始化新的市场期限时,协议读取了被夸大的 HIYA,将其解读为极端的脱钩风险,并将 CT 的初始 AMM 价格设置得远低于其公允价值。攻击者随后以这种扭曲的价格用 RA 交换 CT,廉价获得了大量的 CT 头寸。

0x2.2 脱钩掉期提取:CorkHook.beforeSwap 中缺失访问控制

在标准的 Uniswap v4 hook 设计中,beforeSwap 仅由 PoolManager 在掉期期间调用。Cork 的实现没有强制执行此约束:

// 缺失:require(msg.sender == address(poolManager));
function beforeSwap(
    address sender,
    PoolKey calldata key,
    IPoolManager.SwapParams calldata params,
    bytes calldata hookData
) external override returns (bytes4, BeforeSwapDelta, uint24) {
    ...
}

没有此检查,任何外部合约都可以直接使用任意 hookData 调用 beforeSwap。当 hookData 不为空时,该函数会进入 FlashSwap 执行路径(第 0x1.2 节),该路径通过 depositPsm 将 RA 分解为 CT 和 DS。攻击者通过使用指定的伪造市场代币的精心构造的 hookData 直接调用 beforeSwap 来利用这一点,导致协议分解代币并将结果转移给攻击者。

0x2.3 两个漏洞的组合方式

单一漏洞都无法单独提取完整的 1200 万美元。

HIYA 操纵使攻击者获得了廉价的 CT,但仅靠 CT 无法赎回 RA。赎回公式需要两种代币:CT + DS = RA。攻击者仍然需要一种获得 DS 的方法。

beforeSwap 中缺失的访问控制提供了该路径。通过使用精心构造的 hookData 直接调用 beforeSwap,攻击者可以使用任意参数触发 FlashSwap 分解路径。为了通过此路径获得真实的 DS,攻击者部署了一个伪造市场,将真实的 DS 指定为它的 RA,然后调用 beforeSwap 将该“RA”(真实 DS)分解为伪造的 CT 和伪造的 DS,这些代币可以通过伪造市场换回真实的 DS。

同时持有 CT(来自 HIYA 操纵)和 DS(来自通过伪造市场进行的未授权 beforeSwap 调用)后,攻击者按 1:1 将其赎回为 RA (wstETH)。

0x3 攻击分析

攻击分为三个交易步骤,每个步骤对应一个阶段:推高 HIYA、获取廉价 CT,以及提取 DS 以完成赎回对。

0x3.1 准备:推高 HIYA

这笔交易中,攻击者在市场到期前不久调用了 SwapRaForDs()。由于 TT 接近于零,此操作产生了不成比例的巨大风险溢价(第 0x1.3 节),推高了 accumulatedHIYA

此阶段后攻击者持有: 来自掉期的 DS(稍后在 0x3.3 阶段使用),以及链上存储的被推高的 accumulatedHIYA

0x3.2 初始化:获取廉价 CT

这笔交易中,新市场期限被初始化。协议读取了被推高的 accumulatedHIYA 并设置了 AMM 中扭曲的 CT/RA 价格比率,将 CT 的价格定得远低于公允价值。攻击者随后以这种贬值的价格用约 0.000003e18 RA 换取了 3,760e18 CT。

此阶段后攻击者持有: 大量的 CT 头寸(通过被操纵的初始化价格廉价获得)。

0x3.3 提取:通过伪造市场获得 DS

此阶段使用访问控制漏洞(第 0x2.2 节)来提取 DS,从而完成 RA 赎回所需的 CT + DS 对。核心技术是一个将真实 DS 当作其赎回资产的伪造市场:

伪造市场角色 实际代币 目的
伪造 RA 真实 DS (weETH8DS-2) 允许真实 DS 进入分解路径
伪造 CT 从伪造 RA 分解中铸造 中间体;换回真实 DS
伪造 DS 从伪造 RA 分解中铸造 中间体;换回真实 DS

攻击交易的关键步骤:

  1. 攻击者首先在合法市场中将 RA 换为 DS。

    攻击者持有: 真实 DS。

  2. 攻击者部署并初始化了伪造市场,将真实 DS 指定为伪造 RA。

  3. 攻击者直接调用 beforeSwap(利用缺失的访问控制),并传入非空的 hookData,触发了针对伪造市场的 FlashSwap 执行路径。在 hookData 中,攻击者指定 paymentToken 为伪造 CT,导致协议针对伪造市场执行 RA 分解逻辑。

  4. 协议将所有伪造 RA(即真实 DS)分解为伪造 CT 和伪造 DS。全部伪造 DS 部分被转移给攻击者,伪造 CT 部分(减去最少的 paymentAmount)被退回。

    攻击者持有: 3,761e18 伪造 CT + 3,761e18 伪造 DS(均衍生自真实 DS)。

  5. 攻击者将伪造 CT 和伪造 DS 在伪造市场中换回伪造 RA,从而恢复了真实的 DS。

    攻击者持有: 3,761e18 真实 DS(已恢复)。

  6. 攻击者将恢复的 DS 与第 0x3.2 节中获得的 CT 组合,赎回 RA (wstETH),完成了利润提取。

    攻击者持有: 3,760e18 RA (wstETH) 利润(即 1200 万美元)。

总结

此事件结合了两个独立的缺陷,单从一方面来看都不足以实施此次攻击。攻击者通过利用这两个缺陷形成的单链攻击,从协议中抽走了 1200 万美元。

  • 到期前接近指数级增长的风险溢价。HIYA 定价公式随着距到期时间趋近于零而放大风险溢价,使后期交易成为操纵市场重新初始化价格的向量。
  • Hook 回调中缺失的发送者验证CorkHook.beforeSwap 没有强制要求 msg.senderPoolManager,这允许使用任意参数直接调用,使攻击者能够欺骗 FlashSwap 执行路径。
  • 跨模块交互形成的盲点。经济设计(基于 HIYA 的定价)和访问控制差距(未经身份验证的 hook 回调)位于不同的模块中。它们的交互产生了一个单模块分析难以发现的可利用路径。

参考

  1. https://www.cork.tech/blog/post-mortem

  2. https://docs.cork.tech/core-concepts/cork-pool


关于 BlockSec

BlockSec 是一家全栈区块链安全和加密合规服务提供商。我们构建的产品和服务可帮助客户在协议和平台的整个生命周期内进行代码审计(包括智能合约、区块链和钱包)、实时拦截攻击、分析安全事件、追踪非法资金并满足 AML/CFT(反洗钱/反恐怖融资)法规要求。

BlockSec 已在顶级会议上发表多篇区块链安全论文,报告了多个 DeFi 应用的零日攻击,阻止了多次黑客攻击并挽回了超过 2000 万美元的资产,保护了价值数十亿美元的加密资产。

Sign up for the latest updates

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit