Term Finance: $8.5M Approved by Silence

Nick Sawinyh on 23 Aug 2026

At 06:25:47 UTC on Sunday, August 23, 2026, a single Ethereum transaction executed a governance proposal that had been sitting on-chain, in the open, for six days. The voting window had closed 12 seconds earlier, at 06:25:35, with no vetoes. The transaction pulled 2,841.74 WETH out of Term Finance’s ETH Meta Vault and sent it to a wallet funded with 1 ETH from Tornado Cash. A second transaction at 06:47:47 did the same thing to five USDC vaults for another 1,679,639 USDC.

There was no leaked key, no lying oracle, no reentrancy and no flash loan. The attacker submitted a parameter change through Term’s own governance module, the module queued it, nobody objected, and the module executed it. The payload’s first instruction was to switch off the seven-day timelock that stood behind the vote.

This piece reflects what the chain showed on the morning of August 23, roughly four hours after the first transaction. Everything below is read directly from mainnet transactions, event logs, and live contract calls, and the addresses are cited so you can check them. What is not settled is why an unprivileged address was able to queue a curator-grade parameter change at all. Only Term’s own post-mortem can close that, and at the time of writing it does not exist.

What Term Finance Is

Term Finance is a fixed-rate lending protocol. Instead of the floating rates you get on Aave or Compound, borrowers and lenders match at a fixed rate for a fixed maturity, which is closer to how credit works everywhere outside DeFi lending. Term V2 launched in early August 2026 with an intent-based order book, one-click looping, and refinancing of variable-rate debt from other protocols into fixed terms.

Around that sits a vault layer, and that is what got hit. Term Strategy Vaults follow the curator model that now runs a large share of on-chain yield: depositors put in WETH or USDC, and an external risk curator decides where it goes. Term’s own vaults announcement names K3, August Digital, MEV, RE7, Shorewoods, and UltraYield as launch curators, and says that “any changes to portfolio constraints initiated by Risk Curators are subject to governance by vault LP token holders, ensuring that proposed changes align with depositor interests.”

That sentence describes both what happened and what failed.

On the ETH side the structure is two layers deep. An ETH Meta Vault (tmvETH, 0x26fCb50e…7Db2) holds WETH and allocates it across four curated sub-vaults: Shorewoods ETH, August Digital ETH, Parity Prime ETH, and Parity Core ETH. Those in turn run positions on Morpho and Aave. A depositor holds one token; the risk sits three contracts away. If you have read our guide to curated DeFi vaults, this is the standard shape.

How Term’s Vault Governance Actually Works

Term’s vault governance is not an approval vote. It is a veto vote. When a curator proposes a parameter change, the governor opens a window and asks LP token holders to object. Every legitimate proposal on the ETH Meta Vault’s governor carries the same text, pinned to IPFS:

“Vote YES to VETO the curator’s proposed vault parameter changes. Otherwise, the transaction will become executable when this proposal expires.”

That is proposal 1 from March, proposal 2 from May, proposal 3 from June, proposal 4 from June. Real curator business: toggling a health check, assigning a QUEUE_MANAGER role. All of them boilerplate, all of them opt-out.

Opt-out governance is a reasonable answer to a real problem. Curated vaults need to change parameters constantly, LP turnout is near zero, and a quorum requirement would freeze the vault solid. Morpho-style vaults typically pair a timelock with a guardian who can veto on depositors’ behalf. Term made inaction mean consent, gave depositors a window to object or exit, and put a seven-day timelock behind the vote in case the vote went wrong.

Two guards, then, and the failure mode of the first is not subtle. If the set of addresses permitted to queue a proposal is wider than the set of addresses you trust with the vault’s money, the veto window is what stands between an arbitrary person and the treasury, and a veto window only works if someone is watching.

Nobody was watching. The second guard turned out to be reachable from inside the first, which is the subject of the section after next.

The Setup

Vertical timeline of the Term Finance governance exploit: 1 ETH withdrawn from Tornado Cash on August 17 at 05:01 UTC, 0.5 ETH deposited to the ETH Meta Vault at 05:21, proposal 5 created at 05:25, a second wallet funded on August 18, five USDC vault proposals created on August 21, and the drains on August 23 at 06:25:47 and 06:47:47. Proposal 5 stayed open for six days with zero vetoes cast. Source: Ethereum mainnet block timestamps and governor event logs.

The chain’s version of events starts on August 17.

A wallet, 0xa908b347…612b, receives 1 ETH from the Tornado Cash 1-ETH pool (0x47CE0C6e…2936) in block 25,772,572. Its first outbound transaction lands 90 blocks later, at 05:19:11 UTC.

At block 25,772,675 the wallet deposits 0.5 ETH into the ETH Meta Vault and receives 0.4852 tmvETH. The vault’s total supply at that moment is 2,838.48 tmvETH, so the new depositor holds 0.017% of it.

At 05:25:35 UTC, in block 25,772,694, a contract the attacker deployed (0x64e47780…b4df) creates proposal 5 on the meta vault’s governor. The description is the same boilerplate as every real curator proposal:

{"title":"Veto strategy vault parameter change","summary":"Vote YES to VETO the curator's proposed vault parameter changes. Otherwise, the transaction will become executable when this proposal expires.",...}

Every earlier proposal on this governor, going back to March, had been created by 0xdb97c377…5a81. Proposal 5 came from a contract that had existed for six minutes, holding a stake bought for 0.5 ETH.

The proposal carried 17 actions. The address of the attacker’s payout contract, deployed earlier that same morning, appears six times in the payload. It sat there, publicly readable, for six days.

Only one vote was ever cast on it, the attacker’s own 0.4852 tmvETH, in block 25,772,700. No veto followed.

The Execution

Diagram of the Term Finance attack path: a 0.5 ETH stake buys 0.4852 tmvETH, proposal 5 sits open for six days with zero vetoes, and its first action calls setTxCooldown(0) to delete the Safe's 608,400-second timelock. The vault then recalls four sub-vaults from Aave and Morpho, adds a strategy named Fixed Recipient WETH Exit Strategy with maxDebt set to uint256 max, and forwards 2,841.74 WETH to the attacker in the same transaction. Source: Ethereum mainnet.

The voting window closed at 06:25:35 UTC on August 23. At 06:25:47, in block 25,816,049, the attacker called executeProposal() (tx 0xd354a15b…4129).

Between the vote and the vault sat one more guard. The meta vault is controlled by a Gnosis Safe, and reaching that Safe means going through a Zodiac-style delay modifier at 0x35c99cf4…9e33. A delay modifier holds every queued transaction for a cooldown period before anyone can run it, which is the window a guardian uses to cancel. Term had that cooldown set to 608,400 seconds, a little over seven days.

The first three of the proposal’s 17 actions dealt with it. Each one routes through the modifier’s owner and calls the modifier itself:

  1. setTxCooldown(0), deleting the seven-day wait.
  2. setTxExpiration(0).
  3. enableModule(0x0ae12af3…c0a6), wiring in the governance executor that would push the rest through.

Read txCooldown() at block 25,816,048, one block before the exploit, and it still returns 608,400. Read it at 25,816,049 and it returns 0. The timelock was alive until the transaction that spent it.

With the wait gone, the remaining 14 actions run as seven queue-and-execute pairs inside the same block:

  1. Set the debt allocated to Shorewoods ETH to zero, forcing 44.37 WETH back out of Aave and into the meta vault.
  2. Same for August Digital ETH: 43.88 WETH.
  3. Same for Parity Prime ETH: 1,445.51 WETH, unwound through Morpho.
  4. Same for Parity Core ETH: 1,307.98 WETH.
  5. Add a new strategy to the vault: 0x184f2e57…6338, which reports its own name as “Fixed Recipient WETH Exit Strategy”.
  6. Set that strategy’s max debt to type(uint256).max.
  7. Deposit the vault’s entire WETH balance into it.

The strategy did the one thing its name promises. It took 2,841.7435 WETH and forwarded it to the attacker’s wallet in the same transaction.

Term did not forget the timelock. The timelock was reachable from the proposal it was supposed to contain, and setTxCooldown(0) sat in that proposal’s payload, legible to anyone, for six days.

Four curated sub-vaults, two money markets, one Safe, and a governance module, all doing what they were told.

The Second Round

At 06:47:47 UTC, in block 25,816,159, a second wallet (0x686457a7…0691) ran the USDC side (tx 0x9f273f9a…e8a0).

This one was blunter. Five separate USDC vaults, five separate governors, five proposals executed in a single transaction. The proposals had been created on August 21 with a 49-hour window, and their descriptions were not even filled in. The title field reads, in full:

{"title":"...","summary":"","description":"","resources":[]}

The governor recorded a vote weight of 0.5036 shares on each of the five proposals. Against Parity High Yield USDC v2, the largest vault it drained, that is 0.0000156% of the 3.23 million shares outstanding. The vaults price their shares near par, so the stake behind a $1.68 million withdrawal was worth roughly what a share is: a dollar, give or take.

Vault drained USDC taken
Parity High Yield USDC v2 848,410.95
RockawayX Tori USDC 454,046.26
Parity High Yield USDC 348,877.20
Parity Core USDC 14,172.39
Parity Prime USDC 14,132.49
Total 1,679,639.29

The Cashout

Both wallets consolidated into 0xd5183d8b…fc13. The USDC was swapped to DAI on the way.

As of block 25,817,322, that address held 2,843.20 ETH and 1,679,642 DAI, untouched. Both origin wallets were empty apart from gas dust.

At the ETH price DefiLlama records for 06:25 UTC ($2,387.30), the haul comes to about $8.46 million. PeckShield put it at $8.5 million and independently flagged the Tornado Cash funding, which the withdrawal logs confirm: 1 ETH to each wallet, from the 1-ETH pool, at 05:01 UTC on August 17 and 03:59 UTC on August 18.

The Numbers

Settled, and readable from the chain:

Figure Value Where it comes from
WETH drained 2,841.7435 Transfer logs, tx 0xd354a15b…
USDC drained 1,679,639.29 Transfer logs, tx 0x9f273f9a…
Attacker’s ETH-side stake 0.4852 tmvETH, 0.017% of supply Mint log plus totalSupply at block 25,772,675
Timelock before the exploit 608,400 seconds txCooldown() at block 25,816,048
Timelock after it 0 txCooldown() at block 25,816,049
Vetoes cast 0 Governor logs

Provisional, and worth treating as such:

Figure Value Why it is not settled
USD value of the haul ~$8.46M Depends on the ETH mark; at DefiLlama’s $2,387.30 for 06:25 UTC. PeckShield says $8.5M
Attacker’s USDC-side vote weight 0.5036 shares The VoteCast log records the number, but the same weight appears on all five governors and the proposer held no shares in those vaults at the snapshot block
Total loss Unknown Term has published no accounting; the vaults hold assets that have not been written down

The Vault Still Says the Money Is There

Current depositors can check this one themselves, right now.

Call totalAssets() on the ETH Meta Vault and it returns 2,926.22 WETH. Call convertToAssets(1e18) and each tmvETH share is still priced at 1.0308 WETH. Then check the vault’s actual WETH balance: zero. Check the balance of the “Fixed Recipient WETH Exit Strategy” it deposited into: also zero.

The reason is the accounting. Call strategies(0x184f2e57…) on the vault and it reports a currentDebt of 2,841.7435 WETH against a maxDebt of type(uint256).max. As far as the vault’s books are concerned, the money is not gone. It is out on loan to a strategy. That strategy is a contract whose only function was to forward the balance to the attacker.

Until someone writes that position down, the share price is fiction, and anything reading it, dashboards, integrators, other vaults holding tmvETH, is reading a number backed by nothing.

The Blast Radius

The five USDC vaults still hold about $4.36 million between them, most of it in Parity High Yield USDC v2 ($3.26M). This drain took a slice, not the whole thing.

The contagion is already visible one hop out. The RockawayX Tori USDC vault gave up 454,046 USDC, which means Tori Finance depositors were exposed to a Term governance failure through a curator allocation they never evaluated. The researcher @0xGwoni flagged it within two hours, put the Tori exposure at roughly $480,000, and reported that the team had told them it would cover the loss in full so vault depositors take nothing. Tori had not posted publicly at the time of writing.

That is the curator model’s shape in one incident. RockawayX curated a vault on Morpho, allocated part of it to Term, and Term’s governance let a stranger vote itself the money. The depositor picked one name and inherited three.

Term Labs acknowledged the incident at 07:32 UTC: “We are aware of a governance exploit impacting Term vaults. We will share more details once it has been further investigated.”

Its own response is now queued behind the same machinery. Under two minutes after the drain, at 06:27:35 UTC, the curator address created proposal 6 on the same governor. At 07:52:59 it created proposal 7, whose description reads “The curator has proposed changing shutdown vault to .” Shutting the vault down is itself a parameter change, so it goes through the same veto window the attacker waited out.

DefiLlama, meanwhile, still showed TermFinance Vaults at $12.26M on August 23, down about $450,000 from the day before. An $8.5 million drain does not move a number by $450,000. The likely reason is the section above: the meta vault reports 2,926 WETH it does not have, worth close to $7 million, and an adapter that reads totalAssets inherits the same fiction. A TVL chart is not an incident report, and after an incident it can be a copy of the broken accounting.

The Uncomfortable Questions

How did an unprivileged address queue a curator proposal? Proposals 1 through 4 came from Term’s curator address. Proposal 5 came from a contract deployed minutes earlier by a Tornado-funded wallet, and it executed. Either the governor let anyone with a nonzero share balance submit executable parameter changes, or the attacker acquired a role through a path that is not visible in the governor’s own logs. Everything else in this incident is downstream of that answer, and Term is the only party who can give it.

Why could a proposal switch off the timelock built to contain it? Term’s seven-day cooldown was the second line of defence, the one that assumes the vote might go wrong. It was reachable by the same mechanism it guarded, so a single proposal could delete the wait and then use the modifier it had just disarmed, all inside one block. A delay that a passing proposal can set to zero is not a delay, and this is the cheapest thing on the list to fix: keep cooldown changes behind their own cooldown, or out of governance reach entirely.

Who was supposed to be watching the veto queue? This is the one that generalizes. The proposal was public for six days with the payout contract’s address written into it six times. The USDC proposals were public for two days with a title of ... and no description. Any depositor, any curator, any monitoring bot, any of the six named risk curators could have read them. Nobody did, and the design treats that silence as a yes. Strip the watchers out of an opt-out system and what remains is a delayed-execution queue with a voting UI attached.

Why was there no economic floor on proposing? Half an ETH bought a stake worth 0.017% of the meta vault, and that was enough to put a proposal on the ballot against 2,841 ETH. Even without a quorum, a proposal threshold scaled to the vault, plus a bond the proposer forfeits if a veto passes, changes the economics of trying this. Nothing here required a majority. It required a share balance greater than zero and patience.

That last point is worth stating plainly, because the first alert to circulate, from Defimon, described the attacker as having “cheaply acquired a majority of a sparsely-held DAO governance token.” The logs do not show a majority. On the ETH side the attacker held 0.017% of the vault’s shares; on the USDC side, a rounding error. A majority was never needed, and reading the incident as a token-supply problem points at the wrong fix.

Curated vaults have become the default way to earn yield on-chain because they solve a genuine problem: most depositors cannot evaluate a lending market, so they rent someone’s judgment instead. The governance layer on top is what is supposed to keep that rental honest, and this is the third incident we have covered this year where the authorization layer, rather than the math underneath it, turned out to be the attack surface. Resolv’s USR fell to a single over-powered role in March. Ostium fell to price-submission authorization in July. Term fell to a proposal queue nobody read.

Every low-turnout DAO carries a version of this. We have written before about how decentralized DeFi governance actually is and about Aave’s own governance mess, and the recurring finding is that participation is thin enough that formal process is mostly theater. Opt-out governance takes that thin participation and makes it load-bearing. It converts apathy directly into authorization, and points the result at the treasury.

If you have funds in a Term vault right now, the useful things to check are your own, not a dashboard’s: whether your vault’s governor has a live proposal, who created it, and what its payload actually calls. The share price the vault reports is not currently a guide to what backs it.

More generally, if you hold shares in a curated vault anywhere, the question is not whether the curator is good. It is whether anyone is reading the queue, what happens on-chain when no one objects, and how long you would have to notice. On Term the answers were six days, unopposed execution, and a payload that announced itself the whole time.

Term’s post-mortem still has to explain how a stranger got proposing rights, and that is the part that looks like a genuine defect. Everything after it was the system working: a veto nobody cast, a timelock the vote was allowed to delete, and $8.5 million leaving through the front door on schedule.

DeFi is coming. Don't get left behind

About the author
Nick Sawinyh founded DeFiprime in 2019 and has edited it ever since. His current editorial focus is stablecoin infrastructure, real-world assets on-chain, DeFi yield and risk, and crypto regulation. Based on the East Coast, US. He holds small positions across a range of crypto assets; nothing he publishes is investment advice.

More from the blog