archived · not maintained

flash-loan-liquidator

Liquidation bot for Aave V3 on Arbitrum, Base, and Mantle. Flash loans for zero-capital execution. Two execution paths: Chainlink SVR sealed-bid auctions and direct transactions racing on price feed updates.

Solidity 0.8.20 Foundry TypeScript ethers v6 archived 2026-03

Repo

contracts/          Solidity (Foundry)
  src/              FlashLoanLiquidator, F1SVRSolver, F1SVRSolverBase
  test/             Unit + E2E fork tests
  script/           Deployment scripts

bots/
  arbitrum/         Arbitrum bot (Aave V3 + SVR)
  base/             Base bot
  mantle/           Mantle Aave V3 bot

dashboard/          Single-file HTML telemetry UI
docs/               This page

Execution paths

SVR path (sealed-bid auctions)

Listens to Chainlink's Smart Value Recapture gateway. Receives auction broadcasts for every liquidatable position, estimates profit, submits a bid. Winner is chosen by bid amount. Requires a bond posted to Atlas and a solver contract implementing atlasSolverCall.

Direct path (oracle race)

Subscribes to Chainlink AnswerUpdated events. Pre-builds signed transactions for expected liquidation prices. On a matching event, broadcasts the cached TX over IPC to a colocated Arbitrum Nitro node.

Local Nitro node

The bot runs colocated with an Arbitrum Nitro full node. The node is the foundation for every latency number in this page:

Without a local node, detection still works, but execution latency adds ~15ms per TX and Chainlink WS subscriptions share provider quotas.

Detection pipeline

Three oracle sources feed a single in-memory price store. Each update triggers Health Factor recalc for every position exposed to the asset, in pure BigInt arithmetic, no RPC calls.

SourceTransportLatency vs chainConfidenceAction
Coinbase / Kraken WebSocketExternal WS~100ms ahead0.5Speculative fire
Arbitrum sequencer feedExternal WS~250ms ahead0.95Speculative fire
Chainlink AnswerUpdatedLocal node WSon-chain1.0Confirmed fire

Detection sequence

01 · ~0ms
PriceStore.update
Atomic write of new price, source, timestamp.
02 · ~1ms
PositionStore.getByAsset
Returns positions exposed to the updated feed.
03 · ~10ms
HFRecalculator.batch
BigInt HF calc per position, applying e-mode LT/LB where matched.
04 · gate
Confidence gate
<0.95 → speculative fire. 1.0 → detect HF<1 transitions → execute.

Execution sequence (~33ms after warmup)

eth_call simulation~15msflash loan sim via local node IPC
gas calc~1msfeeData cached 2s
nonce~0mswarmed at startup, in-memory increment
sign + broadcast~17mseth_sendRawTransaction via IPC

Contract flow

executeLiquidation(user, debtAsset, collateralAsset, amount, swapData)
  └─ Aave.flashLoanSimple(debtAsset, amount)
     └─ executeOperation callback:
        1. Aave.liquidationCall(collateral, debt, user, amount, false)
        2. swap: approvedRouter.call(swapData) | UniV3.exactInputSingle()
        3. verify: debtBalance >= amountOwed
        4. approve(Pool, amountOwed)
        5. transfer(OWNER, profit)

Coverage

Build

Contracts

cd contracts
forge install foundry-rs/forge-std
forge install FastLane-Labs/atlas
forge build
forge test                                           # unit
forge test --match-contract F1SVRSolver_E2E_Test -v  # fork E2E (~9 min)

Bot (Arbitrum example)

cd bots/arbitrum
npm install
cp .env.example .env   # fill PRIVATE_KEY, ARBITRUM_RPC_URL, contract addresses
npm run build
node dist/index.js     # DRY_RUN=true by default

Safety notes

License

MIT. See LICENSE.