A flash swap releases swap output before the pool verifies payment; a flash loan temporarily lends assets under a lender's repayment rules. In Uniswap v2, a flash swap can settle with the withdrawn token or the other token in that pair. Aave V3 flashLoanSimple requires the borrowed asset plus its premium in the same transaction. If settlement fails and the error reaches the transaction's top level, the token operations revert, while executed computation can still cost gas.
The useful comparison is the obligation left after assets arrive: which token must return, how much, to which contract, and by what point in execution? Neither mechanism supplies money that can remain unpaid until a later transaction. Both can also consume a receiver's existing funds to cover costs, so successful repayment alone says little about the operation's economic result.
How flash swaps and flash loans settle
This comparison uses Uniswap v2 and Aave V3's EVM flashLoanSimple path. They illustrate different contracts for temporary liquidity; their details are not universal definitions for every product using the word “flash.” A callback lets the source contract run the receiver's code before finishing its own operation.
Uniswap v2 sends the requested output before checking final token balances. Supplying nonempty callback data makes the pair call uniswapV2Call on the recipient, where additional contract operations can run before payment is checked. Ordinary routed swaps can send payment first even though the pair still delivers output before its final check. The official v2 flash-swap guide describes this ordering.
Aave V3 transfers the requested asset to a receiver, invokes executeOperation, and collects the borrowed amount plus premium afterward. The receiver needs both sufficient tokens and permission for the Pool to collect them. This is the flow documented in Aave's flash-loan guide.
| Settlement question | Uniswap v2 callback swap | Aave V3 flashLoanSimple |
|---|---|---|
| Source of assets | A specific two-token pair | One reserve in a specific lending market |
| Acceptable repayment | Either pair token, or a combination satisfying the invariant | The borrowed asset plus its premium |
| Amount check | Fee-adjusted pair balances | Borrowed amount plus calculated premium |
| Transfer direction | Callback sends tokens to the pair | Pool pulls tokens from the receiver |
| Unpaid balance after success | No unsettled swap obligation | No debt opened by this simple path |
For the v2 column, the v2-core v1.0.1 pair source measures balances after the callback and applies its adjusted-product check. This invariant requires the product of fee-adjusted balances to meet or exceed the opening reserve product. A token allowance granted to the pair does not perform that payment. Conversely, directly sending tokens to an Aave contract is not a substitute for the simple path's required allowance and collection.
The broader Aave flashLoan method has a separate option to open eligible variable debt backed by collateral or credit delegation. That option must be selected and satisfy its rules; it is not an automatic rescue for an unpaid simple loan. Aave's Pool reference distinguishes these paths. Any resulting continuing debt belongs in a separate borrowing ledger, where variable APR and accrual matter.
Keep protocol generations distinct. Uniswap v3 documents a separate flash function and flash callback; v2's repayment formula cannot be carried across by name. Likewise, Uniswap v4 dynamic LP fees concern their own pool rules, rather than establishing a universal flash-loan premium.
Isolate repayment costs with a neutral funding ledger
The following hypothetical comparison uses invented token U, with six decimals. Two separate receiver contracts each begin with 40 U funded before the transaction. Each receives 10,000 U, passes exactly 10,000 U through a constructed local function, and receives exactly 10,000 U back before settlement. The function creates no gain or loss. Assume ordinary token transfers, sufficient available liquidity, and no other token movements. The v2 pair's opening balances match its recorded reserves.
This intentionally uneventful round trip exposes where the fee comes from. The receiver's 40 U pays it. Network costs are excluded from the U ledger and belong to the transaction sender's separate gas record.
Returning U to the Uniswap v2 pair
For a same-token v2 repayment with the other reserve unchanged, 99.7% of the returned amount must cover the withdrawn amount. Thus the minimum return before integer rounding is 10,000 / 0.997, approximately 10,030.090270812 U. The documented same-token formula explains why adding exactly 0.3% of the withdrawn principal is insufficient: the fee applies to the amount coming back in.
With six decimal places, the minimum is 10,030.090271 U. Calculate this in raw units, rounding upward: 10,000,000,000 principal units require 10,030,090,271 returned units. The fee is 30.090271 U, leaving 9.909729 U of the receiver's original buffer.
Returning 10,030 U would fail, despite looking like principal plus a 0.3% fee. Returning 10,030.090270 U would also fail: being short by one raw token unit is still being short. Display rounding cannot relax the contract's inequality.
Returning U through Aave's simple path
For this illustration only, stipulate a premium of 0.05%, or five basis points. This is an assumed parameter, not a live market quote; Aave's V3 documentation makes the premium governance configurable. The premium on 10,000 U is exactly 5 U, and the collection amount is 10,005 U. After the receiver approves that amount and collection succeeds, 35 U remains.
The Aave V3 Origin v3.7.0 reference source calculates the premium, requires a successful callback, then pulls principal plus premium from the receiver into the reserve's aToken address. The pinned source documents one reference release. Verify the deployed implementation and fee for the named market, and use the premium supplied to its callback.
| Receiver state | v2 repayment in U | Illustrative Aave simple loan |
|---|---|---|
| Before transaction | 40 U | 40 U |
| After receiving temporary funds | 10,040 U | 10,040 U |
| After the neutral round trip | 10,040 U | 10,040 U |
| Amount paid or collected | 10,030.090271 U | 10,005 U |
| Ending balance | 9.909729 U | 35 U |
| Reduction in owned funds | 30.090271 U | 5 U |
Both successful transactions reduce owned funds. Treating either ending balance as newly earned money would hide the initial 40 U contribution. These figures compare settlement arithmetic under stated assumptions, not the relative attractiveness of available funding routes.
Paying the other pair token changes the calculation
A v2 flash swap can instead pay for U using the pair's other token, V. That is a swap with a fixed output requirement. It cannot be priced by simply converting principal plus a fee at the opening reserve ratio.
Consider a separate hypothetical v2 pair with 1,000,000 U and 500,000 V, both with six decimals. Request 10,000 U out, return no U, and pay only V. Ignore all other flows and nonstandard transfer behavior.
Removing 10,000 U leaves 990,000 U in the pair. The fee-adjusted V balance must make the product at least as large as its opening value. Applying the inspected v2 invariant gives a V requirement before rounding of approximately 5,065.702156976 V. Rounding upward to V's raw unit produces 5,065.702157 V. One raw unit less fails the same invariant.
The opening ratio would value 10,000 U at 5,000 V. The additional required V reflects the pool curve as well as the input fee. It is not a same-token loan premium, and the numbers cannot be compared with a U-denominated fee without an explicit valuation assumption. The exact-input versus exact-output guide explains which side of this obligation is fixed.
This V payment is an alternative example, not another payment added to the earlier U repayment. Record the actual settlement asset and its raw quantity once.
Follow a failed obligation to its rollback boundary
Return to the same-token example and suppose the v2 receiver sends one raw unit too little. The pair's final invariant check fails. If that error propagates to the transaction's top level, the temporary output, local round trip and repayment transfer all roll back. The receiver retains its pre-existing 40 U; a pair that started with 1,000,000 U and 500,000 V retains those balances. No flash-swap fee transfer persists from that failed transaction.
In the Aave illustration, a receiver with 10,040 U but an allowance of only 10,004.999999 U is equally unable to settle. Having enough funds does not repair an insufficient allowance. The simple path reverts rather than leaving a one-unit debt for later repayment.
Rollback also removes logs from reverted execution. A trace may show attempted transfers that never became lasting token movements. EIP-140 defines the rollback behavior and explains that a normal REVERT preserves remaining gas. Gas already consumed is still an execution cost; an out-of-gas failure can consume the supplied gas while reverting state, as Ethereum's gas documentation explains. The failed-swap cost guide keeps these network costs separate from token settlement.
The boundary matters. If an outer contract catches a failed flash call and continues, that call's changes roll back while unrelated outer operations may persist. Inspect the receipt and call structure before describing the whole transaction as failed. Likewise, an approval completed in an earlier transaction remains a separate state change. “Same block” cannot combine two transactions into one atomic repayment sequence.
Keep a settlement worksheet beside the call trace
Use the following record to review a proposed or completed transaction. A quote alone cannot supply all these fields.
| Record | Evidence to retain |
|---|---|
| Identity | Chain, pair or Pool address, implementation version, token addresses and decimals |
| Observation | Block used for balances, reserves, fee parameters and simulation |
| Temporary funding | Actual asset and raw amount sent to the receiver |
| Obligation | Settlement asset, exact raw amount, fee rule and rounding |
| Payment authority | Transfer destination, or approved spender and available allowance |
| Owned capital | Opening receiver funds and any contribution during the call |
| Outcome | Receipt status, persistent transfers, ending balances and gas charged separately |
In a controlled simulation, reproduce the valid repayment, then reduce the payment or allowance by one raw unit. Also test an unexpected callback caller: v2's guide explicitly validates the pair against its factory, and a receiver should bind callbacks to its intended protocol and operation. An external function name alone establishes no authority.
Close the worksheet with one sentence that can be checked against balances: “This receiver must settle this raw amount of this token through this transfer path before the funding call finishes.” Then reconcile the opening funds and ending funds. For the neutral examples, that reconciliation exposes a cost of 30.090271 U or the stipulated 5 U, even though both repayment checks pass.
