Part 2 β Module 5: Flash Loans
Difficulty: Intermediate
Estimated reading time: ~30 minutes | Exercises: ~2-3 hours
π Table of Contents
Flash Loan Mechanics
- The Atomic Guarantee
- Flash Loan Providers
- Read: Aave FlashLoanLogic.sol
- Read: Balancer FlashLoans
- Exercises
Composing Flash Loan Strategies
- Strategy 1: DEX Arbitrage
- Strategy 2: Flash Loan Liquidation
- Strategy 3: Collateral Swap
- Strategy 4: Leverage/Deleverage
- Exercises
Security, Anti-Patterns, and the Bigger Picture
- Flash Loan Security for Protocol Builders
- Flash Loan Receiver Security
- Flash Loans vs Flash Accounting
- Governance Attacks via Flash Loans
- Common Mistakes
- Exercises
π‘ Flash Loan Mechanics
Flash loans are DeFiβs most counterintuitive innovation: uncollateralized loans of unlimited size that must be repaid within a single transaction. If repayment fails, the entire transaction reverts β as if nothing happened.
This matters because it eliminates capital requirements for operations that are inherently profitable within a single atomic step. Before flash loans, liquidating an underwater Aave position required holding enough capital to repay the debt. After flash loans, anyone can liquidate any position. Before flash loans, arbitraging a price discrepancy between two DEXes required capital proportional to the opportunity. After flash loans, a developer with $0 and a smart contract can capture a $100,000 arbitrage.
Flash loans are also the primary tool used in oracle manipulation attacks (Module 3) and are integral to the liquidation flows you studied in Module 4. This module teaches you to use them offensively (arbitrage, liquidation, collateral swaps) and defend against them.
π» Quick Try:
Before diving into providers and callbacks, feel the atomic guarantee on a mainnet fork:
// In a Foundry test:
// 1. Flash-borrow 1M USDC from Balancer Vault (0x BA12222222228d8Ba445958a75a0704d566BF2C8)
// 2. In the callback, check your USDC balance β you're a temporary millionaire
// 3. Transfer amount back to the Vault
// 4. Watch it succeed. Now try returning 1 USDC less β watch the entire tx revert
// That revert IS the atomic guarantee. The million dollars never moved.
π‘ Concept: The Atomic Guarantee
A flash loan works because of Ethereumβs transaction model: either every operation in a transaction succeeds, or the entire transaction reverts. The flash loan provider transfers tokens to your contract, calls your callback function, then checks that the tokens (plus a fee) have been returned. If the check fails, the whole transaction unwinds.
1. Your contract calls Provider.flashLoan(amount)
2. Provider transfers `amount` to your contract
3. Provider calls your contract's callback function
4. Your contract executes arbitrary logic (arbitrage, liquidation, etc.)
5. Your contract approves/transfers amount + fee back to Provider
6. Provider verifies repayment
7. If insufficient: entire transaction reverts (including step 2)
The key insight: from the blockchainβs perspective, if repayment fails, the loan never happened. No tokens moved. No state changed. The borrower only pays gas for the failed transaction.
π Deep Dive: The Flash Loan Callback Flow
Single Ethereum Transaction
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Your Contract Flash Loan Provider β
β ββββββββββββ βββββββββββββββββββ β
β β β β
β β βββββ flashLoan(amount) βββββ β
β β β β
β β β‘ Provider transfers β β
β ββββββ amount tokens ββββββββ β
β β β β
β β β’ Provider calls β β
β ββββ your callback() ββββββββ β
β β β β
β β£ β βββββββββββββββββββββββ β β
β β β YOUR LOGIC HERE: β β β
β β β β’ Swap on DEX β β β
β β β β’ Liquidate on Aave β β β
β β β β’ Collateral swap β β β
β β β β’ Anything atomic β β β
β β βββββββββββββββββββββββ β β
β β β β
β β€ βββ approve(amount + fee) βββ β
β β β β
β β β₯ Provider pulls β β
β β amount + fee β β
β β β Repaid β tx succeeds β β
β β β Short β ENTIRE TX β β
β β REVERTS (steps 1-5 β β
β β never happened) β β
β β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The critical property: Steps β‘-β€ all happen within a single EVM call stack. The provider checks repayment at β₯ β if it fails, the EVM unwinds everything. This is why flash loans are βrisk-freeβ for the provider: they either get repaid or the loan never existed.
π‘ Concept: Flash Loan Providers
Aave V3 β The original and most widely used.
Two functions:
flashLoanSimple(receiverAddress, asset, amount, params, referralCode)β single asset, simpler interface, slightly cheaper gasflashLoan(receiverAddress, assets[], amounts[], modes[], onBehalfOf, params, referralCode)β multiple assets simultaneously, with the option to convert the flash loan into a regular borrow (by settingmodes[i] = 1or2for variable/stable rate)
Callback: executeOperation(asset, amount, premium, initiator, params) must return true.
Fee: 0.05% (_flashLoanPremiumTotal = 5 bps). Waived for addresses granted the FLASH_BORROWER role by governance.
Premium split: A portion goes to the protocol treasury (_flashLoanPremiumToProtocol = 4 bps), the rest accrues to suppliers.
Liquidity: Limited to whatβs currently supplied and unborrowed in Aave pools. On Ethereum mainnet, this is billions of dollars across major assets.
Balancer V2 β Zero-fee flash loans.
The Balancer Vault holds all tokens for all pools in a single contract. This consolidated liquidity is available as flash loans.
function flashLoan(
IFlashLoanRecipient recipient,
IERC20[] memory tokens,
uint256[] memory amounts,
bytes memory userData
) external;
Callback: receiveFlashLoan(tokens[], amounts[], feeAmounts[], userData).
Fee: 0% (governance-set, currently zero). This makes Balancer the cheapest source for flash loans.
Security: Your callback must verify msg.sender == vault. Balancerβs Vault holds over a billion dollars in liquidity.
Uniswap V2 β Flash Swaps
Uniswap V2 pairs support βoptimistic transfersβ β the pair sends you tokens before verifying the invariant. You can either:
- Return the same tokens (a standard flash loan)
- Return a different token (a flash swap β you receive token0 and pay back in token1)
The pairβs swap() function sends tokens to the to address, then calls uniswapV2Call(sender, amount0, amount1, data) if data.length > 0. After the callback, the pair verifies the constant product invariant holds (accounting for the 0.3% fee).
Fee: Effectively ~0.3% (same as swap fee), since the invariant check includes fees.
Uniswap V4 β Flash Accounting
V4 doesnβt have a dedicated βflash loanβ function. Instead, flash loans are a natural consequence of the flash accounting system you studied in Module 2:
- Unlock the PoolManager
- Inside
unlockCallback, perform any operations (swaps, liquidity changes) - All operations track internal deltas using transient storage
- At the end, settle all deltas to zero
You can effectively βborrowβ by creating a negative delta, using the tokens, then settling. This is more flexible than a dedicated flash loan function because it composes natively with swaps and liquidity operations β all within the same unlock context. No separate fee for the flash component; you pay whatever fees apply to the operations you perform.
ERC-3156: The Flash Loan Standard
ERC-3156 standardizes the flash loan interface so borrowers can write provider-agnostic code:
flashLoan(receiver, token, amount, data)on the lenderonFlashLoan(initiator, token, amount, fee, data)callback on the receivermaxFlashLoan(token)andflashFee(token, amount)for discovery
Not all providers implement ERC-3156 (Aave and Balancer have their own interfaces), but itβs the standard for simpler flash loan providers. In practice, most production flash loan code targets Aave or Balancer directly because they have the deepest liquidity. ERC-3156 is most useful when building provider-agnostic tooling (e.g., a flash loan aggregator that routes to the cheapest available source) or when integrating with smaller lending protocols that implement the standard. OpenZeppelin provides an ERC-3156 implementation you can use as a reference.
DAI Flash Mint β MakerDAOβs DssFlash module lets anyone mint unlimited DAI via flash loan β not from a pool, but minted from thin air and burned at the end. This is unique: the liquidity isnβt constrained by pool deposits. DAI is minted in the Vat, used, and burned within the same tx. Fee: 0%. This is possible because DAI is protocol-issued (see Module 6 β CDPs mint stablecoins into existence).
π Connection: The flash mint concept connects to Module 6 β a CDP stablecoin can offer infinite flash liquidity because the protocol controls issuance. Your Part 2 Module 9 capstone stablecoin includes a flash mint feature, and Part 3 Module 9 (Perpetual Exchange capstone) builds on these composability patterns.
π Read: Aave FlashLoanLogic.sol
Source: aave-v3-core/contracts/protocol/libraries/logic/FlashLoanLogic.sol
Trace executeFlashLoanSimple():
- Validates the reserve is active and flash-loan-enabled
- Computes premium:
amount Γ flashLoanPremiumTotal / 10000 - Transfers the requested amount to the receiver via
IAToken.transferUnderlyingTo() - Calls
receiver.executeOperation(asset, amount, premium, initiator, params) - Verifies the receiver returned
true - Pulls
amount + premiumfrom the receiver (receiver must have approved the Pool) - Mints premium to the aToken (accrues to suppliers) and to treasury
Key security observation: The premium calculation happens before the callback. The receiver knows exactly how much it needs to repay. Thereβs no reentrancy risk here because the Pool does the final pull after the callback returns.
Also read executeFlashLoan() (the multi-asset version). Note the modes[] parameter: mode 0 = repay, mode 1 = open variable debt, mode 2 = open stable debt. This enables a pattern where you flash-borrow an asset and convert it into a collateralized borrow in the same transaction β useful for collateral swaps and leverage.
π Read: Balancer FlashLoans
Source: Balancer V2 Vault flashLoan() implementation.
Simpler than Aaveβs because there are no interest rate modes. The Vault:
- Transfers tokens to the recipient
- Calls
receiveFlashLoan() - After callback, checks that the Vaultβs balance of each token has increased by at least
feeAmount(currently 0)
Balancer V3 introduces a transient unlock model similar to V4βs flash accounting β the Vault must be βunlockedβ and balances must be settled before the transaction ends.
π How to Study Flash Loan Provider Code
-
Start with the interface β Read
IFlashLoanSimpleReceiver(Aave) orIFlashLoanRecipient(Balancer). These tell you exactly what your callback must implement. Map the parameters: what data flows in, what the provider expects back. -
Trace the providerβs flow in 3 steps β Every flash loan provider follows the same pattern: (a) transfer tokens out, (b) call your callback, (c) verify repayment. In Aaveβs FlashLoanLogic.sol, find these three steps in
executeFlashLoanSimple(). Note how the premium is computed before the callback β your contract knows exactly what to repay. -
Read the repayment verification β This is where providers differ. Aave pulls tokens via
transferFrom(you must approve). Balancer checks its own balance increased. Uniswap V2 verifies the constant product invariant. Understanding the verification mechanism tells you what your callback must do to succeed. -
Study the
modes[]parameter (Aave only) β In the multi-assetflashLoan(), mode 0 = repay, mode 1 = open variable debt, mode 2 = open stable debt. This enables βflash borrow and keepβ patterns (collateral swap, leverage). This parameter doesnβt exist in Balancer or Uniswap. -
Compare gas costs β Deploy identical flash loans on an Aave fork vs Balancer fork. The gas difference comes from: Aaveβs premium calculation + aToken mint + index update vs Balancerβs simpler balance check. This informs your provider choice in production.
Donβt get stuck on: Aaveβs referral code system or Balancerβs internal token accounting beyond the flash loan flow. Focus on the borrow β callback β repay cycle.
π― Build Exercise: Flash Loan Mechanics
Workspace: workspace/src/part2/module5/exercise1-flash-loan-receiver/ β starter file: FlashLoanReceiver.sol, tests: FlashLoanReceiver.t.sol
Exercise 1 β FlashLoanReceiver: Build a minimal Aave V3-style flash loan receiver that borrows tokens, validates the callback (both msg.sender and initiator), approves repayment, and tracks premiums paid. Also implement a rescueTokens function to sweep any accidentally stuck tokens β reinforcing the βnever store fundsβ principle.
- Implement
requestFlashLoan(owner-only, initiates the flash loan) - Implement
executeOperation(callback security checks + approve repayment) - Implement
rescueTokens(owner-only safety net) - Tests verify: correct premium accounting, cumulative tracking across multiple loans, callback validation, access control, and zero contract balance after every operation
Stretch: Build a Balancer flash loan receiver that borrows the same amount. Compare the callback pattern β Balancer checks balance increase (you transfer) vs Aave uses transferFrom (you approve). Verify the fee is 0.
πΌ Job Market Context
What DeFi teams expect you to know:
-
βExplain the flash loan callback patternβ
- Good answer: Provider sends tokens, calls your callback, then verifies repayment
- Great answer: Itβs a borrow-callback-verify pattern where atomicity guarantees zero risk for the provider. The key differences between providers: Aave uses
transferFrom(you must approve), Balancer checks its own balance increased, Uniswap V2 verifies the constant product invariant. Aaveβsmodes[]parameter lets you convert a flash loan into a collateralized borrow β thatβs how collateral swaps work.
-
βHow do you choose between flash loan providers?β
- Good answer: Compare fees β Balancer is free, Aave is 5 bps
- Great answer: Fee is just one factor. Balancer V2 is cheapest (0%) but liquidity depends on pool composition. Aave has the deepest liquidity for major assets. Uniswap V2 is expensive (~0.3%) but available per-pair without pool dependencies. V4 flash accounting is the most flexible β no separate flash loan needed, it composes natively with swaps. For production, youβd check available liquidity across providers and route to the cheapest with sufficient depth.
Interview Red Flags:
- π© Thinking flash loans create risk for the provider (theyβre zero-risk by construction)
- π© Not knowing Balancer offers zero-fee flash loans
- π© Confusing Uniswap V2 flash swaps with Aave-style flash loans (different repayment mechanics)
Pro tip: In interviews, emphasize that flash loans arenβt just about arbitrage β theyβre a composability primitive. The collateral swap pattern (flash borrow β repay debt β withdraw β swap β redeposit β re-borrow β repay flash) is the most interview-relevant use case because it demonstrates deep understanding of lending mechanics.
π Summary: Flash Loan Mechanics
β Covered:
- The atomic guarantee: borrow β callback β repay or entire tx reverts
- Four providers: Aave V3 (0.05%), Balancer V2 (0%), Uniswap V2 (~0.3%), Uniswap V4 (flash accounting)
- Callback interfaces:
executeOperation(Aave),receiveFlashLoan(Balancer),uniswapV2Call(V2) - Code reading strategy for flash loan provider internals
- Aaveβs
modes[]parameter: repay vs convert to debt position
Next: Composing multi-step strategies β arbitrage, liquidation, collateral swap, leverage
π‘ Composing Flash Loan Strategies
π» Quick Try:
Before building arbitrage contracts, see a price discrepancy with your own eyes. On a mainnet fork, query the same swap on two different DEXes:
interface IUniswapV2Router {
function getAmountsOut(uint256 amountIn, address[] calldata path)
external view returns (uint256[] memory amounts);
}
function testSpotPriceDifference() public {
address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
IUniswapV2Router uniV2 = IUniswapV2Router(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
IUniswapV2Router sushi = IUniswapV2Router(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
address[] memory path = new address[](2);
path[0] = WETH;
path[1] = USDC;
uint256 amountIn = 10 ether; // 10 WETH
uint256[] memory uniOut = uniV2.getAmountsOut(amountIn, path);
uint256[] memory sushiOut = sushi.getAmountsOut(amountIn, path);
emit log_named_uint("Uniswap V2: 10 WETH -> USDC", uniOut[1]);
emit log_named_uint("Sushiswap: 10 WETH -> USDC", sushiOut[1]);
// Any difference here is a potential arbitrage opportunity
// In practice, MEV bots keep these within ~0.01% of each other
}
Run with forge test --match-test testSpotPriceDifference --fork-url $ETH_RPC_URL -vv. Youβll likely see very similar prices β MEV bots keep them aligned. But during volatility, gaps appear briefly. Thatβs where flash loan arbitrage lives.
π‘ Concept: Strategy 1: DEX Arbitrage
The classic flash loan use case: a price discrepancy between two DEXes.
The flow:
- Flash-borrow Token A from Aave/Balancer
- Swap Token A β Token B on DEX1 (where A is expensive / B is cheap)
- Swap Token B β Token A on DEX2 (where B is expensive / A is cheap)
- Repay flash loan + fee
- Keep the profit (if any)
Why this is harder than it sounds:
- Price discrepancies are detected and captured by MEV bots within milliseconds
- Gas costs eat into thin margins
- Slippage on larger trades reduces profitability
- Frontrunning: your transaction sits in the mempool where MEV searchers can see it and extract the opportunity first (Flashbots private transactions mitigate this)
Build: FlashLoanArbitrage
The key architectural decision: your executeArbitrage function encodes the strategy parameters (which DEXs, which intermediate token, minimum profit) into bytes and passes them through the flash loanβs params argument. The callback decodes them to execute the two-leg swap. This encode/decode pattern is how every real flash loan strategy passes information across the callback boundary.
Think about: how do you enforce that the arbitrage is actually profitable before committing? Where in the callback do you check minProfit? What happens to any remaining tokens after repayment?
Workspace exercise: The full scaffold with TODOs is in FlashLoanArbitrage.sol.
π Deep Dive: Arbitrage Profit Calculation
Scenario: WETH is $2,000 on DEX1 and $2,020 on DEX2 (1% discrepancy)
Flash borrow: 100 WETH from Balancer (0% fee)
Step 1: Sell 100 WETH on DEX2 (expensive side)
β Receive: 100 Γ $2,020 = $202,000 USDC
β After 0.3% swap fee: $202,000 Γ 0.997 = $201,394 USDC
Step 2: Buy WETH on DEX1 (cheap side) with enough to repay
β Need: 100 WETH to repay flash loan
β Cost: 100 Γ $2,000 = $200,000 USDC
β After 0.3% swap fee: $200,000 / 0.997 = $200,601 USDC
Step 3: Repay flash loan
β Return: 100 WETH to Balancer (0 fee)
Profit = $201,394 - $200,601 = $793 USDC
Gas cost β ~$5-50 (depending on network)
Net profit β ~$743-788
Reality check:
- Slippage on 100 WETH ($200K) would be significant
- MEV bots detect this in milliseconds
- Real arb opportunities are usually < 0.1% and last < 1 block
- Most profit goes to MEV searchers via Flashbots bundles
π Connection: MEV extraction from these opportunities is covered in depth in Part 3 Module 5 (MEV). Searchers, builders, and the PBS supply chain determine who actually captures this profit.
π‘ How MEV Searchers Actually Use Flash Loans
In practice, profitable flash loan arbitrage isnβt done by humans submitting transactions to the mempool:
- Searchers run bots that monitor pending transactions and DEX state for opportunities
- They build a bundle: flash borrow β arb swaps β repay β profit, as a single transaction
- They submit the bundle to Flashbots Protect or block builders directly (not the public mempool)
- They bid most of the profit to the builder as a tip (often 90%+)
- The builder includes the bundle in their block
The searcher keeps a thin margin. The builder captures most of the MEV. This is why the arbitrage profit from the example above ($793) would net the searcher maybe $50-100 after builder tips. The economics only work at scale with hundreds of opportunities per day.
π‘ Concept: Strategy 2: Flash Loan Liquidation
You built a basic liquidation in Module 4. Now do it with zero capital:
The flow:
- Identify an underwater position on Aave (HF < 1)
- Flash-borrow the debt asset (e.g., USDC) from Balancer (0 fee) or Aave
- Call
Pool.liquidationCall()β repay the debt, receive collateral at discount - Swap the received collateral β debt asset on a DEX
- Repay the flash loan
- Keep the profit (liquidation bonus minus swap fees minus flash loan fee)
Build: FlashLoanLiquidator.sol
Implement a contract that:
- Takes flash loan from Balancer (zero fee)
- Executes Aave liquidation
- Swaps collateral to debt asset via Uniswap V3 (use exact input swap for simplicity)
- Repays Balancer
- Sends profit to caller
π Deep Dive: Flash Loan Liquidation Profit β Numeric Walkthrough
Setup:
Borrower: 10 ETH collateral ($2,000/ETH = $20,000), 16,500 USDC debt
ETH LT = 82.5% β HF = ($20,000 Γ 0.825) / $16,500 = 1.0 (exactly at threshold)
ETH drops to $1,900 β HF = ($19,000 Γ 0.825) / $16,500 = 0.95 β liquidatable!
Liquidation bonus = 5%, Close factor = 50% (HF β₯ 0.95)
Step 1: Flash borrow from Balancer (0% fee)
Borrow: 8,250 USDC (50% of $16,500 debt)
Cost: $0
Step 2: Call Aave liquidationCall()
Repay: 8,250 USDC of borrower's debt
Receive: $8,250 Γ 1.05 / $1,900 = 4.5592 ETH (includes 5% bonus)
Step 3: Swap ETH β USDC on Uniswap V3 (0.3% fee pool)
Sell: 4.5592 ETH at $1,900
Gross: 4.5592 Γ $1,900 = $8,662.48
After 0.3% swap fee: $8,662.48 Γ 0.997 = $8,636.49 USDC
Step 4: Repay Balancer flash loan
Repay: 8,250 USDC (0% fee)
Profit = $8,636.49 - $8,250 = $386.49 USDC
Gas cost β ~$5-30
Net profit β ~$356-381
Breakeven analysis:
Minimum liquidation bonus for profitability:
bonus > swap_fee / (1 - swap_fee) = 0.003 / 0.997 β 0.3%
With Aave's 5% bonus, this is profitable even with significant slippage.
Using Aave flash loan instead (0.05% fee):
Flash loan cost = 8,250 Γ 0.0005 = $4.13
Net profit = $386.49 - $4.13 = $382.36
Savings from Balancer: only $4.13 β but at scale, this adds up.
Test on mainnet fork:
- Set up an Aave position near liquidation (supply ETH, borrow USDC at max LTV)
- Use
vm.mockCallto drop ETH price below liquidation threshold - Execute the flash loan liquidation
- Verify: profit = (collateral seized Γ collateral price Γ (1 + liquidation bonus)) - debt repaid - swap fees
π‘ Concept: Strategy 3: Collateral Swap
A user has ETH collateral backing a USDC loan on Aave, but wants to switch to WBTC collateral without closing the position.
Without flash loans: Repay entire USDC debt β withdraw ETH β swap ETH to WBTC β deposit WBTC β re-borrow USDC. Requires capital to repay the debt first.
With flash loans:
- Flash-borrow USDC equal to the debt
- Repay the entire USDC debt on Aave
- Withdraw ETH collateral (now possible because debt is zero)
- Swap ETH β WBTC on Uniswap
- Deposit WBTC as new collateral on Aave
- Re-borrow USDC from Aave (against new collateral)
- Repay flash loan with the re-borrowed USDC + use existing USDC for the premium
This is Aaveβs βliquidity switchβ pattern β one of the primary production uses of flash loans.
Build: CollateralSwap.sol
This is the most complex composition β and the most interview-relevant. It touches lending (repay, withdraw, deposit, borrow) and swapping, all within a single flash loan callback.
The 6-step callback pattern:
Flash borrow debt asset (e.g., USDC)
β
ββ Step 1: Repay user's entire debt on lending pool
β (we have the tokens from the flash loan)
β
ββ Step 2: Pull user's aTokens, then withdraw old collateral
β (withdraw burns aTokens from msg.sender)
β
ββ Step 3: Swap old collateral β new collateral on DEX
β
ββ Step 4: Deposit new collateral into lending pool for user
β (supply on behalf of user β they receive aTokens)
β
ββ Step 5: Borrow debt asset on behalf of user (credit delegation)
β to cover the flash loan repayment
β
ββ Step 6: Approve flash pool to pull amount + premium
Key prerequisite: The user must set up two delegations before calling this contract:
aToken.approve(collateralSwap, amount)β so the contract can withdraw their collateralvariableDebtToken.approveDelegation(collateralSwap, amount)β so the contract can borrow on their behalf
This delegation pattern is critical for interview discussions β it shows you understand Aaveβs credit delegation system.
Workspace exercise: The full scaffold with TODOs is in CollateralSwap.sol.
π‘ Concept: Strategy 4: Leverage/Deleverage in One Transaction
Leveraging up: A user wants 3x long ETH exposure.
- Flash-borrow ETH
- Deposit all ETH as collateral on Aave
- Borrow USDC against the collateral
- Swap USDC β ETH
- Deposit additional ETH as collateral
- Repeat steps 3-5 (or do it in calculated amounts)
- Final borrow covers the flash loan repayment
In practice, you calculate the exact amounts needed for the desired leverage ratio and do it in one step rather than looping.
Deleveraging: Reverse the process β flash-borrow to repay debt, withdraw collateral, swap to repay the flash loan.
π Deep Dive: Leverage β Numeric Walkthrough
Goal: 3x long ETH exposure starting with 10 ETH ($2,000/ETH = $20,000)
Aave ETH: max LTV = 80% (borrow limit), LT = 82.5% (liquidation threshold)
Remember: you BORROW up to max LTV, but HF uses LT (see Module 4).
Without flash loans (manual looping):
Round 1: Deposit 10 ETH β Borrow $16,000 USDC β Buy 8 ETH
Round 2: Deposit 8 ETH β Borrow $12,800 USDC β Buy 6.4 ETH
Round 3: Deposit 6.4 ETH β Borrow $10,240 USDC β Buy 5.12 ETH
... (converges after many rounds, each with gas + swap fees)
With flash loans (one transaction):
Target: 30 ETH total exposure (3x of 10 ETH)
Need to deposit: 30 ETH
Need to borrow: 20 ETH worth of USDC = $40,000 USDC
Borrow check: $40,000 / $60,000 = 66.7% < 80% max LTV β (within borrow limit)
Health factor: ($60,000 Γ 0.825) / $40,000 = 1.24 β (healthy)
Step 1: Flash-borrow 20 ETH from Balancer (0% fee)
Now holding: 10 (own) + 20 (borrowed) = 30 ETH
Step 2: Deposit all 30 ETH into Aave
Collateral: 30 ETH ($60,000)
Step 3: Borrow $40,000 USDC from Aave against the collateral
Debt: $40,000 USDC
HF = ($60,000 Γ 0.825) / $40,000 = 1.24
Step 4: Swap $40,000 USDC β ~19.94 ETH on Uniswap V3 (0.3% fee)
$40,000 / $2,000 = 20 ETH Γ 0.997 = 19.94 ETH
Step 5: Repay Balancer flash loan (20 ETH)
Need: 20 ETH, Have: 19.94 ETH
Shortfall: 0.06 ETH ($120) β the swap fee cost
Fix: Borrow slightly more USDC in Step 3 to cover swap fees:
Borrow $40,120 USDC β Swap β 20.00 ETH β Repay β Done.
Updated HF = ($60,000 Γ 0.825) / $40,120 = 1.23 (still healthy)
Result:
Position: 30 ETH collateral, $40,120 debt
Effective leverage: ~3x
Cost: One tx gas + $120 in swap fees
If ETH +10%: Position gains $6,000 (30% on your 10 ETH)
If ETH -10%: Position loses $6,000 (30% on your 10 ETH)
Liquidation price: ~$1,621 ETH (-19% from $2,000)
β HF=1.0 when 30 Γ price Γ 0.825 = $40,120 β price = $1,621
Why flash loans matter here: Without them, youβd need 5+ loop iterations (each with gas costs and swap slippage). With a flash loan, itβs a single atomic operation β cheaper, cleaner, and no partial exposure during intermediate steps.
π― Build Exercise: Flash Loan Strategies
Workspace: workspace/src/part2/module5/exercise2-flash-loan-arbitrage/ β starter file: FlashLoanArbitrage.sol, tests: FlashLoanArbitrage.t.sol | Also: CollateralSwap.sol, tests: CollateralSwap.t.sol
Exercise 2 β FlashLoanArbitrage: Build a flash loan arbitrage contract that captures price discrepancies between two DEXs. This exercises the full composition pattern: flash borrow, encode/decode strategy params through the callback bytes, execute two-leg swap, enforce minimum profit, and sweep profit to the caller.
- Implement
executeArbitrage(encode params, request flash loan, sweep profit) - Implement
executeOperation(decode params, two DEX swaps, profitability check, approve repayment) - Tests verify: profitable arb with 1% spread,
minProfitenforcement, revert when spread is too small, callback security, fuzz testing across varying borrow amounts
Exercise 3 β CollateralSwap: Build the most complex flash loan composition: switch a userβs lending position from one collateral to another in a single atomic transaction. This is Aaveβs βliquidity switchβ pattern and the most interview-relevant use case.
- Implement
swapCollateral(encode SwapParams, request flash loan) - Implement
executeOperation(6-step callback: repay debt, pull aTokens + withdraw, swap on DEX, deposit new collateral, borrow on behalf of user via credit delegation, approve repayment) - Tests verify: complete position migration (old collateral to new), correct debt accounting (original + premium), prerequisite delegation checks, callback security
π Summary: Flash Loan Strategies
β Covered:
- Four composition strategies: DEX arbitrage, flash loan liquidation, collateral swap, leverage/deleverage
- Arbitrage: flash borrow β swap on DEX1 β swap on DEX2 β repay β keep profit
- Liquidation: flash borrow debt asset β liquidate on Aave β swap collateral β repay
- Collateral swap: flash borrow β repay debt β withdraw old collateral β swap β deposit new β re-borrow β repay flash
- Leverage: flash borrow β deposit β borrow β swap β deposit more β final borrow covers repayment
Next: Security considerations β both for protocol builders and flash loan receiver authors
β οΈ Security, Anti-Patterns, and the Bigger Picture
β οΈ Flash Loan Security for Protocol Builders
Flash loans donβt create vulnerabilities β they democratize access to capital for exploiting existing vulnerabilities. But as a protocol builder, you need to design for a world where any attacker has access to unlimited capital within a single transaction.
Rule 1: Never use spot prices as oracle. (Module 3 β reinforced here.) Flash loans make spot price manipulation essentially free. The attacker borrows millions, moves the price, exploits your protocol, and returns the loan. Cost to attacker: just gas.
Rule 2: Be careful with any state that can be manipulated and read in the same transaction. This includes:
- DEX reserve ratios (spot prices)
- Contract token balances (donation attacks)
- Share prices in vaults based on
totalAssets() / totalShares() - Governance voting power based on current token holdings
Rule 3: Time-based defenses. If an action depends on a value that can be flash-manipulated, require that the value was established in a previous block. TWAPs work because they span multiple blocks. Governance timelocks work because proposals canβt be executed immediately.
Rule 4: Use reentrancy guards on functions that manipulate critical state. Flash loans involve external calls (the callback). If your protocol interacts with flash-loaned funds, ensure reentrant calls canβt exploit intermediate states.
π Deep Dive: The bZx Attacks (February 2020) β Flash Loansβ Debut
The bZx attacks were the first major flash loan exploits, demonstrating what βunlimited capital in one txβ means for protocol security:
Attack 1 ($350K, Feb 14, 2020):
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Flash-borrow 10,000 ETH from dYdX β
β 2. Deposit 5,500 ETH in Compound as collateral β
β 3. Borrow 112 WBTC from Compound β
β 4. Send 1,300 ETH to bZx to open 5x short ETH/BTC β
β β bZx swaps on Uniswap, crashing ETH/BTC price β
β 5. Swap 112 WBTC β ETH on Uniswap at the crashed price β
β β Got MORE ETH than 112 WBTC was worth before β
β 6. Repay Compound, repay dYdX, keep profit β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
What went wrong: bZx used Uniswap spot price as its oracle.
The attacker manipulated that price with borrowed capital.
Cost to attacker: gas only (~$8). Profit: $350,000.
The lesson for protocol builders: This attack didnβt exploit a bug in flash loans β it exploited bZxβs reliance on a spot price oracle (Rule 1 above). Flash loans just made it free to execute. Every oracle manipulation attack youβll see in Module 3 postmortems follows this pattern: flash borrow β manipulate price β exploit protocol β repay.
π Study tip β Tracing real exploits: Use Tenderly or Phalcon by BlockSec to trace historical exploit transactions step-by-step. Paste the tx hash and youβll see every internal call, state change, and token transfer in order. For the bZx attack, trace this tx β youβll see the flash borrow from dYdX, the Compound interactions, the Uniswap price manipulation, and the profitable unwind all in a single call tree. This is the fastest way to internalize how flash loan compositions work in production.
β οΈ Flash Loan Receiver Security
When building flash loan receivers (your callback contracts), guard against:
Griefing attack: Never store funds in your flash loan receiver contract between transactions. An attacker could initiate a flash loan using your receiver as the target, and your stored funds would be used to repay the loan.
Initiator validation: In executeOperation, check that initiator == address(this) (or your expected caller). Without this, anyone can initiate a flash loan that calls your receiver, potentially manipulating your contractβs state.
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external override returns (bool) {
require(msg.sender == address(POOL), "Caller must be Pool");
require(initiator == address(this), "Initiator must be this contract");
// ... your logic
}
Parameter validation: The params bytes are arbitrary and user-controlled. If you decode them into addresses or amounts, validate everything. An attacker could craft params that route funds to their own address.
π‘ Concept: Flash Loans vs Flash Accounting: The Evolution
Flash loans (Aave, Balancer V2) are a specific feature: borrow tokens, use them, return them.
Flash accounting (Uniswap V4, Balancer V3) is a generalized pattern: all operations within an unlock context track internal deltas, and only net balances are settled. Flash loans are a subset of what flash accounting enables.
The evolution:
- 2020: Flash loans introduced by Aave β revolutionary but limited to borrow-use-repay
- 2021-23: Uniswap V2/V3 flash swaps β flash loans built into DEX operations
- 2024-25: V4 flash accounting + EIP-1153 transient storage β the pattern becomes the architecture. No separate βflash loanβ feature needed; the entire interaction model is flash-native
As a protocol builder, flash accounting is the pattern to understand deeply. Itβs more gas-efficient, more composable, and more flexible than dedicated flash loan functions. Youβll see this pattern adopted by more protocols going forward.
β οΈ Governance Attacks via Flash Loans
Some governance tokens allow voting based on current token holdings at the time of the vote. An attacker can:
- Flash-borrow governance tokens
- Vote on a malicious proposal (or create and immediately vote on one)
- Return the tokens
Defenses:
- Snapshot-based voting: Voting power is determined by holdings at a specific past block, not the current block. Flash-borrowed tokens have zero voting power because they werenβt held at the snapshot block.
- Timelocks: Even if a proposal passes, it canβt execute for N days, giving the community time to respond.
- Quorum requirements: High quorum thresholds make it expensive to flash-borrow enough tokens to pass a proposal.
Most modern governance systems (OpenZeppelin Governor, Compound Governor Bravo) use snapshot voting, making this attack vector largely mitigated. But be aware of it when evaluating protocols with simpler governance.
π Flash Loan Fee Comparison
| Provider | Fee | Multi-asset | Liquidity Source | Fee Waiver |
|---|---|---|---|---|
| Aave V3 | 0.05% (5 bps) | Yes (flashLoan) | Supply pools | FLASH_BORROWER role |
| Balancer V2 | 0% | Yes | All Vault pools | N/A (already free) |
| Uniswap V2 | ~0.3% | Per-pair | Pair reserves | No |
| Uniswap V4 | 0% (flash accounting) | Native | PoolManager | N/A |
| Compound V3 | N/A | N/A | N/A | No flash loan function |
Practical choice: For pure flash loans, Balancer V2 (zero fee) is optimal when it has sufficient liquidity in the asset you need. Aave V3 for maximum liquidity and multi-asset borrows. Uniswap V4 flash accounting for operations that combine swaps with temporary borrowing.
π Deep Dive: Provider Repayment Mechanisms Compared
How each provider verifies you repaid:
Aave V3:
callback returns β Pool calls transferFrom(receiver, pool, amount+premium)
You MUST approve the Pool before callback returns.
Premium goes to: aToken holders (suppliers) + protocol treasury.
Balancer V2:
callback returns β Vault checks: balanceOf(vault) β₯ pre_balance + feeAmount
You MUST transfer tokens TO the Vault inside your callback.
No approval needed β direct transfer.
Uniswap V2:
callback returns β Pair verifies: k_new β₯ k_old (constant product with fee)
You can repay in EITHER token (flash swap).
The 0.3% fee is implicit in the invariant check.
Uniswap V4 / Balancer V3:
unlockCallback returns β Manager checks: all deltas == 0
You settle via PoolManager.settle() or Vault.settle().
No separate "flash loan" β it's native to the delta system.
Key difference:
Aave/Balancer V2: explicit "flash loan" as a feature
V4/Balancer V3: flash borrowing is emergent from the accounting model
π― Build Exercise: Flash Loan Security
Workspace: workspace/src/part2/module5/exercise4-vault-donation/ β starter file: VaultDonationAttack.sol, tests: VaultDonationAttack.t.sol
Exercise 4 β VaultDonationAttack: Build a flash loan-powered vault donation attack that exploits the classic ERC-4626 share price inflation vulnerability. This puts you in the attackerβs shoes to understand why balanceOf-based asset accounting is dangerous and why the virtual shares/assets offset defense exists.
- Implement
executeAttack(encode params, request flash loan, sweep profit) - Implement
executeOperation(5-step attack: deposit 1 wei to become sole shareholder, donate remaining tokens to inflate share price, trigger victimβs harvest that rounds to 0 shares, withdraw everything, approve repayment) - Tests verify: attacker profits ~4,995 USDC from 5,000 USDC victim, victim gets 0 shares and 0 balance, vault is empty after withdrawal, attack contract holds nothing, flash pool gains premium
Stretch: Governance attack simulation. Deploy a simple governance contract with non-snapshot voting. Show how a flash loan can pass a malicious proposal. Then deploy an OpenZeppelin Governor with snapshot voting and verify the attack fails.
Stretch: Multi-provider composition. Build a contract that nests flash loans from different providers (e.g., Balancer + Aave). This tests your ability to manage nested callbacks and track which repayment is owed to which provider.
π Summary: Flash Loan Security
β Covered:
- Protocol builder security: never use spot prices, beware same-tx state manipulation, time-based defenses
- Receiver security: validate
msg.sender, validateinitiator, never store funds in receiver - Flash loans β flash accounting evolution (Aave/Balancer V2 β Uniswap V4/Balancer V3)
- Governance flash loan attacks and defenses (snapshot voting, timelocks)
- Fee comparison across all providers
- Vulnerable protocol exercise: donation attack + ERC-4626 defense
Internalized patterns: Flash loans eliminate capital as a barrier (design assuming every user has infinite temporary capital). The callback pattern is universal (Aave executeOperation, Balancer receiveFlashLoan, Uniswap uniswapV2Call). Flash accounting is the future (V4/Balancer V3 build around delta tracking and end-of-transaction settlement). Zero-fee flash loans change the economics (lower profitability threshold for attacks). Receiver security is critical (validate msg.sender, validate initiator, never store funds). Collateral swaps and leverage are the primary production use cases (not just arbitrage). The economics are razor-thin (MEV searchers capture 90%+ of arbitrage profit via builder tips).
Complete: You now understand flash loans as both a tool (arbitrage, liquidation, leverage) and a threat model (any attacker has unlimited temporary capital).
πΌ Job Market Context β Module-Level Interview Prep
What DeFi teams expect you to know:
-
βHow should your protocol defend against flash loan attacks?β
- Good answer: Use TWAP oracles instead of spot prices
- Great answer: Flash loans donβt create vulnerabilities β they eliminate capital barriers for exploiting existing ones. The defense framework: (1) never rely on values that can be manipulated within a single tx (spot prices, balanceOf, share ratios), (2) use values established in previous blocks (TWAPs, snapshots), (3) for governance, snapshot voting power at proposal creation block, (4) for vaults, use virtual shares/assets offset to prevent donation-based share inflation. Design assuming every user has infinite temporary capital.
-
βWalk through a flash loan liquidation end to endβ
- Good answer: Borrow the debt asset, repay the position, receive collateral, sell it, repay the loan
- Great answer: Flash borrow USDC from Balancer (0 fee). Call
Pool.liquidationCall(collateral, debt, user, debtToCover, receiveAToken=false)β this repays the userβs debt and sends you the collateral at the liquidation bonus discount. Swap collateral β USDC via Uniswap V3 exact input. Repay Balancer. Profit =collateral Γ price Γ (1 + bonus) - debtRepaid - swapFees. The key insight: you choose Balancer over Aave to save 5 bps, and you setreceiveAToken=falseto get the underlying directly for the swap.
Interview Red Flags:
- π© Thinking flash loans are only useful for arbitrage (most production uses are liquidation and collateral management)
- π© Not knowing that flash accounting (V4/Balancer V3) is replacing dedicated flash loan functions
- π© Building a protocol without considering flash-loan-amplified attack vectors in the threat model
- π© Storing funds in a flash loan receiver contract (griefing vector)
Pro tip: If asked to design a liquidation system in an interview, mention that flash loan compatibility is a feature, not a bug. MakerDAO Liquidation 2.0 was explicitly designed to be flash-loan compatible β Dutch auctions with instant settlement let liquidators use flash loans, which means more competition, better prices, and less bad debt. A protocol thatβs βflash loan resistantβ for liquidations is actually worse off.
β οΈ Common Mistakes
Mistake 1: Not validating msg.sender in the callback
// β WRONG β anyone can call this function directly
function executeOperation(
address asset, uint256 amount, uint256 premium,
address initiator, bytes calldata params
) external returns (bool) {
// attacker calls this directly, initiator = whatever they want
_doSensitiveOperation(params);
return true;
}
// β
CORRECT β validate both msg.sender AND initiator
function executeOperation(
address asset, uint256 amount, uint256 premium,
address initiator, bytes calldata params
) external returns (bool) {
require(msg.sender == address(POOL), "Only Pool");
require(initiator == address(this), "Only self-initiated");
_doSensitiveOperation(params);
return true;
}
Both checks are required: msg.sender confirms the lending pool is calling you (not an arbitrary contract), and initiator confirms your contract requested the flash loan (not someone else using your callback as a target).
Mistake 2: Storing funds in the receiver contract
// β WRONG β contract holds USDC between transactions
contract MyFlashReceiver is IFlashLoanSimpleReceiver {
function deposit(uint256 amount) external {
USDC.transferFrom(msg.sender, address(this), amount);
}
function executeOperation(...) external returns (bool) {
// Uses stored USDC + flash loaned amount for strategy
}
}
// Attacker initiates a flash loan targeting YOUR contract
// β Pool sends tokens to your contract
// β Your callback runs with attacker-controlled params
// β Even if callback fails, attacker can try different params
// β
CORRECT β pull funds in the same tx, never hold between txs
function executeArbitrage(...) external {
USDC.transferFrom(msg.sender, address(this), seedAmount);
POOL.flashLoanSimple(address(this), USDC, amount, params, 0);
USDC.transfer(msg.sender, USDC.balanceOf(address(this)));
// Contract balance returns to 0 after every tx
}
Mistake 3: Forgetting to approve repayment (Aave)
// β WRONG β Aave will revert because it can't pull the repayment
function executeOperation(...) external returns (bool) {
_doStrategy();
return true; // Returns true but Pool's transferFrom fails
}
// β
CORRECT β approve before returning
function executeOperation(
address asset, uint256 amount, uint256 premium, ...
) external returns (bool) {
_doStrategy();
IERC20(asset).approve(address(POOL), amount + premium);
return true;
}
Aave uses transferFrom to pull the repayment after your callback returns. Balancer uses balance checks instead (you transfer inside the callback). Mixing up these patterns is a common source of reverts.
Mistake 4: Using flash loans for operations that donβt need atomicity
Flash loans add complexity (callback architecture, approval management, extra gas). If you already have the capital and donβt need atomicity, a simple multi-step transaction or even multiple transactions may be simpler and cheaper. Flash loans shine when: (1) you donβt have the capital, or (2) you need the entire operation to succeed or fail atomically (e.g., you donβt want to repay debt and then fail on the swap, leaving you exposed).
π Cross-Module Concept Links
β Backward References (Part 1 + Modules 1β4)
| Source | Concept | How It Connects |
|---|---|---|
| Part 1 Module 1 | Custom errors | Flash loan receivers use custom errors for initiator validation, repayment failures |
| Part 1 Module 2 | Transient storage / EIP-1153 | V4 flash accounting uses TSTORE/TLOAD for delta tracking β flash loans become emergent from the accounting model |
| Part 1 Module 3 | Permit / Permit2 | Gasless approvals in flash loan callbacks β approve repayment without separate tx |
| Part 1 Module 5 | Fork testing / vm.mockCall | Essential for testing flash loan strategies against real Aave/Balancer/Uniswap liquidity on mainnet forks |
| Part 1 Module 6 | Proxy patterns | Aave Pool proxy delegates to FlashLoanLogic library; Balancer Vault is a single immutable entry point |
| Module 1 | SafeERC20 / token transfers | Safe token handling in callbacks β approve patterns differ between providers (Aave: approve, Balancer: transfer) |
| Module 2 | AMM swaps / price impact | DEX swaps are the core operation inside most flash loan strategies (arbitrage, liquidation collateral disposal) |
| Module 2 | Flash accounting (V4) | V4 doesnβt have dedicated flash loans β flash borrowing is emergent from the delta tracking system |
| Module 3 | Oracle manipulation threat model | Flash loans make spot price manipulation free β the entire oracle attack surface assumes flash loan access |
| Module 3 | TWAP / Chainlink defense | Time-based oracles resist flash loan manipulation because they span multiple blocks |
| Module 4 | Liquidation mechanics / health factor | Flash loan liquidation: borrow debt asset β liquidate β swap collateral β repay β zero-capital liquidation |
| Module 4 | Collateral swap / leverage | Flash borrow β repay debt β withdraw β swap β redeposit β re-borrow β repay flash β Aaveβs βliquidity switchβ |
β Forward References (Modules 6β9 + Part 3)
| Target | Concept | How Flash Loan Knowledge Applies |
|---|---|---|
| Module 6 (Stablecoins) | DAI flash mint | Unlimited flash minting from CDP-issued stablecoins β infinite liquidity because the protocol controls issuance |
| Module 6 (Stablecoins) | Liquidation 2.0 | MakerDAO Dutch auctions designed for flash loan compatibility β more competition, better prices, less bad debt |
| Module 7 (Yield/Vaults) | ERC-4626 inflation attack | Flash loans amplify donation attacks on vault share prices β virtual shares/assets offset is the defense |
| Module 8 (Security) | Attack simulation | Flash-loan-amplified attack scenarios as primary threat model for invariant testing |
| Module 9 (Stablecoin Capstone) | Flash mint | Capstone stablecoin protocol includes ERC-3156-adapted flash mint β CDP-issued tokens can offer infinite flash liquidity |
| Part 3 Module 5 (MEV) | Searcher strategies | Flash loan arbitrage profits captured by MEV searchers via Flashbots bundles; builder tips consume 90%+ of profit |
| Part 3 Module 8 (Governance) | Governance attacks | Flash loan voting attacks and snapshot-based voting defense; quorum requirements |
| Part 3 Module 9 (Capstone) | Perpetual Exchange | Capstone perp exchange integrates flash loan patterns for liquidation and MEV strategies learned throughout Part 3 |
π Production Study Order
Study these codebases in order β each builds on the previous oneβs patterns:
| # | Repository | Why Study This | Key Files |
|---|---|---|---|
| 1 | Aave V3 FlashLoanLogic | The most widely used flash loan provider β premium calculation, callback verification, modes[] parameter | contracts/protocol/libraries/logic/FlashLoanLogic.sol, contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol |
| 2 | Balancer V2 Vault | Zero-fee flash loans from consolidated vault liquidity β simpler callback, balance-based verification | pkg/vault/contracts/Vault.sol (search flashLoan), pkg/interfaces/contracts/vault/IFlashLoanRecipient.sol |
| 3 | Uniswap V2 Pair | Flash swaps β optimistic transfers with constant product verification; repay in either token | contracts/UniswapV2Pair.sol (search swap, uniswapV2Call) |
| 4 | MakerDAO DssFlash | Flash mint pattern β unlimited DAI minted from thin air, burned at end of tx; zero-fee | src/flash.sol |
| 5 | Uniswap V4 PoolManager | Flash accounting β no dedicated flash loan, borrowing is emergent from delta tracking + transient storage | src/PoolManager.sol (search unlock, settle), src/libraries/TransientStateLibrary.sol |
| 6 | ERC-3156 Reference | The flash loan standard interface β provider-agnostic borrower code | contracts/interfaces/IERC3156FlashLender.sol, contracts/interfaces/IERC3156FlashBorrower.sol |
Reading strategy: Start with Aaveβs FlashLoanLogic β trace executeFlashLoanSimple() to understand the canonical borrow β callback β verify pattern. Then Balancer for the simpler balance-check approach. Uniswap V2 shows flash swaps (repay in a different token). MakerDAOβs DssFlash shows flash minting β a fundamentally different model. V4βs PoolManager shows the future: flash borrowing as emergent behavior from delta accounting.
π Resources
Aave flash loans:
Balancer flash loans:
Uniswap flash swaps/accounting:
Flash loan attacks and security:
- Cyfrin β Flash loan attack patterns
- RareSkills β Flash loan guide
- samczsun β Taking undercollateralized loans for fun and for profit (classic)
Navigation: β Module 4: Lending | Module 6: Stablecoins & CDPs β