MakerDAO Black Thursday Near-Zero-Bid Collateral Auctions (2020-03-12)
- Name: MakerDAO Black Thursday near-zero-bid collateral auctions
- Date: 2020-03-12
- Protocol: MakerDAO
- Chain: Ethereum
- Category: liquidation-auction liveness failure / keeper participation collapse / near-zero-bid collateral seizure / bad-debt event
- Loss: roughly
62,892.93 ETHof collateral reportedly cleared through near-zero-bid auctions across March 12-13, 2020; public analyses also describe about5.67M DAIof system shortfall / bad debt and roughly$8.32Mof keeper windfall at then-prevailing ETH prices - Summary: MakerDAO’s Black Thursday failure was not a classic contract-drain bug; it was a liquidation-mechanism breakdown. As ETH crashed and Ethereum blockspace became severely congested, Maker’s Liquidations 1.2 stack pushed undercollateralized ETH-A vaults into
Flipperauctions thatCat.bite()/kick()opened withbid = 0and relied on outside keepers to discover price. Inflip.sol,tend()requiredbid > bids[id].bidand at leastbeg(5%) improvement over the previous bid, but when the previous bid was literally zero that rule became functionallyany positive dust bid is valid. In practice, many honest keeper bots could not react fast enough, could not reprice gas aggressively enough, or got stuck behind nonce chains and congestion. A small set of opportunistic keepers then won large collateral lots with dust-sized openingtend()bids, waited out the bid-expiry window, and useddeal()to claim the ETH. Vault owners lost all or nearly all collateral in many cases, while Maker still accumulated bad debt that later had to be socialized through MKR dilution. - Trigger / entry point:
- ETH’s violent price collapse on 2020-03-12 pushed many Maker vaults below required collateralization.
- Maker’s liquidation path used
Cat.bite()to seize unsafe vault collateral and kickFlipauctions inFlipperwith openingbid: 0. - In
Flipper, bids were funded fromVat.daiinternal balances rather than ordinary wallet DAI, so competitive participation depended on keepers already having prefunded internal DAI plus a working transaction pipeline. - Ethereum congestion and gas spikes impaired both vault-defense transactions and ordinary keeper competition right when liquidation volume surged.
- Root cause:
- Maker treated liquidation participation as an external market-service assumption rather than a protocol-critical liveness dependency.
- Liquidations 1.2 allowed new auctions to open from
bid = 0, andFlipper.tend()only enforcedbid > previous bidplus abegminimum increment over the prior bid. Because the prior bid started at zero, the opening-bid floor was effectivelyany positive dust amountrather than a meaningful reserve price. - Short auction timers and brittle keeper infrastructure turned chain congestion into a solvency event: the protocol could seize collateral, but it could not reliably sell that collateral for enough DAI.
- Oracle / OSM timing and market shock compressed liquidations into the same window that crippled bidding, magnifying the keeper-capacity problem.
- In effect, Maker’s solvency logic assumed healthy offchain bidder competition during exactly the network conditions least likely to sustain it.
- Exploit path:
- As ETH sold off sharply on 2020-03-12, more Maker vaults crossed liquidation thresholds and became biteable.
Cat.bite()transferred collateral out of unsafe vaults and kicked ETH-AFlipauctions withbid: 0, setting up atendphase whereFlipper.tend()only required the first valid bid to be strictly greater than zero; the usualbeg = 5%minimum increase did not protect the opening step because5% * 0is still0.- Honest keepers were expected to fund internal DAI balances, observe auction ids, and compete bids upward toward
tab, but heavy congestion and gas spikes disrupted that process. - Public reporting and later analyses describe keeper bots that did not adapt gas pricing well under stress and sometimes became stuck behind their own earlier pending transactions.
- Opportunistic keepers submitted dust-sized opening bids that were technically valid
tend()calls even though they were economically negligible relative to the collateral lots. - Because few or no competing bids arrived before the bid-expiry window elapsed, those bidders became the auction winners by default.
Flipperpermitted auctions to end in thetendphase without ever reachingtab; afterticexpired,deal()transferred the entire collateral lot to the winning bidder while the unpaidtab - bidshortfall remained bad debt against theVow.- This repeated across a large share of the liquidation set, producing the cluster of so-called
0 DAIorzero-bidauctions remembered as Black Thursday. - Vault owners lost collateral, Maker was left with millions of DAI of bad debt, and the protocol later had to recapitalize through debt auctions that minted and sold MKR.
- What the attacker needed to be true:
- Vault liquidations had to arrive during a period when keeper competition was badly impaired.
- Auctions had to permit an economically tiny first bid rather than enforcing a meaningful reserve or protocol backstop.
- Honest keepers needed to be unable or unwilling to replace the opening dust bid before the timer expired.
- The bidder needed enough operational reliability to keep one live transaction path working while others stalled.
- Maker needed to continue settling auctions mechanically even when the realized bid was nowhere near fair distressed collateral value.
- Technical anatomy worth remembering:
- The colloquial
0 DAIdescription slightly oversimplifies the contract mechanics.Flipper.tend()required the new bid to be strictly greater than the previous bid, so the decisive bids were dust-sized or near-zero rather than literally zero; the economic result was the same. Cat.bite()explicitly kicked auctions withbid: 0, andflip.solsetbeg = 1.05,ttl = 3 hours, andtau = 2 daysby default. The crucial failure was thatbegwas inert on the very first bid because the comparison started from zero.Flipperalso allowed an auction to settle intendwithout ever reachingtab, so the protocol could both hand out the entire lot and still carry the unpaid difference into system bad debt.- Competitive bidding depended on
Vat.daiinternal balances, not only on wallet balances or a keeper’s willingness to participate. That made prefunding and keeper operational readiness part of the effective security boundary. - This was a full-stack failure: price shock, OSM timing, blockspace congestion, keeper capital, gas repricing, nonce management, and auction math all interacted.
- The incident is also a reminder that
liquidation works in normal marketsis not the same claim asliquidation preserves solvency in crisis markets. - It is the auction-side exemplar for liquidation-capital-provenance-and-keeper-competition-assumptions: Maker did not merely need an honest price for ETH; it needed live bidders with prefunded internal
DAI, working mempool access, and enough operational headroom to keep competing while congestion was worst.
- The colloquial
- Representative transactions and artifacts:
- ETH-A
Flipperauction contract:0xF32836B9E1f47a0515c6Ec431592D5EbC276407f Catliquidation module:0x78f2c2af65126834c51822f56be0d7469d7a523e- Public analyses highlighted multiple winning keeper addresses, including
0x9c05a05893ada984fc20d0da0c046de5cc0e8273,0x9631a838a81d4050c43c66bc03a0cf414243f661,0xb00b6d69822da235a99d2242376066507c9a97b7, and0xb400cd43dc25db30c07e665903a052ac120c30ad. - White Rabbit’s post-incident chain analysis reported
3,994liquidation transactions across March 12-13, of which1,462— about36.6%— cleared at a reported100% discount/ near-zero-bid outcome.
- ETH-A
- Response / mitigation:
- Maker governance responded with emergency parameter changes intended to make auction capture harder, including longer bidding windows and larger lot sizing.
- The protocol later recapitalized system bad debt through MKR debt auctions, diluting MKR holders rather than letting DAI remain undercollateralized.
- In the longer run, Black Thursday became the canonical justification for Liquidations 2.0 and broader redesign of Maker’s liquidation and backstop assumptions.
- The event also triggered prolonged governance debate over compensating vault owners whose collateral had been seized for effectively nothing.
Pattern tags
- Core recurring pattern: liquidation-auction-liveness-failure.
- The preserved shape is sharper than generic
market crashor genericoracle lag: Maker’s solvency path depended on zero-start English auctions, prefunded internalVat.dai, and live keeper competition staying healthy during the exact blockspace crisis that made liquidations surge. - This is the corpus’s clean canonical example of
liquidation triggered correctly, recovery still failedbecause the first executable bid was underconstrained and the rescue capital / mempool-access assumptions were too optimistic.
Three liquidation-authority promotions this incident collapsed
-
Maker could mechanically trigger liquidation and seize collateral from unsafe vaults
Cat.bite()could correctly identify undercollateralized vaults, move collateral into the liquidation path, and kickFlipperauctions.- By itself this only proved the protocol could start liquidations. It did not yet prove that the resulting auction state represented sane stressed recovery value.
-
Maker promoted the first live
tend()bid into canonical stressed-market price discovery- Because auctions opened from
bid = 0, the first surviving keeper bid answeredwhat is this collateral lot worth right now?even when that bid was just dust submitted during congestion. - That was the decisive promotion: one live bidder under broken competition conditions became the protocol’s authoritative distressed-price signal.
- Because auctions opened from
-
That accepted dust-price signal still retained full collateral-transfer and bad-debt crystallization authority
- Once the weak opening bid survived the timer,
deal()could transfer the entire lot to the bidder while the unpaid remainder hardened into bad debt against the system. A live bid existedandthat live bid deserves final collateral-transfer authority plus solvency consequenceswere separate promotions, and Black Thursday collapsed them together.
- Once the weak opening bid survived the timer,
Why the exploit worked
Cat.bite()openedFlipperauctions frombid = 0, andFlipper.tend()only required the next bid to be strictly greater than the previous one while improving it bybeg; that meant the opening step was effectivelyany positive dust amountrather than a meaningful reserve price.- Maker’s stressed recovery path depended on external keepers already holding usable internal
Vat.daibalances plus the operational ability to observe auction ids, reprice gas, and keep nonce chains healthy during extreme Ethereum congestion. Those were hidden but very real solvency assumptions. Flippercould still settle an auction in thetendphase without ever reachingtab, so the protocol could both transfer the whole collateral lot to the winner and keep the unpaid remainder as bad debt. The liquidation engine therefore lacked a hard guarantee that collateral seizure implied adequate debt recovery.- OSM timing, price shock, and mempool stress bunched many unsafe vaults into the same crisis window, which meant the weakest part of the design — price discovery through opportunistic external bidding — was asked to do the most work when bidder competition was least reliable.
- The later MKR debt auctions confirmed the deeper failure mode: Maker had a path to socialize the loss after auctions failed, but not a sufficiently robust mechanism to stop
dust first bid + no competitionfrom becoming live collateral-transfer authority in the first place.
Detection and audit pivots
- Audit the exact first-bid rule rather than the headline increment rule. If an English auction starts from zero, ask what protects the opening step when only one bidder is live.
- Separate
collateral can be seizedfromcollateral sale restores solvency. Any liquidation engine that can close while still underrecovering debt should be treated as a recapitalization-risk surface, not just an auction surface. - Stress keeper operations as part of protocol security: internal balance prefunding, gas repricing, nonce replacement, mempool connectivity, and monitoring latency all mattered here as much as auction math.
- Model oracle-lagged liquidation bursts, not only smooth mark-to-market deterioration. A system that looks safe under staggered liquidations can still fail when delayed recognition compresses many auctions into one blockspace crisis.
- Ask what the protocol’s single-bidder lower bound looks like. If one surviving bidder can still walk away with economically absurd collateral at the opening step, the design is not stressed-safe.
- Review the recapitalization path before the event. If the protocol’s real answer to failed liquidation recovery is governance-token dilution or emergency socialization, that should be explicit in risk review rather than discovered during crisis.
Why this incident matters
- It is the cleanest major example of a DeFi protocol failing not because collateral prices moved, but because the liquidation market that was supposed to save the system stopped functioning under stress.
- It shows that mempool access, gas strategy, and bidder ops are part of protocol security whenever solvency depends on offchain keepers.
- It remains one of the best case studies for why auction liveness, reserve logic, and precommitted backstop liquidity matter as much as collateral ratios and oracle correctness.
Failure-prevention checklist
- Do not let the opening liquidation step inherit a meaningless reserve from
0. If the first executable bid can seize the whole collateral lot, the system needs a real opening-price floor, bounded protocol backstop, or alternate sale path that still works when only one bidder is live. - Treat keeper funding rails as part of the security boundary. If bidding requires prefunded internal balances like
Vat.dai, the protocol should monitor, diversify, and rehearse that capital path instead of assuming it will appear during a blockspace crisis. - Size lot configuration, auction timing, and liquidation throughput against stressed bidder capacity rather than normal-market participation. A safe auction should remain competitive when many vaults are liquidated together, gas spikes, and nonce chains are under strain.
- Distinguish
liquidation can startfromliquidation can restore solvency. If an auction may end before reachingtab, the protocol needs explicit bounds on acceptable underrecovery plus a precommitted recapitalization path. - Keep emergency modes ready before the crisis: longer bidding windows, smaller or more adaptive lot sizing, circuit breakers for stalled auctions, and pre-funded or pre-authorized backstop capital when organic keeper competition disappears.
- Stress test mempool-access and transaction-ops assumptions directly. Bidder health should include replacement-transaction reliability, gas repricing speed, bundle/private-orderflow access, and the ability to keep multiple simultaneous auctions live.
- Review oracle timing and liquidation batching together. Delayed recognition that dumps many unsafe vaults into one narrow auction window can turn a manageable liquidation design into a keeper-capacity failure.
- Make the residual-loss surface explicit to governance and users. If failed auctions ultimately socialize losses through dilution or insurance, that is part of the liquidation design, not an afterthought.
Audit prompts
- What economically meaningful lower bound applies to the very first bid when an auction opens, and what prevents a single surviving bidder from buying a large collateral lot for dust under congestion?
- If keepers must hold internal balances, bridge assets, or specific venue access before they can bid, how many genuinely independent operators already satisfy those prerequisites during stress?
- Can the auction close without reaching
tab, and if so, what exact bad-debt ceiling, recapitalization path, and market-pause rule contain that underrecovery? - How many simultaneous liquidations can the system actually clear at stressed gas prices before bidder competition collapses below the level the solvency model assumes?
- Which parts of liquidation readiness depend on mempool conditions, private relay access, nonce management, or gas-replacement behavior rather than on-chain math alone?
- Does lot sizing reduce bidder-friction under crisis conditions, or does it accidentally force keepers to show up with more capital than the market can realistically mobilize at once?
- If oracle delay or batch liquidation pushes many vaults into auction together, what automatic controls narrow the system before
too many auctions at oncebecomes a solvency event? - Before governance promises user compensation or post-event dilution, what design change actually prevents
healthy liquidation trigger, failed debt recoveryfrom recurring?
Lessons that should already be standard
- Liquidation is a liveness system, not just a pricing system. Correctly identifying an unsafe vault is not enough if the protocol cannot reliably convert seized collateral into debt repayment.
- Opening from
bid = 0is not neutral. In a stressed market it means the real reserve price is whatever the last surviving bidder can get away with. - Keeper capital, mempool access, and transaction operations are security dependencies whenever solvency depends on offchain bidding.
- An auction that may legally settle before covering the debt is already a recapitalization design. The question is whether that loss path is bounded and intentional.
- Crisis-time liquidation assumptions must be written for the worst blockspace conditions, not for ordinary days with healthy competition.
- Socialized recovery after failed liquidations can be necessary, but it is not the same thing as a liquidation mechanism that preserved solvency on its own.
Internal linkages
- Core recurring pattern: liquidation-auction-liveness-failure.
- Positive-design companion on bidder-capital and venue assumptions: liquidation-capital-provenance-and-keeper-competition-assumptions.
Control surface
-
The decisive leverage sat in Maker’s
Cat→Flipperliquidation path, thebid = 0auction opening condition, short stressed-market timers, OSM-delayed liquidation recognition, and the real-world operational quality of keeper bots competing in Ethereum mempools. -
Maker did not lose control because one contract forgot an access check. It lost control because liquidation solvency depended on offchain competition that vanished when the system needed it most.
-
Sources:
- https://docs.makerdao.com/miscellaneous/liquidations-1.2-system-deprecated/cat-detailed-documentation
- https://docs.makerdao.com/miscellaneous/liquidations-1.2-system-deprecated/flipper-detailed-documentation
- https://github.com/makerdao/dss/blob/master/src/flip.sol
- https://medium.com/@whiterabbit_hq/black-thursday-for-makerdao-8-32-million-was-liquidated-for-0-dai-36b83cac56b6
- https://www.coindesk.com/tech/2020/07/22/mempool-manipulation-enabled-theft-of-8m-in-makerdao-collateral-on-black-thursday-report
- https://vote.makerdao.com/polling/QmWC4qey
-
Last reviewed: 2026-07-31 UTC