On May 28, 2025, asset-pegged insurance CorK Protocol suffered a ~$12M security breach.
The attacker exploited a lack of parameter checks, to set up a fake market, and the relatively open access of its AMM extension (CorkHook) to induce double counting of derivative token weETH8DS-2 on two markets, and acquire a large amount of derivatives which they redeemed for 3,761 wstETH.
Pegged crypto assets aim to mirror the value of a more stable asset, providing users with exposure to the stable asset's market behavior and a less volatile cryptocurrency option. These assets are "pegged" to another asset, typically a fiat currency. However, pegged assets can deviate from their intended value, a situation referred to as a "depeg." This can occur by a significant amount, meaning the asset fails to accurately reflect the price of its peg.
While some cryptocurrencies are inherently volatile, pegged assets are designed for stability, but their mechanism can sometimes fail.
In addition to a regular dex pair of a Pegged Asset (PA) and a Redemption Asset (RA), Cork Protocol market introduces the Peg Stability Module (PSM) contract to price and hedge their depeg risk. As we can see in the documentation, the PSM mints two tokenized derivatives: Depeg Swap (DS) and Cover Tokens (CT).
User can buy and sell DS and CT tokens as follows:
Preparation transaction: https://etherscan.io/tx/0x14cdf1a643fc94a03140b7581239d1b7603122fbb74a80dd4704dfb336c1dec0
Exploit transaction: https://etherscan.io/tx/0xfd89cdd0be468a564dd525b222b728386d7c6780cf7b2f90d2b54493be09f64d
Introduced in Uniswap v4, ‘hooks’ are external smart contracts that can be attached to individual pools. Every pool can have one hook but a hook can serve an infinite amount of pools to intercept and modify the execution flow at specific points during pool-related actions (https://docs.uniswap.org/contracts/v4/concepts/PoolManager).
The victim is a legitimate market deployed by the project itself id = 0x6b1d373ba0974d7e308529a62e41cec8bac6d71a57a1ba1b5c5bf82f6a9ea07a where: - RA = wstETH, - PA = weETH, - DS = weETH8DS-2, - CT = weETH8CT-2.
However there is no restriction on market setup, especially RA and exchangeRateProvider.
The exploiter input the tokenized derivative as ra and a malicious contract as exchangeRateProvider to set up a fake market.
CorkHook, which is used extensively in rebalancing, lacks access control so the attacker can inject false hookData to deposit tokens from FlashSwap to ModuleCore (also a step of normal rebalancing), and essentially changes their role from a legitimate DS to a fake market RA while minting additional derivatives for the attacker.
Addresses
Attack wallet: 0xEA6f30e360192bae715599E15e2F765B49E4da98
Attack contract: 0x9Af3dCE0813FD7428c47F57A39da2F6Dd7C9bb09
CorkHook: 0x5287e8915445aee78e10190559d8dd21e0e9ea88
Victim proxy: 0xccd90f6435dd78c4ecced1fa4db0d7242548a2a9
Step by Step Event Flow
i) 0.00347 wstETH was transferred to FlashSwapRouter; through FlashSwapRouter._flashswap()->CorkHook.swap()->poolManager.unlock()->CorkHook._beforeSwap()->Forwarder.CorkCall().
ii) An additional 1.121 wstETH was withdrawn from FlashSwapRouter Proxy at the expense of weETH5CT-2 and weETH5DS-2.
iii) In another CorkHook.swap() call, 2.558 wstETH was used to mint equal amounts of weETH5CT-2 and weETH5DS-2.
To simulate a functioning market, the attacker minted the necessary derivative tokens:
This completed the set up of a fake market, id 0xc67cae5b35ca2fdf6564b38dc5332c88ad608d1c5b3595dd9ad781f5a340cb9d where RA = weETH8DS-2, PA = wstETH, DS = wstETH5DS-3 and CT = wstETH5CT-3.
The attacker deposited a small amount of weETH8DS-2 into the fake market, minted matching derivative tokens (wstETH5DS-3 and wstETH5CT-3), and created a Uniswap v4 liquidity pool. They then called unlock() on the Uniswap V4 Pool Manager with crafted calldata, triggering CorkHook.beforeSwap(). By passing malicious hookdata, the attacker tricked CorkCall into executing arbitrary logic from their own contract, simulating a fake swap and setting the stage for unauthorized minting.
The attacker directly called unlock() on Uniswap V4 Pool Manager with the following calldata:
The parameters were passed back to the attack contract which called CorkHook.beforeswap()
The input mimics a regular swap of 110987905101460 wei RA(weETH8DS-2) for CT(wstETH5CT-3) for a fake exchangeRateProvider of 1, but the call uses the attack contract as a hook with the following malicious hookdata:
3,761 weETH8DS-2 tokens were transferred from FlashSwapRouter to ModuleCore and an additional 3,761 wstETH5CT-3 and 3,761 weETH8DS-3 was minted. The additional wstETH5CT-3 and weETH8DS-3 were “skimmed out” and sent to the attacker (3761257491693078379366- 110987905101460 = 3761257380705173277906) who then redeemed them for weETH8DS-2 again.
At the time of writing, the funds remain in Ethereum wallet 0xea6f30e360192bae715599e15e2f765b49e4da98.
To keep up to date on the latest incident alerts and statistics, follow @certikalert on X or read our latest analysis on certik.com.