Reproduced Exploit
Cook Finance Issuance — Caller-Chosen Weightings Drain CKToken Components via Thin Pancake Pools
1. Cook's IssuanceModuleV2.issueWithSingleToken2 (IssuanceModuleV2.sol:3124-3153) lets anyone mint a CKToken by supplying a single component token and a caller-chosen _weightings[] array.
Loss
~2.82 BNB net profit to the attacker (2816924852223933205 wei), extracted from a Cook Finance CKToken's compo…
Chain
BNB Chain
Category
oracle
Date
Jun 2026
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. Step by Solidity line or by opcode across all call depths; the source line, Stack, Memory, Storage, Transient storage and Return value stay in sync. Click any opcode or source line to jump. No backend, no live RPC.
Source & credit. Exploit reproduction, trace data, and analysis adapted from DeFiHackLabs by SunWeb3Sec — an open registry of reproduced on-chain exploits. Standalone Foundry PoC and full write-up: 2026-06-CookFinanceIssuance_exp in the
evm-hack-registrymirror. Upstream DeFiHackLabs PoC:src/test/…/CookFinanceIssuance_exp.sol.
Vulnerability classes: vuln/oracle/price-manipulation · vuln/logic/incorrect-state-transition · vuln/defi/flash-loan-attack
Reproduction: the PoC compiles & runs offline in an isolated Foundry project at this project folder. Full verbose trace: output.txt. Verified vulnerable source: IssuanceModuleV2.sol and CKToken.sol.
Key info#
| Loss | ~2.82 BNB net profit to the attacker (2816924852223933205 wei), extracted from a Cook Finance CKToken's component inventory |
| Vulnerable contract | IssuanceModuleV2 — 0x7Db3CBAf736C049933A3Af28dBeD4A4442aa89d0 |
| Victim CKToken | 0xA4e9f6032ee717710D8Fd3dCE0367d283e16f50e |
| Attacker EOA | 0xEe18c4c2E123402731f43d680e75ca2809c30f8b |
| Attacker contract | 0xeFFcB496CaE89E7E92abe17d22386345707CEEe4 |
| Attack tx | 0x51e46828b7aabfa810910b3f8ca535053716e6bcb8b7f94a4ff59757d71a1bca |
| Chain / block / date | BSC / 106,740,999 / June 2026 |
| Bug class | Permissionless issueWithSingleToken2 accepts attacker-chosen component weightings that size swaps of the CKToken's own inventory through a Pancake V2 spot adapter with zero min-out, so thin-pool seeding turns a 1-unit issue into a real component drain |
TL;DR#
-
Cook's
IssuanceModuleV2.issueWithSingleToken2(IssuanceModuleV2.sol:3124-3153) lets anyone mint a CKToken by supplying a single component token and a caller-chosen_weightings[]array. -
Internally
_issueWithSpec(IssuanceModuleV2.sol:3365-3387) does:_issueTokenAmountToUse = _issueTokenQuantity.preciseMul(_weightings[i]).sub(1); componentReceived = _tradeAndWrapComponents(...); // zero min-out on Pancake spotThere is no bound that weightings sum to 1e18, and no TWAP/oracle on the swap path.
-
The attacker seeds thin CAKE/component and vBNB/component Pancake V2 pools with ~0.02 BNB, then calls
issueWithSingleToken2twice with weightings that force the CKToken to trade nearly its entire CAKE (then vBNB) inventory through those pools at manipulated prices. -
After each issue, the attacker removes the seeded LP (recovering the drained components), swaps everything to BNB, and keeps the surplus.
-
Reproduced profit: 2.8369 BNB ending balance / 2.8169 BNB net over the 0.02 BNB seed (
assertGt(..., 2.7 ether)), output.txt.
The vulnerable code#
// IssuanceModuleV2.sol — issueWithSingleToken2 + _issueWithSpec
function issueWithSingleToken2(
ICKToken _ckToken,
address _issueToken,
uint256 _issueTokenQuantity,
uint256 _minCkTokenRec,
address[] memory _midTokens,
uint256[] memory _weightings, // attacker-controlled "percentages"
address _to,
bool _returnDust
) external nonReentrant onlyValidAndInitializedCK(_ckToken) { ... }
// weightings size the CKToken-side trades with no sum/cap check and no min-out
uint256 _issueTokenAmountToUse = _issueTokenQuantity.preciseMul(_weightings[i]).sub(1);
componentReceived = _tradeAndWrapComponents(_ckToken, _issueToken, _issueTokenAmountToUse, ...);
Root cause: untrusted weightings + spot DEX adapter + zero minimum output = permissionless NAV/inventory extraction against any CKToken that holds real component balances.
Attack flow#
Recommendation#
- Cap and normalize weightings so they sum to exactly
1e18(or use a fixed pro-rata schedule the issuer cannot override). - Require non-zero
minAmountOuton every external swap, priced against a TWAP/oracle rather than spot. - Do not allow a single-token issue path to sell other components of the set — issue should only buy missing components up to the mint amount.
- Add a max issue-size / max inventory-delta guard so one call cannot move nearly 100% of a component balance.
References#
- Attack tx: https://bscscan.com/tx/0x51e46828b7aabfa810910b3f8ca535053716e6bcb8b7f94a4ff59757d71a1bca
- Analysis: https://x.com/DefimonAlerts/status/2071497001443770684
- Upstream PoC: DeFiHackLabs
src/test/2026-06/CookFinanceIssuance_exp.sol
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 2026-06-CookFinanceIssuance_exp (evm-hack-registry mirror).
- Upstream DeFiHackLabs PoC:
CookFinanceIssuance_exp.sol. - Attack transaction: view on explorer.
Alerts & third-party analyses
- Original alert / thread: post on X.
- DeFiHackLabs incident explorer: search "Cook Finance Issuance".
- Web3Sec X hacked database: search.
- Rekt leaderboard: search.
- Solodit incident search: search.
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.