This is a lower bound: only assets with reliable historical USD prices are counted, so the actual loss may be higher.
0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e1060x579a3244f38112b8aabefce0227555c9b6e7aaf0Ethereum0x1e692ef9cf786ed4534d5ca11edba7709602c69fEthereumOn Ethereum mainnet transaction 0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e106 in block 19498911, an unprivileged attacker bought only 2 CGT, locked it in Curio's DSChief-style governance contract, replaced the incumbent hat, and immediately executed a malicious spell through Curio's DSPause executor. The spell minted 1e30 raw CGT and 1e27 raw DAI-equivalent, after which the attacker swapped part of the inflation into liquid assets, bridged additional CGT out, and transferred WETH, DAI, and residual CGT back to the controlling EOA.
The root cause was a governance path that remained permissionlessly reachable at an insecure threshold together with a zero-second timelock. The decisive breakpoint occurred when DSChief.lift(address(this)) accepted the attacker contract as the new hat after only 2e18 CGT were locked against an incumbent hat with only 1e18 approval, which immediately unlocked DSPause.plot and DSPause.exec in the same transaction because delay() == 0.
Curio reused Maker-style governance components. A DSChief-style contract at 0x579a3244f38112b8aabefce0227555c9b6e7aaf0 selects a single hat, and a DSPause-style executor at 0x1e692ef9cf786ed4534d5ca11edba7709602c69f delegates privileged spell execution to whatever address DSChief currently authorizes.
The attacker only needed public components:
0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a0xdaaa6294c47b5743bdafe0613d1926ee27ae8cf5Action at 0x1e791527aea32cddbd7ceb7f04612db536816545The newly added victim-side decompilation closes the governance semantics gap:
dschief-decompiled.sol identifies selector 0x3c278bd5 as lift(address) and selector 0xb7009613 as canCall(address,address,bytes4).dspause-decompiled.sol identifies selector 0x46d2fbbb as plot(address,bytes32,bytes,uint256) and selector 0x168ccd67 as exec(address,bytes32,bytes,uint256).Those decompiled paths align with state queries at block 19498910: hat() was 0x261508b40143eB1631982693bbBB3A776a615196, approvals(hat) was 1e18, delay() was 0, and authority() on DSPause pointed to DSChief.
This was an ATTACK-class governance capture, not a hidden-key incident and not a replay of attacker-private artifacts. The governing invariant should have been that only a materially secure governance process with a non-zero execution delay can obtain spell-execution authority over Curio minting modules. Curio violated that invariant in two ways at once: the incumbent executive hat had only 1e18 approval, and DSPause imposed no waiting period after scheduling. Because DSChief authorization is tied to the current hat, a public buyer of 2 CGT could deterministically become the hat by locking slightly more than the incumbent approval weight. Once that happened, the same attacker contract also satisfied the DSChief canCall gate used by DSPause. With delay() == 0, the attacker could plot and exec the malicious spell at eta = block.timestamp in the same transaction. The spell then invoked Curio minting paths to create massive unauthorized DAI-equivalent and CGT balances, which were immediately monetized.
The attacker path is visible both in the verified attacker contract and in the victim-side governance code. The attacker helper contract transfers in 2 CGT, approves DSChief, calls lock, votes for itself, calls lift, deploys a spell, and then uses DSPause to schedule and execute that spell.
Victim-side decompilation explains why this worked. In the decompiled DSChief contract, canCall(address,address,bytes4) checks that the caller address equals the current hat before returning authorization for governed selectors. In the decompiled DSPause contract, plot(...) checks eta >= block.timestamp + delay, while exec(...) checks the stored plan bit, codehash match, and block.timestamp >= eta before delegating into the spell path. Because DSPause.authority() pointed to DSChief and delay() was 0, the attacker only needed to become the hat once.
The trace shows that exact transition:
0x579A3244...::lift(0x1E791527AEA32cDDBD7CeB7F04612DB536816545)
storage slot 12: 0x261508b40143eB1631982693bbBB3A776a615196 -> 0x1E791527AEA32cDDBD7CeB7F04612DB536816545
0x1e692eF9...::plot(...)
0x579A3244...::canCall(0x1E791527..., 0x1e692eF9..., 0x46d2fbbb) -> true
Once the governance gate opened, DSPause executed the attacker spell in the same transaction:
0x1e692eF9...::exec(...)
0x8B2B0c10...::suck(..., 1e54)
0xE35Fc630...::exit(0x1E791527..., 1e27)
Csc::mint(0x1E791527..., 1e27)
DSToken::mint(0x1E791527..., 1e30)
Those calls are the code-level exploitation breakpoint. Vat.suck and DaiJoin.exit created the DAI-equivalent position, while DSToken.mint inflated CGT supply by 1000000000000000000000000000000 raw units. The exploit then converted part of the minted inventory into liquid assets and public bridge claims, which demonstrates that the governance failure translated directly into realizable value, not just theoretical control.
The attacker flow was fully contained in one adversary-crafted transaction:
0xdaaa6294c47b5743bdafe0613d1926ee27ae8cf5 called attacker helper contract 0x1e791527aea32cddbd7ceb7f04612db536816545.2e18 CGT, locked it in DSChief, voted for itself, and called lift.0x20ebbd71998e189a8d6909bbd650d9c47a8085dc.The final transfer sequence is explicit in the trace:
WETH9::transfer(0xdaAa6294..., 25958519201526709279)
DAI::transfer(0xdaAa6294..., 18669354038893441676322)
DSToken::transfer(0xdaAa6294..., 996000144999000000000000000000)
This matches the incident characterization in the balance diff and confirms that the exploit was permissionless, profitable, and end-to-end complete.
The exploit gave the adversary arbitrary executive control over Curio governance long enough to mint unauthorized assets and realize value from them. The measurable loss recorded in the root cause package is:
CGT: 1000000000000000000000000000000 raw units with 18 decimalsDAI: 1000000000000000000000000000 raw units with 18 decimalsIn addition to those minted amounts, the attacker EOA directly realized:
25.958519201526709279 WETH18669.354038893441676322 DAI996000144999000000000000000000 raw CGTThe same transaction also pushed additional CGT into public bridge contracts, extending the impact beyond the immediate mainnet liquidation path.
0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e106/workspace/session/artifacts/collector/seed/1/0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e106/metadata.json/workspace/session/artifacts/collector/seed/1/0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e106/trace.cast.log/workspace/session/artifacts/collector/seed/1/0x4ff4028b03c3df468197358b99f5160e5709e7fce3884cc8ce818856d058e106/balance_diff.json/workspace/session/artifacts/auditor/iter_1/decompile/dschief-decompiled.sol/workspace/session/artifacts/auditor/iter_1/decompile/dspause-decompiled.sol/workspace/session/artifacts/collector/seed/1/0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a/src/token.sol/workspace/session/artifacts/collector/seed/1/0xfdcdfa378818ac358739621ddfa8582e6ac1adcb/src/csc.sol/tmp/action_source.json