#6 Cork Protocol Incident: Two Independent Flaws Combine into One Devastating Exploit Chain

#6 Cork Protocol Incident: Two Independent Flaws Combine into One Devastating Exploit Chain

On May 28, 2025, the Cork Protocol on Ethereum was exploited [1], resulting in approximately $12 million in losses. The root cause was a combination of expiration-time Historical Implied Yield Average (HIYA) price manipulation and missing access control in a Uniswap v4 hook callback. Because HIYA risk premiums increase exponentially as time to maturity approaches zero, late-stage swaps inflated HIYA and caused newly initialized markets to severely underprice Cover Tokens. At the same time, CorkHook.beforeSwap lacked msg.sender authentication, allowing arbitrary calls with crafted parameters. By exploiting both flaws, the attacker extra ~3,760e18 CT and DS and redeemed them for wstETH, draining protocol reserves.

0x1 Background

0x1.1 Tokenomics

Cork Protocol [2] introduces a new primitive for tokenized risk, serving as a programmable risk layer for onchain assets such as vault tokens, yield-bearing stablecoins, and liquid (re)staking tokens. The foundational component is the Cork Pool, which is the mechanism around which markets are built. Each Cork Pool is built around an asset pair: Redemption Asset(RA) and Pegged Asset (PA).

The Cork Pool receives deposits of Redemption Asset, which is locked. In return, two tokens are minted and returned to the depositor: Depeg Swap (DS) and Cover Token (CT). Before the set expiration date, 1 DS + 1 CT/PA can be swapped back for 1 RA; after expiration, 1 CT can be redeemed proportionally for the remaining RA + PA in the pool.

PA+DS=RAPA + DS = RA

CT+DS=RACT + DS = RA

0x1.2 Contract Implementation

Both DS and CT are tradeable. Users can trade CT and RA using NormalSwap based on a custom AMM curve through CorkHook, while DS and RA are traded using FlashSwap via Router and CorkHook.

NormalSwap [Custom AMM curve]:

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

FlashSwap [FlashSwapRouter.swapDsforRa]: This mechanism is central to the exploit. The attacker later triggers this path through a direct, unauthenticated call to beforeSwap (Section 0x2.2).

  1. The buyer transfers RA to the Router.

  2. In the first beforeSwap call, the Router computes the DS amount to be swapped out. If needed, it borrows RA and CT from the Uniswap v4 pool, converts the borrowed CT and the protocol's DS into RA, keeps the required RA, and returns the borrowed RA to the Uniswap pool.

  3. In the second beforeSwap call, the Router decomposes RA into CT and DS via depositPsm, transfers all DS to the user, repays the borrowed CT to the Uniswap pool, and refunds any excess CT to the buyer.

Fund Distribution After Issuance:

RA+CT:AMMRA+CT: AMM

DS:RouterDS: Router

0x1.3 Pricing Mechanism for New Issuance

The protocol employs HIYA (Historical Implied Yield Average), calculated as the cumulative sum of volume (vTv_T) × risk premium (rTr_T), which serves to measure risk premiums and adjust initialization prices upon expiration. If HIYA is high, the protocol assumes higher depeg risk, resulting in lower initial CT pricing.

Cumulative HIYA=TrTvTCumulative\ HIYA = \sum_T r_T v_T

The risk premium (rTr_T) calculation consists of two components: high CT prices correlate with low rt values (which is intuitive), and the expiration time T has an exponential amplification effect. Near expiration, T approaches zero, causing the exponent 1/T1/T to grow rapidly. This amplifies even small CT price changes into large risk premium values.

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

  • FF is 1

  • PTP_T is the price of CT

  • TT is the time to maturity normalized between 1-0

To illustrate the amplification: if CT trades at pT=0.95p_T = 0.95 (a 5% discount), the risk premium at T=0.5T = 0.5 (halfway to expiration) is:

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

At T=0.01T = 0.01 (near expiration), the same CT price produces:

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

The same 5% CT discount generates a risk premium ~1,500x larger near expiration. This exponential sensitivity is the manipulation vector: a swap executed shortly before expiration inflates HIYA disproportionately, distorting the next market's initialization price.

0x2 Vulnerability Analysis

The impacted market involves the following tokens:

Role Token Description
RA wstETH Redemption Asset
PA weETH Pegged Asset
DS weETH8DS-2 Depeg Swap
CT weETH8CT-2 Cover Token

For clarity, the remainder of this report refers to tokens by their abstract roles (RA, DS, CT) rather than their concrete names, except where the distinction matters.

The attacker extracted both DS and CT from the AMM and Router using two distinct methods. Since DS + CT can be redeemed for RA, obtaining both enables direct profit extraction. The attack consists of two components.

0x2.1 Cover Token Extraction: HIYA Manipulation Leading to Artificially Low Market Initialization Prices

When a market term expires, the protocol initializes the next term using accumulatedHIYA from the previous term to set the CT/RA price ratio in the AMM. A higher HIYA signals higher perceived depeg risk, which translates to a lower initial CT price.

Because HIYA is updated on every swap and incorporates risk premiums (Section 0x1.3), and because risk premiums grow exponentially as T0T \to 0, swaps executed shortly before expiration inflate accumulatedHIYA by orders of magnitude. The attacker exploited this by calling SwapRaForDs() near expiration, generating a large risk premium that accumulated into HIYA.

hen the new market term was subsequently initialized, the protocol read the inflated HIYA, interpreted it as extreme depeg risk, and set CT's initial AMM price far below its fair value. The attacker then swapped RA for CT at this distorted price, acquiring a large CT position cheaply.

0x2.2 Depeg Swap Extraction: Missing Access Control in `CorkHook.beforeSwap`

In standard Uniswap v4 hook design, beforeSwap is called exclusively by the PoolManager during a swap. Cork's implementation did not enforce this constraint:

// Missing: 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) {
    ...
}

Without this check, any external contract can call beforeSwap directly with arbitrary hookData. When hookData is non-empty, the function enters the FlashSwap execution path (Section 0x1.2), which decomposes RA into CT and DS via depositPsm. The attacker exploited this by invoking beforeSwap directly with crafted hookData that specified a fake market's tokens, causing the protocol to decompose tokens and transfer the results to the attacker.

0x2.3 How the Two Flaws Compose

Neither vulnerability alone is sufficient to extract the full $12 million.

HIYA manipulation gives the attacker cheap CT, but CT alone cannot be redeemed for RA. The redemption formula requires both tokens: CT + DS = RA. The attacker still needs a way to obtain DS.

The missing access control in beforeSwap provides that path. By calling beforeSwap directly with crafted hookData, the attacker can trigger the FlashSwap decomposition path with arbitrary parameters. To obtain real DS through this path, the attacker deploys a fake market that designates real DS as its RA, then calls beforeSwap to decompose that "RA" (real DS) into fake CT and fake DS, which can be swapped back for real DS through the fake market.

With both CT (from HIYA manipulation) and DS (from the unauthenticated beforeSwap call via the fake market) in hand, the attacker redeems them 1:1 for RA (wstETH).

0x3 Attack Analysis

The attack unfolds across three transactions, each corresponding to one phase: inflating HIYA, acquiring cheap CT, and extracting DS to complete the redemption pair.

0x3.1 Preparation: Inflating HIYA

In this transaction, the attacker called SwapRaForDs() shortly before market expiration. Because TT was near zero, this swap generated a disproportionately large risk premium (Section 0x1.3), inflating accumulatedHIYA.

Attacker holds after this phase: DS from the swap (used later in Phase 0x3.3), and an inflated accumulatedHIYA stored on-chain.

0x3.2 Initialization: Acquiring Cheap CT

In this transaction, the new market term was initialized. The protocol read the inflated accumulatedHIYA and set a distorted CT/RA price ratio in the AMM, pricing CT far below fair value. The attacker then swapped ~0.000003e18 RA for 3,760e18 CT at this deflated price.

Attacker holds after this phase: a large CT position (acquired cheaply via the manipulated initialization price).

0x3.3 Extraction: Obtaining DS via the Fake Market

This phase uses the access control vulnerability (Section 0x2.2) to extract DS, completing the CT + DS pair needed for RA redemption. The core technique is a fake market that treats the real DS as its redemption asset:

Fake Market Role Actual Token Purpose
Fake RA Real DS (weETH8DS-2) Allows real DS to enter the decomposition path
Fake CT Minted from fake RA decomposition Intermediate; swapped back for real DS
Fake DS Minted from fake RA decomposition Intermediate; swapped back for real DS

The key steps of the attack transaction:

  1. The attacker first swapped RA for DS in the legitimate market.

    Attacker holds: real DS.

  2. The attacker deployed and initialized the fake market, designating real DS as fake RA.

  3. The attacker invoked beforeSwap directly (exploiting the missing access control) with non-empty hookData, triggering the FlashSwap execution path against the fake market. Within the hookData, the attacker specified paymentToken as fake CT, causing the protocol to execute the RA decomposition logic against the fake market.

  4. The protocol decomposed all fake RA (i.e., real DS) into fake CT and fake DS. The entire fake DS portion was transferred to the attacker, and the fake CT portion (minus a minimal paymentAmount) was refunded.

    Attacker holds: 3,761e18 fake CT + 3,761e18 fake DS (both derived from real DS).

  5. The attacker swapped fake CT and fake DS back into fake RA within the fake market, recovering real DS.

    Attacker holds: 3,761e18 real DS (recovered).

  6. The attacker combined the recovered DS with the CT obtained in Section 0x3.2 to redeem RA (wstETH), completing the profit extraction.

    Attacker holds: 3,760e18 RA (wstETH) profit (i.e., $12M).

Summary

This incident combined two independent flaws, neither sufficient on its own, into a single exploit chain that drained $12 million from the protocol.

  • Exponential risk premium near expiration. The HIYA pricing formula amplifies risk premiums as time to maturity approaches zero, making late-stage swaps a manipulation vector for market reinitialization prices.
  • Missing sender validation in hook callbacks. CorkHook.beforeSwap did not enforce that msg.sender was the PoolManager, allowing direct invocation with arbitrary parameters and enabling the attacker to spoof the FlashSwap execution path.
  • Cross-module interaction as a blind spot. The economic design (HIYA-based pricing) and the access control gap (unauthenticated hook callback) resided in separate modules. Their interaction created an exploitable path that single-module analysis is unlikely to detect.

Reference

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

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


About BlockSec

BlockSec is a full-stack blockchain security and crypto compliance provider. We build products and services that help customers to perform code audit (including smart contracts, blockchain and wallets), intercept attacks in real time, analyze incidents, trace illicit funds, and meet AML/CFT obligations, across the full lifecycle of protocols and platforms.

BlockSec has published multiple blockchain security papers in prestigious conferences, reported several zero-day attacks of DeFi applications, blocked multiple hacks to rescue more than 20 million dollars, and secured billions of cryptocurrencies.

Sign up for the latest updates