LI.FI Swap Route Atomicity

A LI.FI swap route cannot commit its final receiver transfer if a modeled route gate fails, a modeled swap step fails, or output is below the user's minimum amount.

LI.FI routes users across same-chain swaps and cross-chain intents. This case targets the original GenericSwapFacet.swapTokensGeneric path and its shared SwapperV2 swap loop. The guarantee is about source-chain commit behavior for the provided _swapData, not about third-party DEX pricing or bridge completion.

Why It Matters

A route executor touches user funds, approvals, external DEX calls, leftover refunds, and the final receiver transfer in one transaction. The dangerous failure mode is partial success: a route looks complete to the user even though a modeled step or public-route guard failed.

The value at risk is the asset being routed through LI.FI's source-chain swap path. If the public final transfer could commit after a failed step, users and integrators could observe a completed route even though the route did not execute as supplied.

The proof checks the all-or-nothing control-flow layer. A failed receiver check, reentrancy guard, required deposit, allow-list check, approval, low-level call, leftover refund, minimum-output check, or final transfer prevents a committed final receiver transfer in the model.

How This Was Modeled and Proven

The model follows the public wrapper gates and helper ordering in the Solidity source. swapTokensGeneric includes the receiver, non-reentrant, and refund-excess-native gates around the helper call. It calls _depositAndSwap, then transfers the final receiving asset to the receiver. The shared executor deposits required assets, runs _executeSwaps, performs leftover refunds, checks minimum output, and returns the output amount.

Each SwapData item is represented by a decoded SwapStep. Route gates that live outside one step are represented by RouteGuards. The source-shaped model is in Contract.lean, the readable specs are in Specs.lean, and the no-sorry reference proofs are in Proofs.lean.

Scope

Covered: the original GenericSwapFacet.swapTokensGeneric source-chain path, the common no-reserve SwapperV2._depositAndSwap overload, required-deposit success, calldata selector shape, allow-list checks, ERC20 approval gates, target-contract and non-zero-amount checks, low-level call failure propagation, leftover refund success, minimum-output failure, final receiver transfer success, and excess-native refund success.

Out of scope: GenericSwapFacetV3, periphery Executor loops, the native-reserve overload, exact token balances, event fields, exact refund amounts, and whether a third-party DEX call with success == true performed the intended economic swap beyond LI.FI's minimum-output gate.

Proof artifacts
  • Contract.lean contains the route model, step executor, route guards, and committed-route summary.
  • Specs.lean defines the six task-level properties over failed steps, route-gate failures, committed step counts, and minimum output.
  • Proofs.lean proves the reference theorems with no case-specific axioms and no sorry placeholders.
  • The case directory contains the compile target and generated task skeletons.
  • Benchmark pull request records the exact reviewable branch and CI status.
FunctionTheoremStatus
_executeSwapsfailed_step_revertsProven
swapTokensGenericno_final_transfer_on_failed_stepProven
swapTokensGenericfinal_transfer_implies_all_steps_succeededProven
_depositAndSwapcommitted_route_executes_every_stepProven
_depositAndSwapmin_output_required_for_commitProven
swapTokensGenericroute_gate_failure_prevents_commitProven
Verify it yourself
git clone https://github.com/lfglabs-dev/ethereum-verification-benchmark
cd ethereum-verification-benchmark
git checkout cc6f9f4a52fb9578071522c3d83658e87c18d2cc
lake build Benchmark.Cases.LiFi.SwapAtomicity.Compile

If the build succeeds, Lean has checked the LI.FI swap atomicity reference proofs for the modeled source-chain route.

Assumptions

These assumptions name the proof boundary. They are scope limits, not hidden Lean axioms.

  • decoded SwapDataEach route step is already decoded into booleans

    Benchmark/Cases/LiFi/SwapAtomicity/Contract.lean

    The model abstracts calldata bytes, token addresses, native versus ERC20 status, and allow-list lookups into explicit fields on SwapStep. Short calldata is represented by calldataWellFormed = false.

  • external-call flagsToken, refund, transfer, and DEX calls are success inputs

    Benchmark/Cases/LiFi/SwapAtomicity/Contract.lean

    The proof verifies LI.FI's response to success or failure flags. It does not prove third-party DEX semantics, token contract internals, or price quality beyond the modeled minimum output gate.

  • EVM rollbackOption.none means no committed route result

    Benchmark/Cases/LiFi/SwapAtomicity/Specs.lean

    Reverting routes produce no RouteCommit and no committed final receiver transfer. Rollback of earlier external effects is the standard EVM transaction semantics assumption, not a separate theorem about every third-party contract.

  • scoped entrypointOriginal GenericSwapFacet and common SwapperV2 path

    cases/lifi/swap_atomicity/case.yaml

    The case excludes GenericSwapFacetV3, periphery Executor swap loops, the native-reserve overload, exact event fields, and exact leftover refund amounts.

Learn More