VRF7
HomeGuides › Flash Loan Attacks Explained (With Real Examples)

Flash Loan Attacks Explained (With Real Examples)

Updated 2026-06-18 · VRF7 Security Guides

A flash loan attack is not a single vulnerability. It is an economic exploit that uses uncollateralized, atomic borrowing to amplify an underlying weakness in a smart contract — usually a manipulable price source, a flawed invariant, or a logic error that only becomes profitable at large scale. Understanding the attack requires understanding both the tool (flash loans) and the weakness it exposes.

How Flash Loans Work

A flash loan is a loan that is borrowed and repaid within a single transaction. Because Ethereum's EVM executes a transaction atomically, the lender can enforce repayment at the end of that same call stack. If the borrower does not return the principal plus fee before the transaction completes, the entire transaction reverts, leaving the lender's funds untouched.

Protocols like Aave, dYdX, and Uniswap V3 all expose flash loan or flash swap primitives. In Aave V3, the interface looks roughly like this:

// Aave V3 flash loan callback (simplified)
function executeOperation(
    address[] calldata assets,
    uint256[] calldata amounts,
    uint256[] calldata premiums,
    address initiator,
    bytes calldata params
) external returns (bool) {
    // Use borrowed assets here
    // Must approve pool to pull back amounts[i] + premiums[i]
    return true;
}

There is no credit check and no collateral required. Any address — including a freshly deployed contract — can borrow millions of dollars worth of tokens for the duration of one block. This is not inherently dangerous, but it removes capital as a barrier to entry for attackers.

Why Flash Loans Amplify Other Vulnerabilities

Flash loans do not create vulnerabilities. They fund them. An attacker who finds a logic flaw or a manipulable price oracle in your contract might lack the capital to make the exploit profitable. A flash loan eliminates that barrier entirely, turning a theoretical weakness into a practical one-transaction theft.

The two most common attack chains are:

Notable Real-World Flash Loan Attacks

bZx (February 2020) — $350,000 and $600,000

This was one of the first widely publicized flash loan attacks and it set the template. In the first attack, the attacker borrowed 10,000 ETH from dYdX, used part of it to open a leveraged short on bZx (which borrowed WBTC internally), then dumped ETH on Kyber to crash the ETH/WBTC rate, allowing the short to close profitably. The second attack a few days later manipulated the sUSD price on Kyber to allow cheap borrowing on bZx. Both exploits required no code vulnerability in the traditional sense — they were economic attacks made possible by bZx reading a manipulable spot price.

Pancake Bunny (May 2021) — ~$45 Million

The attacker flash-borrowed a large amount of BNB from PancakeSwap, used it to pump the BNB/BUNNY price on the AMM, triggered a BUNNY minting function inside Pancake Bunny that read that inflated price, dumped the newly minted BUNNY, then repaid the flash loan. The root cause was a price oracle that read directly from an AMM pool that could be manipulated within a single transaction.

Cream Finance (October 2021) — $130 Million

This attack exploited Cream's use of its own crETH token price, which was calculated from its exchange rate rather than an external price feed. The attacker used recursive borrowing and flash loans to manipulate the exchange rate, then used the inflated collateral value to drain the protocol. This is an example of a share-price or exchange-rate oracle vulnerability rather than an AMM spot-price vulnerability.

Euler Finance (March 2023) — $197 Million

The Euler attack was more complex. It exploited a flaw in Euler's donation mechanism combined with a liquidation logic error. Flash loans allowed the attacker to build up a large leveraged position, donate to the reserves in a way that made their position appear insolvent, then self-liquidate at a discount that extracted more collateral than the debt being cleared. The attacker recovered funds later, but the exploit demonstrated that flash loans can make even subtle accounting bugs catastrophically expensive.

The Core Vulnerable Pattern: Spot Price Oracles

The single most common enabler of flash loan attacks is reading a token price from an AMM spot reserve during the same transaction in which those reserves can be manipulated. Here is a simplified example of a vulnerable lending function:

// VULNERABLE: reads spot price from Uniswap pair
function getPrice(address token) internal view returns (uint256) {
    (uint112 reserve0, uint112 reserve1,) = IUniswapV2Pair(pair).getReserves();
    return uint256(reserve1) * 1e18 / uint256(reserve0);
}

function borrow(uint256 tokenAmount) external {
    uint256 price = getPrice(collateralToken);
    uint256 collateralValue = collateralBalances[msg.sender] * price / 1e18;
    require(collateralValue >= tokenAmount * minCollateralRatio / 100);
    // transfer tokenAmount to msg.sender
}

An attacker can flash-borrow a large amount of the collateral token, dump it into the pair to inflate reserve0 relative to reserve1, call borrow with the manipulated price, then restore the pair price and repay the flash loan — all in one transaction.

For a deeper treatment of oracle vulnerabilities and their mitigations, see Price Oracle Manipulation Attacks.

Defenses Against Flash Loan Attacks

Use TWAP Oracles

A time-weighted average price (TWAP) oracle, such as the one built into Uniswap V2 and V3, computes the average price over a window of blocks. Because a flash loan exists only within a single block, it cannot move a TWAP over any meaningful window. A 30-minute TWAP window is a standard minimum; longer windows provide more manipulation resistance at the cost of slower price updates.

// Uniswap V3 TWAP (simplified)
function getTWAP(address pool, uint32 twapInterval)
    internal view returns (uint256 price)
{
    uint32[] memory secondsAgo = new uint32[](2);
    secondsAgo[0] = twapInterval;
    secondsAgo[1] = 0;
    (int56[] memory tickCumulatives,) =
        IUniswapV3Pool(pool).observe(secondsAgo);
    int56 tickDelta = tickCumulatives[1] - tickCumulatives[0];
    int24 meanTick = int24(tickDelta / int56(uint56(twapInterval)));
    price = TickMath.getSqrtRatioAtTick(meanTick);
}

For critical price feeds, supplement on-chain TWAPs with a decentralized oracle network like Chainlink. A dual-source check — requiring both sources to agree within a tolerance — is significantly more robust than either alone.

Reentrancy Guards and Checks-Effects-Interactions

Flash loan callbacks re-enter your contract. Any function that updates state after an external call is a candidate for reentrancy. Apply OpenZeppelin's ReentrancyGuard to all state-mutating functions and follow the checks-effects-interactions pattern rigorously. For more on this, see Reentrancy Attacks in Solidity: How They Work and How to Prevent Them.

Validate Invariants Explicitly

Rather than trusting that extreme inputs are impossible, assert your protocol's invariants at the end of sensitive functions. If your collateralization ratio must stay above 1.5x, check it explicitly before any state-changing operation completes. Fuzz testing with tools like Echidna is particularly effective at finding inputs — including flash-loan-scale values — that break these invariants.

Use Read-Only Reentrancy Guards for View Functions

Protocols that read state from another DeFi protocol mid-transaction are vulnerable to read-only reentrancy. If Protocol B reads a price from Protocol A's view function while Protocol A is in the middle of a callback, it may read an intermediate, manipulated state. The mitigation is to check that the source protocol is not currently in a reentrant state before reading from it.

Circuit Breakers and Rate Limiting

Limit the maximum amount that can be borrowed, withdrawn, or minted in a single block or transaction. This does not prevent all attacks, but it caps the damage from any single exploit and gives monitoring systems time to respond.

What Automated Tools Can and Cannot Catch

Static analysis tools like Slither can reliably detect spot-price oracle patterns, missing reentrancy guards, and certain arithmetic issues. Symbolic execution tools like Mythril can find reachable states that violate assertions. Fuzz testing with Echidna can discover invariant violations at scale. However, economic attacks that are logically valid but financially destructive — like the Euler Finance exploit — often require manual reasoning about protocol-level incentives and game theory. No automated tool will catch every flash loan attack vector.

That said, running automated analysis before deployment catches the patterns that underlie most attacks: manipulable oracles, missing guards, and broken invariants. You can run an automated scan against your contract to identify these structural weaknesses before they reach mainnet. VRF7 runs tools including Slither, Mythril, and Echidna in parallel and attributes each finding to the tool that produced it, so you know exactly what was checked and how.

If your protocol issues or interacts with ERC-20 tokens, also review the How to Audit an ERC-20 Token Contract guide, since token-level flaws in balance accounting and approval logic are frequent flash loan attack components.

Summary

Flash loans are not a vulnerability. They are a capital-amplification tool that makes pre-existing vulnerabilities exploitable by anyone. The most important defensive steps are: eliminate spot-price oracle dependencies, enforce protocol invariants explicitly, apply reentrancy protection everywhere external calls occur, and test at realistic capital scales using fuzzing. Structural weaknesses that look harmless at small values are frequently catastrophic when millions of dollars of borrowed capital are applied to them in a single atomic transaction.

Scan your contract before you ship

Run an automated, transparent security scan — seven industry tools in parallel, every finding labeled with its source tool. It is not a substitute for a full manual audit, but it is a fast first line of defense.

Scan a contract

Frequently asked questions

Can a flash loan attack be executed by anyone, or does it require advanced skills?

Flash loan attacks require meaningful technical skill: the attacker must write a smart contract that coordinates the borrow, the exploit steps, and the repayment atomically. However, once a successful exploit contract exists, it can be copied and redeployed by others with far less expertise. The capital barrier is zero — the skill barrier is moderate but falling as tooling improves.

Does adding a reentrancy guard fully protect against flash loan attacks?

No. A reentrancy guard prevents a specific class of callback-based exploits, but most flash loan attacks do not rely on reentrancy. They exploit oracle manipulation or economic logic flaws that execute in a straightforward linear sequence. You need reentrancy guards, but they are not sufficient on their own. Oracle design and invariant validation are equally important.

Are TWAP oracles completely safe against flash loan manipulation?

TWAP oracles are highly resistant to single-block flash loan manipulation because the attacker cannot sustain a manipulated price across the observation window without holding the position across multiple blocks, which requires real capital and exposes them to arbitrage. However, a TWAP can still be manipulated over time with sustained capital, particularly in low-liquidity pools. Using a well-capitalized pool and a sufficient time window — at least 30 minutes — significantly reduces risk. For high-value applications, combining a TWAP with a decentralized oracle network provides stronger guarantees.

Why did some flash loan attackers return funds, as in the Euler Finance case?

In the Euler Finance case, the attacker eventually returned approximately $177 million of the $197 million taken, likely due to on-chain negotiation, the possibility of being identified, and the legal risk of keeping stolen funds. This is not a reliable outcome. Protocol teams should not build any assumption of fund recovery into their security posture. The Ronin Bridge and many other exploits resulted in permanent loss.

What is the difference between a flash loan attack and a flash loan exploit?

The terms are used interchangeably in practice. Some writers use 'flash loan attack' to describe the overall category and 'flash loan exploit' to emphasize that the flash loan is a tool rather than the root cause vulnerability. In both cases, the attacker borrows capital atomically to amplify an underlying flaw in a target protocol.