Why
The distinction is the whole story. Term has two very different products under one brand: the core fixed-rate repo markets use per-loan collateral lockers to isolate borrower and lender exposure, and that design held and was untouched. What drained was Term Vaults, a separate yield product built as Yearn v3 contracts, and Yearn was explicit that this was not their bug — the attack came through Term's own governance wrapper sitting on top of the vault. Yearn V3 is deliberately un-opinionated: it exposes privileged roles (role_manager, debt manager, emergency manager) and says nothing whatsoever about who holds them. That holder can be an EOA, a multi-sig, or a governance contract that relays calls, and Term put a DAO vote there. So the audited surface ends at the vault, and the actual security of the vault becomes a property of the token distribution, which no auditor reviews. The invariant that should govern any token-controlled vault is that the cost to acquire decisive voting power exceeds the value that power controls. Term's vault TVL was $12.2M, $8.6M of it on Ethereum, against a governance token cheap and thin enough to corner from a 2 ETH base routed through Tornado Cash. When that inequality inverts this stops being an exploit and becomes an arbitrage — it needs no bug, no zero-day and no cleverness, it executes deterministically, and the attacker is racing nobody. The seed size matters more than it looks: this was not a Beanstalk-style flash-loan attack renting voting power for one block, because the float was thin enough to buy outright, which also means there was no anomalous funding signature to alert on. Accumulation looks like organic buying right up until the proposal executes. This catalogue has recorded the same shape twice already — the stake-concentration card, where a set looks like N independent units while the unit of independence is smaller, and the Aqua card, where quoted depth is real but only for whoever arrives first. Here it is N tokens that are not N voters.
How it works
Mechanics as reported: the attacker cornered a majority of a sparsely held governance token, then passed malicious proposals to seize the strategy vaults, holding 100% of voting power in four of five USDC strategy vaults and roughly 91% in the Ethereum Meta Vault at execution time. The vault contracts then executed the malicious calls as legitimate, because they were. Execution was not a naive transfer either — the first exploit transaction burned 44.37 aEthWETH and withdrew WETH from Aave through the stataEthWETH wrapper, meaning the proposal forced the strategy to unwind external positions first and then redirect. From the vault state machine's point of view that is an entirely ordinary rebalance-and-shutdown sequence, no invariant was violated, and no monitor watching for impossible state would have fired. The exit was 2,843 ETH and about 1.68M USDC swapped to DAI, consolidated into one wallet beginning 0xD5183, and the USDC-to-DAI hop is a read on which assets carry a centralized freeze function. Term reportedly had a seven-day timelock plus an LP veto and neither stopped it, which is the part worth building the measurement around. A timelock is latency, not a control: it converts a security property into an operational one, requiring someone to watch the proposal queue, recognise a hostile payload, and hold both the authority and the liveness to act inside the window. If nobody runs that loop the delay only means the theft is scheduled a week in advance — and notably the incident was first surfaced by a third party's on-chain monitoring bot rather than by Term or its LPs. A veto held by an apathetic quorum is likewise not exercisable, since the population that let voting power reach 100% is the same population expected to veto. So the PoC is two numbers per protocol and neither needs a contract deployed. First, the naive cost of buying 51% of supply against the real cost of buying 51% of historical turnout, because quorum measured against turnout rather than total supply degrades to whoever shows up; the gap between those two figures is the number nobody publishes, and it is where governance apathy stops being a governance problem and becomes a direct reduction in attack cost. Second, and cheaper: for every protocol advertising a timelock, has any proposal ever actually been cancelled or vetoed? If the answer is never, the timelock is decorative, and its presence on a security page is a claim about a loop nobody runs. Context for scale: DefiLlama classified five governance attacks in 2026 totalling $25.1M, led by a $20M malicious proposal against BonkDAO in July, and Term itself lost roughly $1.5M in May 2025 to an oracle decimal mismatch during a routine upgrade — a different failure with the same underlying theme, that the risk kept landing in the configuration and privilege layer rather than in the core math.
Update 2026-08-25 — mechanism worked through, card closed
What a DAO proposal actually is. Not a policy document but the transaction itself. A Governor exposes propose(address[] targets, uint256[] values, bytes[] calldatas, string description), and execution is a loop of targets[i].call{value: values[i]}(calldatas[i]). The governance contract is a machine that makes arbitrary calls on request, and the vote is its trigger. The description field is not enforced on-chain, so a proposal may read "Q3 strategy rebalance" while the calldata does something else entirely; only the calldata binds.
So the attacker's actions reduce to two: author a transaction, which anyone may do, and win the vote, which requires buying tokens. No privilege escalation, no reentrancy, no overflow. The DAO was used exactly as designed.
What sat in the calldata. Every Yearn v3 function involved is an ordinary operational one — set_role, add_strategy, update_debt, shutdown_vault. The reported execution burned 44.37 aEthWETH and withdrew WETH from Aave through the stataEthWETH wrapper, which is the on-chain signature of update_debt(aaveStrategy, 0): unwind the external position back into the vault first, then redirect. Inferred sequence, since no postmortem is published: register an attacker contract as a strategy, zero the Aave strategy's target debt to recall funds, push the recalled balance into the attacker strategy, withdraw. A legitimate rebalance and this attack differ by one twenty-byte address in a second argument. Nothing monitoring for invariant violations fires, because no invariant is violated.
Three denominators, and only the third is the attack cost. Cost to buy 51% of total supply is the number people quote; cost to buy 51% of the liquid float is closer; cost to buy 51% of historical turnout is what actually had to be paid. Locked team and treasury allocations do not vote, and most circulating holders do not either, so an attacker holding a small single-digit percentage of supply can hold 100% of votes cast — which is what the reported figures describe. A quorum floor measured against total supply would have raised the cost by orders of magnitude, but quorum floors set high enough to matter also paralyse DAOs, so protocols relax them, and the relaxation is the discount.
Why the existing defences did not bind. A seven-day timelock is latency, not a control: it converts a security property into an operational one requiring somebody to watch the proposal queue, recognise a hostile payload, hold authority and remain live inside the window. Nobody ran that loop — the incident was surfaced by a third party's monitoring bot rather than by Term or its LPs. An LP veto held by an apathetic quorum is likewise not exercisable, since the population that let voting power reach 100% is the population expected to exercise it. And the absence of a flash loan made things worse rather than better: Beanstalk-style rental leaves an enormous funding signature, while a float thin enough to buy outright makes accumulation indistinguishable from organic demand until execution.
The fixes, ordered by whether they need a human. Narrowing the executor to a whitelist of pre-registered functions and addresses would have made add_strategy(attacker) unreachable, and it works with nobody watching. Tying voting weight to vault shares rather than to a separate token makes the invariant self-enforcing: controlling 51% requires depositing 51%, so half of anything stolen was already the attacker's. A guardian key independent of the token can cancel during the timelock. A longer timelock alone changes nothing, since the loop it depends on was never running.
Why this keeps recurring. After Beanstalk the industry adopted vote snapshots, voting delays and timelocks, which defeat flash-loan governance attacks completely — and Term passed all of them by simply buying and holding. The vector was patched, not the class. Meanwhile the configuration itself is the industry default, because placing role_manager in a multisig invites the criticism of centralisation, and narrowing governance powers reduces token utility, lowers the price, and thereby cheapens the remaining voting power. Security and the decentralisation narrative pull in opposite directions, which is why no team's org chart contains the person who would compute this ratio.
Closing status. The mechanism, the denominators, the failure of timelock and veto, and the ordered fixes are now documented here. What remains is arithmetic on live protocols, and it belongs in a follow-up rather than in scoping: pull historical turnout from Snapshot or Tally, price decisive weight against DEX depth, and set it against governed TVL. Note also that the invariant is time-varying — it was likely satisfied at launch and inverted silently as the token declined — so the deliverable is a monitor rather than an audit.
Where it lands in Jayverse
- DeFi: price voting power before granting a role, not after. Before jayverse-defi hands role_manager, debt manager, or emergency manager on any vault strategy to a governance contract, compute the cost to buy 51% of historical turnout against governed TVL as a design check, not a documentation afterthought.
- Auditor: add "has any timelocked proposal ever been cancelled or vetoed" as a standing question. If the answer is never, the audit should flag the timelock as decorative rather than crediting it as a control.
- Token/Bridge/Personas: tie JYVE voting weight to locked stake or vault shares, not a freely tradeable token. That makes the invariant self-enforcing — acquiring 51% of votes requires depositing 51% of the value at risk, so half of anything stolen was already the attacker's.
- Devnet/gitboard: build a monitor, not a one-time audit. Since the cost-to-capture invariant is time-varying, track governance-token float against DEX depth on devnet continuously and surface it on gitboard rather than checking it once at launch.
Key expressions
| Expression | 뜻 · 쓰이는 자리 |
|---|---|
| market order | 시장가 주문 · 여기서는 "그냥 사들이면 끝나는 공격"이라는 뜻으로 제목에 쓰임 · "when the exploit is a market order" |
| cornered a majority | (시장을) 매점하다, 통째로 사들여 지배력을 얻다 · 유통량이 얕은 토큰을 쓸어담아 다수를 장악함 · "cornered a majority of a sparsely held governance token" |
| float | 유통 물량 · 시중에 풀려 실제 거래 가능한 수량 · "the float was thin enough to buy outright" |
| sit on top of | ~의 위에 얹혀 있다 · 하위 시스템을 감싸는 거버넌스 레이어를 설명할 때 · "governance wrapper sitting on top of the vault" |
| un-opinionated | 특정 방식을 강요하지 않는, 중립적인 · 설계가 사용 방식에 관여하지 않음을 뜻함 · "Yearn V3 is deliberately un-opinionated" |
| decisive voting power | 승부를 가르는 의결권 · 과반을 얻어 제안을 통과시킬 수 있는 지분 · "cost to acquire decisive voting power exceeds" |
| convert ~ into an operational one | ~을 운영상의 문제로 바꿔놓다 · 보안 장치가 사람의 감시에 의존하게 됨을 설명 · "converts a security property into an operational one" |
| decorative | 장식적인, 실효 없는 · 아무도 실행하지 않는 안전장치를 가리킴 · "the timelock is decorative" |
| apathetic quorum | 무관심한 정족수(투표권자들) · 아무도 나서서 거부권을 행사하지 않는 상황 · "a veto held by an apathetic quorum" |
| pull in opposite directions | 서로 반대 방향으로 끌어당기다, 상충하다 · 보안과 탈중앙화 서사가 충돌함을 표현 · "pull in opposite directions, which is why" |
| TVL | 락업된 총 가치(Total Value Locked) · DeFi 볼트·프로토콜에 예치된 자산 총액 지표. "Term's vault TVL was $12.2M" |
| Snapshot | 스냅샷 · 가스비 없이 오프체인 투표를 진행하는 거버넌스 플랫폼. "pull historical turnout from Snapshot or Tally" |
| Tally | 텔리 · 온체인 제안 실행까지 연결하는 DAO 거버넌스 대시보드. "pull historical turnout from Snapshot or Tally" |
| stataEthWETH | Aave의 이자수익형 래핑 WETH 토큰(static Aave Token WETH) · 인출 흐름이 이 래퍼를 거쳤다는 온체인 흔적. "withdrew WETH from Aave through the stataEthWETH wrapper" |
| Tornado Cash | 토네이도 캐시 · 자금 출처를 숨기는, 제재 대상인 이더리움 믹서. "routed through Tornado Cash" |
| DefiLlama | 디파이라마 · TVL 등 DeFi 통계를 집계하는 데이터 사이트. "DefiLlama classified five governance attacks in 2026" |
| Beanstalk | 빈스토크 · 2022년 플래시론으로 거버넌스를 탈취당한 선례 프로토콜. "a Beanstalk-style flash-loan attack renting voting power" |