Development of Liquidation Bot for Lending Protocols
When a position enters liquidation on Aave V3, the health factor drops below 1.0. At that moment, anyone can call liquidationCall() and receive liquidation bonus—5% to 15% of collateral depending on asset. On major protocols, a single transaction liquidator can earn tens of thousands of dollars. Hundreds of bots compete for the right to be first, with co-located servers and optimized gas.
The difference between slow and fast bots is not algorithm but infrastructure and implementation details.
Where Liquidation Bots Compete
Position Detection: Polling vs Event Subscription
Naive approach: every N seconds, query position lists via getUserAccountData. With thousands of active positions, this fails: too many RPC requests, too high latency.
Right approach: combination of two channels:
Event subscription via WebSocket. Listen to Borrow, Deposit, Repay events. Update local state of specific users. No need to re-query everything—only changed positions.
Price feed subscription. Listen to Chainlink AnswerUpdated events for all protocol assets. When asset price changes, recalculate health factor for positions using this asset as collateral or debt. Oracle updates usually trigger liquidations, not user actions.
Two channels give an up-to-date liquidation candidate list with 1-2 second delay after on-chain state change.
Flash Loan for Capital-Free Liquidation
Classic liquidation requires holding reserves of each debt token. With dozens of assets—expensive and inefficient. Standard solution: flash loan from Aave or Balancer, call liquidationCall(), swap received collateral for source token via Uniswap V3 or Curve, repay flash loan. All in one transaction.
Critical: profitable path. After flash loan fee (0.09% in Aave V3) and swap slippage/fee, liquidation must stay profitable. Pre-simulate the full transaction via eth_call before sending—otherwise reverting gas is also a loss.
MEV and Private Mempool
Public mempool means death for liquidation bots. Profitable transactions get sandwich-attacked or MEV-frontrun instantly. Solution: Flashbots Bundles (Ethereum) or private RPC endpoints (Alchemy Private, BloxRoute). Transaction goes directly to validator, bypassing public mempool.
On L2 (Arbitrum, Optimism, Base) it's different: sequencer is centralized, MEV less aggressive, but latency to sequencer node matters just as much.
Bot Architecture
| Component | Implementation | Role |
|---|---|---|
| State manager | In-memory + Redis | User positions, health factors |
| Event listener | ethers.js WebSocket | Position and price updates |
| Profitability calculator | On-chain simulation | eth_call before sending |
| Executor | Flashbots / private RPC | Sending without front-run |
| Flash loan handler | Solidity contract | Atomic liquidation |
Liquidation contract deploys separately. The bot calls its execute() function, passing: borrower address, debt token, collateral token, amount. Contract executes flash loan → liquidation → swap → repayment. Profit stays on contract; bot withdraws periodically.
Multi-Protocol Support
Aave V3, Compound V3 (Comet), Venus on BSC, Radiant—each has its own liquidationCall interface and health factor logic. Use adapter pattern: common ILiquidator interface with implementations per protocol. Adding new protocol = write new adapter without changing core logic.
Testing and Deployment
Fork-tests on mainnet—mandatory. Foundry vm.createFork + vm.warp let you reproduce historical liquidations: take a block where a position was liquidated, run the bot—it should detect and execute it. Best way to verify health factor calculation correctness.
Load test: 10,000 positions in state manager, simulate updating all Chainlink feeds—bot must process queue in <500ms.
Deployment: server in same region as Alchemy/Infura nodes (usually us-east-1). PM2 or systemd for uptime. Monitoring via Grafana: latency from event to transaction, profit per liquidation, failed attempts.
Timeline Estimates
Basic bot for one protocol (Aave) on one chain: 1-1.5 weeks. Multi-protocol with flash loan executor and Flashbots integration: 2-3 weeks. Multi-chain support with unified state manager: add 1 week per chain.







