Securityadvancedarticle25 min read

Badger DAO Hack: $120M Stolen via Front-End Exploit | VCC

On December 2, 2021, BadgerDAO — Ethereum's largest Bitcoin yield aggregator — discovered that $120 million had vanished from roughly 100 user wallets. The contracts were untouched, the vaults had been audited, and no private key was stolen. What broke was the website. For 22 days, a malicious

Vietcardano teamTeam

Đội ngũ biên tập VietCardanoCommunity — các chuyên gia blockchain và Cardano, cung cấp nội dung giáo dục và nghiên cứu chuyên sâu cho cộng đồng.

Published September 14, 2026

On December 2, 2021, BadgerDAO — Ethereum's largest Bitcoin yield aggregator — discovered that $120 million had vanished from roughly 100 user wallets. The contracts were untouched, the vaults had been audited, and no private key was stolen. What broke was the website. For 22 days, a malicious script injected through a compromised Cloudflare API key had been silently rewriting every transaction users approved on app.badger.com, swapping the intended Badger DAO hack victim's vault deposit for an infinite token approval to an attacker-controlled address. When the approvals were later drained with transferFrom, the blockchain did exactly what it was told — because the lie happened in the browser, not on-chain. Understanding why this frontend exploit DeFi incident succeeded — and why Content-Security-Policy, Subresource Integrity, and least-privilege API tokens would have stopped it — reframes DeFi security for every team that still treats its website as marketing rather than as a trust boundary.

What BadgerDAO Does and Why Its Bitcoin Vaults Made a Juicy Target

BadgerDAO launched in late 2020 with a single thesis: Bitcoin holders want yield without leaving their BTC exposure. The protocol built Setts — yield-bearing vaults on Ethereum that accept Bitcoin-pegged assets (wBTC, renBTC, ibBTC) and Curve LP tokens, then auto-compound Curve, Convex, and Badger rewards. By November 2021, Badger managed roughly $1.5 billion in total value locked, with the flagship bveCVX and ibBTC / renBTC Curve vaults holding deep BTC liquidity that few other aggregators matched.

Two properties made Badger a uniquely valuable frontend target. First, its users were BTC whales — wallets holding 50–1,000+ wBTC (each worth ~$55k at the time), not retail dust. A single compromised approval could be worth $50 million. Second, Badger's vault tokens (bveCVX, bCRV, bBadger, ibBTC LP) are ERC-20s that behave like money — once an attacker holds an infinite approval, transferFrom works at any future block without further user interaction. There is no timelock on an allowance, no vault-level circuit breaker, and no issuer freeze (unlike USDT, wBTC is not centrally freezable in the same way). The frontend was the narrowest point that controlled the widest value.

Crucially, Badger's vault contracts themselves had been audited (Haechi, 2021) and contained no reentrancy or accounting flaw. The exploit needed no contract bug because it never touched contract logic — it obtained legitimate approvals through a compromised user interface, then used the contracts exactly as designed. That distinction is why post-mortem checklists for lending and vault protocols now separate "contract audit" from "frontend trust boundary review" as two independent gates.

Diagram - BadgerDAO architecture: user wallet connecting via app.badger.com frontend trust boundary to Setts holding wBTC/ibBTC and Curve LP assets that the frontend approvals controlled

Timeline: 22 Days Inside the Website Before Anyone Noticed

The Badger DAO hack was an APT-style intrusion — persistence mattered more than speed.

November 10, 2021 — The attacker, having obtained a Cloudflare API key belonging to a BadgerDAO engineer, used Cloudflare's API to create or modify a Cloudflare Worker route on api.badger.com. The Worker injected roughly 40 lines of obfuscated JavaScript into every response served by app.badger.com. Badger later confirmed the key had broad scope (Workers + Zone edit), no IP allowlist, no rotation schedule, and no MFA gate on API use. The injection was live from this date, but drains were staged to avoid early detection.

November 10 – December 1, 2021 (dwell window) — The injected script ran inside every visitor's browser. It wrapped window.ethereum.request, intercepted eth_sendTransaction and eth_sign, and — when the user submitted a legitimate sett deposit — quietly replaced or appended an approve(attackerContract, 0xfff…fff) (MAX_UINT / infinite approval) for whatever tokens the wallet held, after first calling eth_call to check balances and target large holders. The UI still showed the expected transaction details; the approval's spender address (attacker-controlled) was never rendered as a human-readable warning. Over three weeks, more than 100 wallets accumulated infinite allowances to attacker contracts. The attacker rotated the spender address once mid-window to compartmentalize risk.

December 2, 2021, ~00:00–06:00 UTC — Community members on Discord reported unauthorized transferFrom drains. On-chain, the attacker began sweeping the accumulated approvals in batches — not all at once, to keep gas spikes and TVL charts smooth. The largest single victim lost roughly $50 million (wBTC + vault tokens).

December 2, 2021, ~09:00 UTC — BadgerDAO detected the active exploit, paused all vaults and smart contracts via the pause() admin function, and took app.badger.com offline. Cloudflare API keys were revoked, Workers removed, and the malicious script's hash published for verification. No further funds were drained after the pause.

December 2–3, 2021 — PeckShield, BlockSec, and SlowMist published independent root-cause threads within hours, all converging on the Cloudflare API key → Worker injection → infinite approval chain. The badger dao hack analysis hardened from hypothesis to consensus before the official post-mortem.

December 10, 2021 — BadgerDAO published the technical post-mortem on Medium: Cloudflare API key compromise confirmed, injection details, attacker addresses, and a remediation plan (CSP, SRI, token scoping, frontend canary). A treasury-funded reimbursement framework was proposed in subsequent governance posts.

2022–2023 — Forensic tracking (SlowMist, Chainalysis) followed consolidated funds to Tornado Cash deposits in ~100 ETH batches. Of the $120M, roughly $70M+ was obfuscated through the mixer by January 2022; the BTC-heavy composition complicated laundering because wBTC had to be unwrapped and bridged before mixing. No attacker identity was publicly confirmed; no funds were returned.

Timeline - Badger DAO hack timeline: Nov 10 Worker injection, 22-day stealth dwell with selective approvals, Dec 2 detection and vault pause, Dec 10 post-mortem disclosure

The Numbers: Where $120 Million Went and Why It Concentrated in BTC

Headlines round to $120 million, but cross-checking aggregators shows expected variance by price snapshot. PeckShield cites $120.3M, BadgerDAO says $120M, and Rekt reports $120M — differences map to BTC's intraday price ($53k–$57k on Dec 2, 2021). Use $120M with the variance noted; precision beyond that is snapshot-dependent.

ItemValue
Headline loss~$120M (~$120–121M by USD snapshot)
BTC-denominated loot~2,100 BTC (wBTC + ibBTC_interest-bearing) ≈ $85–90M
BADGER + vault LP~151 BADGER + bBadger / bveCVX / bCRV / ibBTC Curve LP ≈ $25–30M
Remaining ERC-20sDIGG, renBTC LP, assorted vault receipts ≈ $5M
Affected wallets~100 with infinite approvals; ~10 with >$1M loss
Largest single victim~$50M (single whale's wBTC + sett tokens)
Flash loan involved?No — this was not a flash loan attack; approvals were collected over weeks
Funds returned$0 (0% recovery) — attacker-controlled, no issuer freeze
Who bears lossUsers initially; Badger treasury/governance reimbursement framework proposed

Three details distinguish these numbers from other 2021 losses. First, ~75% of value was BTC-pegged, not stables — the opposite of lending exploits like Cream Finance ($130M in mixed majors). BTC's late-2021 price meant each compromised whale was worth double digits of millions. Second, the per-victim concentration was extreme: the top 10 wallets held ~60% of the total, because the injected script prioritized large balances via balanceOf checks before requesting approvals. Third, because wBTC and ibBTC are not issuer-freezable like Tether's USDT (where Tether froze $33M in the Poly Network hack), no on-chain choke point existed to claw funds after the sweep — once transferFrom executed, the assets were sovereign.

Root Cause: How a Cloudflare API Key Became a $120M Smart-Contract Drain

The malicious token approval chain had four links. Break any one and the $120M stays put.

1. Long-lived, over-scoped Cloudflare API key

The compromised credential was a Cloudflare Global API Key or scoped API token belonging to an engineer with Workers Scripts:Edit + Zone:Edit permissions. It had no IP allowlist, no short TTL, no rotation history, and — critically — Cloudflare's API does not enforce MFA on key usage even if the account has MFA for login. In practice, whoever held that string could rewrite any Cloudflare-proxied path for Badger's domains. Badger's disclosure explicitly distinguishes this from "Cloudflare was hacked" — Cloudflare's infrastructure was not breached; a credential scoped to it was abused, exactly like a leaked GitHub PAT that can rewrite a repository.

2. Cloudflare Worker injected into api.badger.com

Using the API, the attacker created or updated a Cloudflare Worker bound to the api.badger.com route (the same domain that serves the frontend's API and, via Workers, can inject into app.badger.com responses). The Worker appended a