13 December 2025 · 5 min read

The flash loan is free until it reverts

Aave's premium is the smallest cost a flash-loan arbitrageur pays. The real cost is gas burned on attempts that revert, and that cost depends on how the transaction was sent.

The number everyone quotes about flash loans is 0.05%. That is the premium Aave charges on the amount borrowed, and it is the one line on the invoice that is easy to read. When I built the execution engine for Shayanomaly, which borrows from Aave V3 and settles a cross-venue trade in one atomic transaction, the premium turned out to be the least interesting cost in the system. The cost that decides whether a strategy lives is the gas spent on attempts that fail, and that cost is not a property of the strategy. It is a property of how the transaction reaches the chain.

Where the premium sits

Aave's flash loan documentation describes the mechanism: the pool transfers the requested amount to your contract, calls your contract's executeOperation, and expects the amount plus the premium to be repaid before the call returns. If it is not, the entire transaction reverts and the pool never lent anything. The premium is initialised at 0.05% and can be changed by governance; the current value is read from FLASHLOAN_PREMIUM_TOTAL on the Pool contract, and at initialisation none of it goes to the protocol treasury, so it is paid to the liquidity providers whose capital you used for one block.

Borrow a million dollars of a stablecoin and the premium is five hundred dollars. That sounds like a lot until you notice that you only pay it on success, and that the capital it buys you for one block would cost far more to hold in a wallet for a year. A reverted flash loan pays no premium, because the loan was undone. So the premium is a tax on wins, and a tax on wins never kills a strategy. It just shrinks the wins.

One atomic flash-loan arbitrage, and where it can revert Three lanes: your contract, the Aave pool, and two exchanges. The pool lends, calls executeOperation, your contract swaps on exchange A then exchange B, then repays the amount plus premium. A marked point after the second swap shows where a profitability check reverts the whole transaction. Your contract Aave V3 pool Exchanges A and B flashLoan(amount) transfer, then executeOperation() swap on A, swap on B tokens back require(profit > 0) or revert everything repay amount + 0.05%
Illustrative: the call shape described in the Aave V3 flash loan guide, not a trace of any live transaction.

The cost that is not on the invoice

Now look at the attempts that lose. Cross-venue arbitrage is a race: the spread you saw is visible to everyone with the same feeds, and by the time your transaction executes, someone else's may have taken it. Your contract swaps, checks the result, finds no profit, and reverts. The loan is undone, the swaps are undone, the premium is never paid. Nothing happened on chain, except that you paid for the computation.

That is the whole problem. On Ethereum a reverted transaction still pays gas for every operation it executed up to the revert, because the network did the work of finding out that it should fail. A flash loan plus two swaps plus the checks is a heavy transaction; call it 500,000 gas as a round figure. At a gas price of 20 gwei that is 0.01 ETH per failed attempt, at 5 gwei it is 0.0025 ETH, and at 80 gwei it is 0.04 ETH. Those are exact multiplications, not estimates, and they are paid on every loss.

Put the two costs side by side. The premium is paid on wins and scales with the loan. Revert gas is paid on losses and scales with how often you are wrong and how expensive the block is. A strategy that wins one attempt in ten pays nine reverts for each premium, and at ordinary gas prices the nine reverts cost more than the premium long before the loan is large.

The revert budget

The number I keep in front of me is what I call the revert budget: the expected profit from one successful fill divided by the gas cost of one failed attempt at the current gas price. It is the number of losses a strategy can afford per win. A budget of 8 means the strategy survives a 12% hit rate; a budget below 1 means that even winning every second attempt loses money.

Revert budget against gas price for one strategy Five columns showing how many failed attempts a strategy can afford per win, assuming 0.02 ETH expected profit per win and 500,000 gas per attempt: 8 at 5 gwei, 4 at 10 gwei, 2 at 20 gwei, 1 at 40 gwei and 0.5 at 80 gwei. Failed attempts a strategy can afford per win 0.02 ETH expected profit per win, 500,000 gas per attempt 8 5 gwei 4 10 gwei 2 20 gwei 1 40 gwei 0.5 80 gwei below 1, every public attempt is a losing bet
Illustrative: computed as profit per win divided by gas per attempt times gas price; the inputs are stated assumptions, not measured results.

The budget moves with the gas market, which means a strategy that is fine at 3 in the morning is dead at 3 in the afternoon, with no change to the code. Most of the arbitrage bots that quietly bleed do so because they run one number, the gross spread threshold, and never recompute the budget from the live gas price.

The submission path is the strategy

Here is the part that turns a cost problem into a design decision. The gas-on-revert rule is a rule of the public mempool. A bundle sent through Flashbots follows a different rule. Their documentation states it plainly: a bundle containing a transaction that reverts is not included in the block at all, unless you listed that transaction in revertingTxHashes, and a bundle that is not included costs nothing. The builder simulated it, saw the revert, and dropped it. You paid for nothing because nothing happened.

That changes the revert budget from a number to a choice. Through the public mempool, every loss costs full gas and the budget is finite. Through a bundle, a loss costs only the opportunity, and the budget is effectively unlimited; what you pay instead is a tip that only lands on the wins, plus a different kind of exposure that I will come back to.

Where a strategy survives, by submission path and revert rate A two by two grid. Horizontal axis: revert rate, low on the left and high on the right. Vertical axis: submission path, public mempool at the bottom and bundle at the top. Bottom left survives if the budget is above one. Bottom right loses money. Top left and top right survive, paying only on wins. Survives reverts are free, tip paid on wins Survives the only home for a low hit rate Survives if budget above 1 recompute it every block Loses money nine reverts per premium Revert rate: low to high Submission path: public mempool to bundle
Illustrative: a placement of the four cases, with the dot on the cell a cross-venue arbitrage strategy usually occupies.

This is why, in Shayanomaly, the flash loan and the bundle were one decision rather than two features. A cross-venue arbitrage strategy lives in the top-right cell: it is wrong often, because the spreads it chases are short-lived, and it can only afford to be wrong often if being wrong is free. Atomic execution through Aave makes the loss safe. Bundle submission makes the loss cheap. Without the second, the first only guarantees that you lose gas instead of capital.

What the contract should do about it

Two consequences fall out for the code. First, if any path goes through the public mempool, revert early and cheap: quote both venues and check the expected profit before calling flashLoan, so the common failure costs a few thousand gas instead of half a million. Second, if every path goes through bundles, the early check still belongs there, but for a different reason: builders simulate bundles, and a strategy that submits hopeless bundles is spending the builder's patience rather than gas.

A third consequence is about the number itself. Read the premium from the pool at runtime, not from a constant in your code, because governance can change it and a contract that hard-codes 0.05% will repay too little on the day it changes and revert on every attempt, which on the public mempool means paying for every one of those failures. The same goes for the gas estimate in the revert budget: it should come from a simulation of the actual call against current state, the way you would run eth_call before sending, rather than from the figure you measured the week you deployed. Both numbers drift, and the budget is only as honest as its inputs.

And the exposure I promised to return to. A bundle removes one adversary, anyone reading the public mempool, and replaces it with a smaller set you now trust to simulate honestly and not to front-run what they saw. Flashbots' own EIP-1559 notes spell out how the tip and the base fee interact for bundles, and the trust question deserves its own post. For this one, the rule is simpler. Compute the revert budget from live gas before every attempt. If it is below 1, the public mempool is not a submission path; it is a slow way to donate ETH to validators.

Flash LoansAaveMEV
All writing

Written by Mohd Shayan

Get new posts by email

Occasional essays on engineering, AI, and building for the people technology leaves behind.

One email per new post. Unsubscribe any time.

Subscribe with RSS