Development of a Flash Loan Liquidation Bot
In August 2023, there was approximately $4 million available to liquidate within one hour on Aave v3 in Polygon following a sharp market movement. Bots that responded first earned liquidator fees — averaging 5–8% of liquidated collateral. Bots that responded 2–3 seconds late either lost to competitors or received reverts because the position was already liquidated. A liquidation bot is a task of speed, calculation precision, and MEV strategy, not just a call to liquidationCall.
Flash loans allow participation in liquidations without capital: borrow an asset, liquidate the position, receive collateral, swap to the asset, return the debt + fee. The entire operation is a single atomic transaction.
How Liquidation Works on Aave v3
A position becomes liquidatable when health factor < 1.0. Health factor = (collateral_value * liquidation_threshold) / debt_value. The liquidation threshold for ETH on Aave v3 is 82.5%, for WBTC — 75%.
A liquidator calls liquidationCall(collateralAsset, debtAsset, user, debtToCover, receiveAToken). You can cover up to 50% of the debt per transaction (close factor). In exchange, you receive collateral with a bonus — liquidation bonus; for ETH this is 5%.
Profitability calculation before sending the transaction:
profit = collateral_received * collateral_price
- debt_covered * debt_price
- flash_loan_fee (0.09% on Aave v3)
- swap_slippage
- gas_cost
If profit ≤ 0 — we don't send the transaction. This sounds obvious, but without precise off-chain calculation with current oracle prices and slippage, the bot loses money on every unprofitable liquidation, only paying gas.
Bot Architecture
Smart Contract Executor
A single contract that accepts liquidation parameters and executes an atomic sequence:
-
flashLoan()from Aave PoolAddressesProvider — borrowdebtAsset - In the
executeOperation()callback, callliquidationCall - Receive
collateralAsset(or aToken) - Swap
collateralAsset→debtAssetvia Uniswap v3 or 1inch - Return
debtAsset + feeto Aave - Remaining balance — profit, goes to the wallet
The contract should be non-upgradeable with onlyOwner on the execution function. No need for upgradeability — we need simplicity and minimal attack surface.
Off-chain Monitoring
Position Data Source. Three options:
-
getUserAccountData()via Multicall for a list of known borrowers — slow for large numbers of addresses - The Graph Aave subgraphs — index all positions, update per block
- Direct event tracking:
Borrow,Deposit,Repayevents → local state machine for positions
Optimal scheme: The Graph for initial state load + WebSocket events for real-time updates. The list of positions with health_factor < 1.05 is checked on each new block.
Price Calculation. You cannot rely only on Chainlink oracle — Aave uses it for health factor calculation, but the actual swap price may differ. You need both: Chainlink for liquidation profit calculation, Uniswap v3 TWAP for collateral swap slippage calculation.
MEV and Competition
A liquidation bot operates in the MEV world. If you send a transaction to the public mempool with standard gasPrice, a searcher can front-run it: copy the calldata, send with higher gas, liquidate the position first.
Solutions:
Flashbots / MEV Blocker. Send bundles directly to Flashbots relay on Ethereum mainnet. The transaction does not enter the public mempool, invisible to searchers. On Polygon — Bor private transactions via QuickNode or Alchemy private pool.
Bundle Simulation. Before sending, simulate the bundle through eth_callBundle — verify that by the time of block inclusion, the position is not yet liquidated and profit is positive.
Priority Fee Dynamics. On L2 (Arbitrum, Optimism, Base), MEV competition is lower due to the sequencer. Liquidations on Arbitrum are often profitable even without Flashbots.
Typical Implementation Issues
Slippage on Large Collateral Swaps. If the position is large — swapping 1000 ETH to USDC through a single Uniswap v3 pool will create significant price impact. Solution: split routing through 1inch API or custom multi-hop implementation through multiple pools. Optimal route calculation should be part of off-chain profitability check.
Reorg on L2. Arbitrum and Optimism have finality lag. A transaction is confirmed on L2, but then the rollup reorgs — rarely, but it happens. For a liquidation bot this is not critical (either the position is liquidated or not), but confirmations must be handled correctly.
Gas Estimation. eth_estimateGas for a flash loan transaction can be off by 10–20% — external contracts behave differently. Add a 20% buffer to the estimate and verify that after the buffer the transaction is still profitable.
Stale Health Factor. Between health factor calculation and transaction sending, 1–2 blocks may pass. If the price rises during this time — the position is no longer liquidatable, liquidationCall reverts. Add try/catch at the off-chain logic level and pay only gas for failed transactions.
Development Process
Smart Contract Development (3–4 days). Solidity + Foundry. Fork tests on Ethereum/Arbitrum mainnet: simulate specific liquidatable positions from historical data, verify calculation correctness and profit.
Off-chain Monitoring (4–6 days). Node.js/TypeScript, viem for on-chain interactions, The Graph SDK, WebSocket block subscriptions, Redis for position state storage.
MEV Integration (2–3 days). Flashbots SDK, bundle building, pre-send simulation.
Testnet Testing + Mainnet Soft Launch (3–5 days). Start on Sepolia fork, then mainnet with minimal capital — several actual liquidations to calibrate profitability parameters.
Timeline Guidance
A basic bot for one protocol (Aave v3) on one chain — 1–2 weeks. Multi-protocol (Aave + Compound + Morpho) with multi-chain support — 3–4 weeks. Timelines depend on MEV protection requirements and the number of target protocols.
Cost is calculated after discussing target protocols and chains.







