Flash Loan Attacks Keep Winning When One Block Can Decide Too Much
Flash loan attacks are not a special kind of magic. They are what happens when a protocol lets one block of borrowed capital rewrite prices, votes, or solvency.
Establish the problem with technical depth
Calling something a "flash loan attack" is often a way of refusing to name the real failure.
The flash loan is usually just the financing layer. The actual bug is deeper: governance that mistakes temporary balances for legitimate authority, collateral logic that mistakes a manipulable market price for trustworthy value, or accounting that mistakes a transient state for a safe one. Naming the wrong root cause leads teams to defend the wrong thing.
Beanstalk is the clean governance example. In its own incident writeup, Beanstalk says it was attacked on April 17, 2022 and that about $77 million in non-Beanstalk user assets were stolen. The attacker used a flash loan to exploit the protocol's governance mechanism. That sentence matters because it says two things at once. First, the attacker did not need long-term control of the protocol. Second, one transaction was enough to convert temporary economic weight into permanent treasury loss.
Mango Markets shows the same structural weakness from the market side instead of the governance side. In January 2023, the SEC alleged that Avraham Eisenberg manipulated the thinly traded MNGO token beginning on October 11, 2022, then used the inflated value of his perpetual position to borrow and withdraw about $116 million worth of crypto assets from Mango. Borrowed scale or temporarily manufactured scale became protocol truth long enough to extract real assets.
That is the part founders and investors should care about. These incidents are not edge-case engineering embarrassments. They are treasury design failures. If your system allows a one-block distortion to create real borrow capacity, real voting power, or real withdrawal rights, then your downside is not "the bug might be found eventually." Your downside is that the protocol can move from apparently healthy to economically broken inside a single block window.
For CTOs and Solidity engineers, the implication is harsher. Security on public chains cannot rely on capital scarcity, reaction time, or the hope that a manipulative transaction will look too expensive to execute. In a composable market, capital can be rented. Sequence risk can be simulated in advance. If your safety argument starts with "an attacker probably cannot assemble enough size quickly," your safety argument is already dead.
The mechanism, the mistake, the misunderstanding
Flash loans are dangerous because they erase one of the assumptions weaker protocols quietly depend on: that capital is hard to gather and slow to move.
Once that assumption disappears, several bad designs collapse immediately.
The first bad design is same-transaction truth. A protocol reads a price, balance, or voting weight during execution and treats that value as if it were durable rather than adversarially shaped. This is the classic setup for oracle manipulation and self-referential collateral attacks.
function borrow(uint256 amount) external {
uint256 collateralValue = collateral[msg.sender] * oracle.spotPrice();
require(collateralValue >= debt[msg.sender] + amount, "insolvent");
debt[msg.sender] += amount;
asset.transfer(msg.sender, amount);
}
That check looks reasonable until you ask the only question that matters: can spotPrice() be distorted inside the same transaction path that releases value? If the answer is yes, then the protocol is not measuring solvency. It is measuring how effectively the attacker can rent a false price for one block.
The second bad design is self-referential authority. Mango is the obvious case. According to the SEC's complaint, the attacker used two Mango accounts, pushed up the price of the thinly traded MNGO token, increased the value of his MNGO perpetual position, and then borrowed against that inflated position until the platform was drained. The protocol accepted internally amplified market conditions as if they were external truth. That is not a flash loan problem. That is a reflexive collateral problem.
The third bad design is zero time separation between acquiring influence and exercising it. Beanstalk's governance failure is the brutal version of this. If current balances determine governance power, and if proposal approval plus execution can happen with too little delay, borrowed tokens become borrowed control. When one block can create voting power and the next step can immediately spend treasury assets, governance stops being governance. It becomes a capital race.
This is the industry's most persistent misunderstanding. Teams talk as if flash loans are a special attack class that needs a special patch. They are not. Flash loans are an attacker capability, like cheap cloud compute or a fast fuzzing harness. You do not patch the existence of capital markets. You patch the assumption in your protocol that becomes false when capital is abundant for one transaction.
That is why the right question is never "How do we stop flash loans?" You do not. The right question is "What truth in our protocol can be rented for one block?"
If the answer is price, fix your oracle and collateral model. If the answer is governance power, fix your snapshot and execution model. If the answer is solvency, fix your accounting invariants. But stop pretending the loan itself is the disease.
What good looks like
Good flash-loan defense starts by assuming the attacker already has access to maximum relevant capital.
For governance, use historical voting snapshots and real execution delay. OpenZeppelin's governance docs make the model explicit: vote counting is tied to a snapshot timepoint, and the TimelockController exists to enforce delay before successful proposals execute. Those are not nice governance features for mature protocols. They are basic defenses against temporary balance-based control. If users can borrow influence and exercise it before anyone can react, the protocol is inviting a Beanstalk-style failure.
For collateral and price-sensitive logic, separate trade price from borrow-safe price. Thin liquidity, self-issued governance assets, LP shares with opaque embedded risk, and manipulable same-venue prices should never be treated as if they carry the same trust level as deep external reference assets. That means bounded oracle design, conservative collateral factors, tighter caps, and in some cases a blunt decision to disallow an asset entirely. If your protocol can mark an asset up using the same market structure that then grants borrow power, you are building a feedback loop, not a risk engine.
For testing, stop thinking in single-function units. Foundry's invariant testing guidance is valuable here because it forces teams to test truths across randomized sequences of actions, checking the invariant after each call. That is much closer to how real exploit paths emerge. The invariant should not be "borrow() reverts when the unit test says it should." The invariant should be "total realizable collateral value must stay above total debt," or "temporary voting power cannot become executable authority in the same campaign," or "a price spike in a single venue cannot create unbacked withdrawable value."
For operations, treat every diff that touches collateral rules, governance plumbing, execution timing, oracle sources, liquidation parameters, or privileged roles as security-critical. A large share of major losses do not come from untouched core logic. They come from change. One extra adapter, one pricing shortcut, one governance parameter update, one "safe because it is temporary" exception. On public chains, those are not local edits. They are new public attack surfaces.
And for leadership, improve the diligence questions. Do not ask your team only whether the contracts were audited. Ask whether any asset can influence its own borrowable value. Ask whether voting power is historical or current. Ask whether execution is delayed after approval. Ask which invariants are machine-checked on each release. Ask what happens if an attacker has the deepest pool on-chain for exactly one block. If nobody can answer clearly, the protocol is not ready.
ChainShield's angle
ChainShield treats flash loans as baseline environment, not edge case.
The wrong mental model is "an attacker might use a flash loan." The correct model is "the attacker definitely has access to scalable, atomic liquidity, and our protocol must remain safe anyway." Once you accept that, review quality improves immediately. You stop fixating on labels and start inspecting the exact places where a temporary state can become a permanent right.
That is where ChainShield spends its time. Which balances can become authority? Which prices can become collateral truth? Which upgrade or governance paths can compress observation, approval, and execution into one exploitable window? Which invariants are only true when markets behave politely?
The teams that survive do not "handle flash loans" as a special case. They remove the design shortcuts that make flash loans profitable in the first place.
If one block can decide too much in your protocol, the attacker does not need brilliance. They just need liquidity.
ChainShield Discovery Runs are designed to identify high-risk issues quickly, validate what matters, and give engineering teams a faster path to remediation.
Request Security Quote