The Anatomy of a Flash Loan Attack: Five Protocols That Lost Millions and Lessons Learned

The Anatomy of a Flash Loan Attack: Five Protocols That Lost Millions and Lessons Learned
Flash loans were supposed to be one of DeFi's cleverer inventions. Borrow millions, do something useful with it, pay it back, all inside a single atomic transaction. No collateral, no credit check, no risk to the lender. Beautiful in theory. In practice, they've become the weapon of choice for some of the most expensive exploits in crypto history.
The pattern is almost always the same. An attacker spots a pricing assumption or a logic gap in a smart contract, borrows a stupid amount of capital for a few seconds, manipulates the conditions the contract relies on, drains the funds, and pays back the loan. Total cost to the attacker: a gas fee. Total cost to the protocol: sometimes nine figures.
Below are five attacks worth studying, not because they're dramatic, but because the underlying mistakes keep showing up in new code. If you're building, auditing, or investing in DeFi, these are the failure modes you want burned into memory. BlockVet tracks these incidents in real time as part of its broader project intelligence work, and the recurring themes below are part of why on-chain monitoring matters more than a one-time audit stamp.
1. bZx (February 2020), the one that taught everyone what was coming
bZx wasn't the largest flash loan exploit, but it was the first that made the rest of the industry pay attention. Two separate attacks within days of each other, both leveraging flash loans from dYdX to manipulate oracle prices on Kyber and Uniswap. The attacker borrowed ETH, used it to skew an on-chain price feed, then exploited bZx's lending logic which trusted that feed at face value.
The losses were under a million dollars, which today sounds quaint. The lesson was anything but. If your contract reads a price from a thin liquidity pool, an attacker with a flash loan can become the market for a single block. Spot oracles on low-liquidity pairs are not oracles. They're a suggestion, and the suggestion can be bought.
2. Harvest Finance (October 2020), a $24M lesson in stablecoin assumptions
Harvest's yield vaults assumed Curve's stablecoin pools would behave like, well, stablecoin pools. The attacker disagreed. Using a flash loan of around $50M in USDT, they imbalanced Curve's Y pool, deposited into Harvest at the manipulated price, rebalanced the pool, withdrew at a profit, and walked away with roughly $24M.
Every step was legal as far as the contracts were concerned. Nothing was "hacked" in the Hollywood sense. The vault simply trusted the share price calculation at the moment of deposit and withdrawal, and that share price was a function of a pool that could be moved by anyone with enough temporary capital. Which, thanks to flash loans, is everyone.
The takeaway: any contract that prices itself off an external AMM at a single point in time is exposed. Time-weighted averages help. Liquidity floors help. Trusting a snapshot doesn't.
3. PancakeBunny (May 2021), tokenomics as an attack surface
PancakeBunny lost around $45M, and the BUNNY token lost roughly 95% of its value within hours. The attacker took a massive flash loan from PancakeSwap, manipulated the BNB/USDT and BNB/BUNNY pools, tricked the protocol's reward calculation into minting an absurd amount of BUNNY as a "reward," then dumped it into the same manipulated pool.
What makes this one instructive is that the exploit lived inside the protocol's own incentive design. The smart contract did exactly what it was told. The problem was that "exactly what it was told" included a formula that read manipulable pool reserves to determine how many tokens to mint. Reward math tied to AMM state is a flash loan magnet. Full stop.
4. Cream Finance (October 2021), $130M and a composability nightmare
Cream's second major incident drained roughly $130M through a tangle of flash loans across multiple protocols. The attacker borrowed from MakerDAO and Aave, exploited how Cream calculated the value of yUSD collateral by manipulating the underlying yVault's price-per-share, and then borrowed against vastly inflated collateral.
This is the composability problem laid bare. Cream wasn't insecure in isolation. It became insecure because it relied on another protocol's accounting, which could itself be moved by a third protocol's flash loan. Every integration you add is a new trust assumption, and a lot of teams don't actually map those assumptions out before shipping.
Honestly, this is the part most teams get wrong. They audit their own contracts and call it done. Nobody audits the seam where two protocols meet.
5. Beanstalk (April 2022), governance as the exploit
Beanstalk lost about $182M in maybe the most elegant flash loan attack on record. The attacker didn't break any math. They borrowed about $1B in assets via flash loans, used it to acquire enough governance tokens to instantly pass a malicious proposal they'd submitted earlier, and the proposal sent the protocol's treasury to their wallet. Loan repaid, attack complete, all in one transaction.
Governance that can be executed in the same block it's voted on is not governance. It's a vending machine. Time locks exist for a reason. So do voting delays, snapshot-based voting power, and proposal review periods. Beanstalk had none of these protections in a meaningful way, and a billion-dollar flash loan turned the protocol's own democracy against it.
The patterns nobody wants to admit
Look at all five together and the common threads are uncomfortable.
Spot prices from on-chain sources keep getting trusted as ground truth. Reward and share-price math keeps getting tied to manipulable state. Governance keeps getting designed as if voters were humans with intent, rather than contracts with capital. And composability keeps getting treated as a feature rather than a multiplier on every other risk in the stack.
None of these are exotic bugs. They're design choices that look reasonable in isolation and catastrophic in production. Most of them would have been flagged by a thorough audit. Some of them were flagged, and shipped anyway.
What actually helps
A few things, none of them glamorous:
Use time-weighted average prices, or better, decentralized oracle networks with manipulation resistance built in. If you must read from an AMM, know the cost of moving it and assume someone will pay that cost. Add liquidity minimums before a pool is even eligible as a price source.
Separate reward calculations from instantaneous pool state. Use checkpoints, epochs, snapshots, anything that breaks the "borrow, manipulate, claim, repay" loop within a single block.
Put real time locks on governance execution. A 48-hour delay would have killed the Beanstalk attack outright. The cost is inconvenience. The benefit is not losing the treasury.
And monitor continuously. An audit is a snapshot. Protocols evolve, integrations change, oracle dependencies shift. The five attacks above happened to projects that, in most cases, had been audited. Audits caught what they could catch at the time they were performed. They didn't catch what came next, because nobody was watching after the report was filed.
That's the gap most projects underestimate. Security intelligence isn't a PDF you publish on your docs site, it's a continuous read on what your contracts are doing, what they depend on, and how those dependencies are behaving in the wild. If you're running a protocol or sizing up where to deploy capital, having a live view across thousands of projects, with scoring, watchlists, and ongoing risk assessment, is the kind of thing that turns a forensic post-mortem into a prevented incident. Worth a look at BlockVet if that's the layer you're missing.
Flash loans aren't going away. The capital is too useful and the mechanism is too elegant. What changes is whether your contract assumes the rest of the world will play nicely for the 12 seconds it takes to execute a block. It won't. Build like it won't.
Written by the CreatorFetch.com editorial team.