{"license":"CC-BY-4.0","licenseUrl":"https://creativecommons.org/licenses/by/4.0/","attribution":"ChainChoice (https://chainchoice.io)","category":"flash_loans","evidenceReadAt":"2026-09-27","generatedAt":"2026-11-12","criteria":[{"id":"borrowable_depth","label":"Single-transaction borrowable depth","weight":30},{"id":"loan_cost_bps","label":"Loan cost in basis points","weight":28},{"id":"integration_surface","label":"Integration surface","weight":22},{"id":"incident_record","label":"Venue incident record","weight":20}],"providers":{"morpho_blue":{"borrowable_depth":{"s":9,"q":"eth_call ERC-20 balanceOf(0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb, the Morpho Blue singleton) at Ethereum block 26070891 (2026-09-27): USDC 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 = 113611415.149013; USDT 0xdAC17F958D2ee523a2206206994597C13D831ec7 = 35946294.472934; WETH…","u":"https://raw.githubusercontent.com/morpho-org/morpho-blue/main/src/interfaces/IMorpho.sol","d":"2026-09-27"},"loan_cost_bps":{"s":10,"q":"Warning: Not ERC-3156 compliant but compatibility is easily reached: | `flashFee` is zero. | `maxFlashLoan` is the token's balance of this contract.","u":"https://raw.githubusercontent.com/morpho-org/morpho-blue/main/src/interfaces/IMorpho.sol","d":"2026-09-27"},"integration_surface":{"s":7,"q":"A user contract calls morpho.flashLoan(token, amount, data) | Morpho calls onMorphoFlashLoan(amount, data) on the caller contract | must approve Morpho to pull back the borrowed amount | If your callback fails to approve the repayment, the entire transaction will revert","u":"https://docs.morpho.org/learn/concepts/flashloans/","d":"2026-09-27"},"incident_record":{"s":8,"q":"\"name\":\"LeadBlock's Morpho Blue Market\",\"classification\":\"Oracle Manipulation\",\"technique\":\"Oracle Misconfiguration\",\"amount\":250000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"sky_dai_flash_mint":{"borrowable_depth":{"s":7,"q":"eth_call DssFlash 0x60744434d6339a6B27d73d9Eda62b6F66a0a04FA at Ethereum block 26070891 (2026-09-27): maxFlashLoan(DAI 0x6B175474E89094C44Da98b954EedeAC495271d0F) = 500000000000000000000000000; max() = 500000000000000000000000000; flashFee(USDS 0xdC035D45d973E3EC169d2276DDab16f1e407384F, 1e24)…","u":"https://developers.skyeco.com/protocol/liquidity/dai-flash-mint/","d":"2026-09-27"},"loan_cost_bps":{"s":9,"q":"require(token == address(dai), \"DssFlash/token-unsupported\"); return 0; | if (what == \"max\") { | else revert(\"DssFlash/file-unrecognized-param\"); | receiver.onFlashLoan(msg.sender, token, amount, 0, data) == CALLBACK_SUCCESS, | dai.transferFrom(address(receiver), address(this), amount);","u":"https://raw.githubusercontent.com/sky-ecosystem/dss-flash/master/src/flash.sol","d":"2026-09-27"},"integration_surface":{"s":10,"q":"Since the Flash module conforms to the ERC3156 spec, you can just use the reference borrower implementation from the spec | function onFlashLoan( address initiator, address token, uint256 amount, uint256 fee, bytes calldata data ) | FlashBorrower: Untrusted lender | FlashBorrower: Untrusted loan…","u":"https://developers.skyeco.com/protocol/liquidity/dai-flash-mint/","d":"2026-09-27"},"incident_record":{"s":8,"q":"\"name\":\"MakerDAO\",\"classification\":\"Oracle Manipulation\",\"technique\":\"Stale Oracle Price\",\"amount\":8320000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"spark_sparklend":{"borrowable_depth":{"s":8,"q":"eth_call SparkLend Pool 0xC13e21B648A5Ee794902342038FF3aDAB66BE987 getReservesList() at Ethereum block 26070891 (2026-09-27) = 20 reserves; underlying balanceOf(spToken) at the same block: USDS 413953049.84318445974856186 (spUSDS 0xc02ab1a5eaa8d1b114ef786d9bde108cd4364359); wstETH…","u":"https://docs.spark.finance/dev/sparklend/features/flash-loans","d":"2026-09-27"},"loan_cost_bps":{"s":8,"q":"The flash-loan fee is split between the LPs of the borrowed reserve and the protocol treasury. Both shares are bps and are governance-set via PoolConfigurator.updateFlashloanPremiumTotal and updateFlashloanPremiumToProtocol. | For flashLoanSimple, the fee is never waived.","u":"https://docs.spark.finance/dev/sparklend/features/flash-loans","d":"2026-09-27"},"integration_surface":{"s":8,"q":"The callback signature is executeOperation(address[] assets, uint256[] amounts, uint256[] premiums, address initiator, bytes params) returns (bool). | must return true; returning false reverts with INVALID_FLASHLOAN_EXECUTOR_RETURN (error code 13).","u":"https://docs.spark.finance/dev/sparklend/features/flash-loans","d":"2026-09-27"},"incident_record":{"s":6,"q":"The governance process centers around updating the Spark Agent artifact in the Sky Atlas, which controls key protocol parameters including budgets, risk settings, asset onboarding | The Spark Spell is executed through the established Sky Spell process | All governance proposals must be submitted as…","u":"https://docs.spark.finance/governance/","d":"2026-09-27"}},"uniswap_v4":{"borrowable_depth":{"s":8,"q":"eth_call balances of the PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90 at Ethereum block 26070891 (2026-09-27): USDC 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 balanceOf = 67029795.109354; USDT 0xdAC17F958D2ee523a2206206994597C13D831ec7 balanceOf = 76863436.410714; WBTC…","u":"https://developers.uniswap.org/llms.mdx/docs/protocols/v4/guides/flash-accounting","d":"2026-09-27"},"loan_cost_bps":{"s":9,"q":"Negative deltas indicate tokens owed to the PoolManager | If any deltas remain unresolved when the PoolManager locks, the entire transaction reverts.","u":"https://developers.uniswap.org/llms.mdx/docs/protocols/v4/guides/flash-accounting","d":"2026-09-27"},"integration_surface":{"s":6,"q":"1. Unlock the PoolManager 2. Execute operations (creating deltas) 3. Resolve all deltas 4. Context returns to the PoolManager which verifies no outstanding deltas | Sync the currency balance with `sync()` | Complete the settlement with `settle()` | For positive deltas, simply use `take` to receive…","u":"https://developers.uniswap.org/llms.mdx/docs/protocols/v4/guides/flash-accounting","d":"2026-09-27"},"incident_record":{"s":8,"q":"\"name\":\"Uniswap V1\",\"classification\":\"Reentrancy\",\"technique\":\"Reentrancy\",\"amount\":220000 | \"name\":\"Uniswap (Phishing Attack)\",\"classification\":\"Social Engineering\",\"technique\":\"Phishing\",\"amount\":8000000 | \"name\":\"BoostHook\",\"classification\":\"Oracle Manipulation\",\"technique\":\"Spot Price…","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"aave_v3":{"borrowable_depth":{"s":10,"q":"eth_call Aave v3 Pool 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2 at Ethereum block 26070891 (2026-09-27): getReservesList() = 67 reserves; aToken from getReserveData, then underlying balanceOf(aToken): aEthUSDT 0x23878914efe38d27c4d67ab83ed1b93a74d4086a holds USDT 191357700.805206; aEthUSDC…","u":"https://aave.com/docs/aave-v3/guides/flash-loans","d":"2026-09-27"},"loan_cost_bps":{"s":5,"q":"The flash loan fee is initialized at deployment to 0.05% and can be updated via Governance Vote. | Fee to LP: FLASHLOAN_PREMIUM_TOTAL - FLASHLOAN_PREMIUM_TO_PROTOCOL | At initialization, FLASHLOAN_PREMIUM_TO_PROTOCOL is set to 0.","u":"https://aave.com/docs/aave-v3/guides/flash-loans","d":"2026-09-27"},"integration_surface":{"s":9,"q":"Allows borrower to access liquidity of multiple reserves in single flashLoan transaction. The borrower also has an option to open variable rate borrow position backed by supplied collateral or credit delegation in this case | Allows borrower to access liquidity of single reserve for the…","u":"https://aave.com/docs/aave-v3/guides/flash-loans","d":"2026-09-27"},"incident_record":{"s":7,"q":"\"name\":\"Aave V3\",\"classification\":\"Oracle Manipulation\",\"technique\":\"Oracle Misconfiguration\",\"amount\":862000 | \"name\":\"Aave\",\"classification\":\"Access Control\",\"technique\":\"Arbitrary External Call\",\"amount\":56000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"uniswap_v3_flash":{"borrowable_depth":{"s":6,"q":"eth_call at Ethereum block 26070891 (2026-09-27), USDC 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 and WETH 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 balanceOf each pool: 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640 (fee() = 500) USDC 75307737.203666, WETH 9018.049155286005879513…","u":"https://raw.githubusercontent.com/Uniswap/v3-core/main/contracts/UniswapV3Pool.sol","d":"2026-09-27"},"loan_cost_bps":{"s":3,"q":"uint256 fee0 = FullMath.mulDivRoundingUp(amount0, fee, 1e6); | uint256 fee1 = FullMath.mulDivRoundingUp(amount1, fee, 1e6);","u":"https://raw.githubusercontent.com/Uniswap/v3-core/main/contracts/UniswapV3Pool.sol","d":"2026-09-27"},"integration_surface":{"s":8,"q":"Uniswap v3 introduces a new function, `flash`, within the Pool contract. | `Flash` withdraws a specified amount of both `token0` and `token1` to the `recipient` address. The withdrawn amount, plus the swap fees, will be due to the pool at the end of the transaction.","u":"https://developers.uniswap.org/llms.mdx/docs/protocols/v3/guides/flash-swaps/getting-started","d":"2026-09-27"},"incident_record":{"s":9,"q":"\"name\":\"Uniswap V1\",\"classification\":\"Reentrancy\",\"technique\":\"Reentrancy\",\"amount\":220000 | \"name\":\"Uniswap (Phishing Attack)\",\"classification\":\"Social Engineering\",\"technique\":\"Phishing\",\"amount\":8000000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"balancer_v3":{"borrowable_depth":{"s":1,"q":"eth_call balances of the Balancer V3 Vault 0xbA1333333333a1BA1108E8412f11850A5C319bA9 at Ethereum block 26070891 (2026-09-27): USDC 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 = 110878.94338; WETH 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 = 164.201028386351384373; USDT…","u":"https://docs.balancer.fi/concepts/vault/flash-loans.html","d":"2026-09-27"},"loan_cost_bps":{"s":9,"q":"IERC20(loanToken).transfer(address(balancerVault), amount); | balancerVault.settle(IERC20(loanToken), amount);","u":"https://docs.balancer.fi/concepts/vault/flash-loans.html","d":"2026-09-27"},"integration_surface":{"s":6,"q":"balancerVault.unlock(abi.encodeWithSelector(this.receiveFlashLoan.selector, userData)); | balancerVault.sendTo(IERC20(loanToken), address(this), amount); | The settle() function is required to inform the Vault that the borrowed funds have been repaid and to settle the balances.","u":"https://docs.balancer.fi/concepts/vault/flash-loans.html","d":"2026-09-27"},"incident_record":{"s":6,"q":"\"name\":\"Balancer V1\",\"classification\":\"Token & Share Accounting\",\"technique\":\"Rounding Error\",\"amount\":234000 | \"name\":\"Balancer V2\",\"classification\":\"Token & Share Accounting\",\"technique\":\"Rounding Error\",\"amount\":128000000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}},"balancer_v2":{"borrowable_depth":{"s":2,"q":"eth_call balances of the Balancer V2 Vault 0xBA12222222228d8Ba445958a75a0704d566BF2C8 at Ethereum block 26070891 (2026-09-27): USDC 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 = 291240.496139; WETH 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 = 1153.327439083724377866; DAI…","u":"https://docs-v2.balancer.fi/reference/contracts/flash-loans.html","d":"2026-09-27"},"loan_cost_bps":{"s":8,"q":"Currently there are 0 fees for flash loans.","u":"https://docs-v2.balancer.fi/reference/contracts/flash-loans.html","d":"2026-09-27"},"integration_surface":{"s":9,"q":"function receiveFlashLoan( IERC20[] memory tokens, uint256[] memory amounts, uint256[] memory feeAmounts, bytes memory userData ) external override | vault.flashLoan(this, tokens, amounts, userData); | require(msg.sender == address(vault)); | this contract owes the flashloaned amounts + feeAmounts.","u":"https://raw.githubusercontent.com/balancer/docs/main/docs/guides/arbitrageurs/flash-loans.md","d":"2026-09-27"},"incident_record":{"s":2,"q":"\"name\":\"Balancer V2\",\"classification\":\"Token & Share Accounting\",\"technique\":\"Rounding Error\",\"amount\":128000000","u":"https://api.llama.fi/hacks","d":"2026-09-27"}}}}