Liquidation bot
Liquidation bots monitor Euler accounts, identify unhealthy positions, simulate liquidation candidates, and may submit transactions under operator-defined constraints. Simulation and expected profit do not guarantee successful or profitable execution.
Read Liquidations first if you need the protocol mechanics: health, reverse Dutch discounts, maximum liquidation discount, cool-off time, and bad-debt behavior.
Reference implementation
liquidation-bot-v3 is the reference liquidation bot for Euler V3. It is a Rust binary (built with Cargo) that runs as a long-lived process against a single chain.
On startup it does a one-shot historical sync from the Euler subgraph to discover every active borrower, then keeps account state fresh in three concurrent ways:
- It watches the EVC contract for on-chain events, so any new or changed account is picked up in real time.
- It polls the configured oracles (including Pyth) on a fixed interval. When a price moves, every account that depends on the affected oracle is re-evaluated.
- It runs a full resync and health check across every tracked account on a longer interval as a safety net.
When an account becomes unhealthy, the bot picks the most profitable borrow/collateral pair, gets a swap quote from the Euler swap API for the seized collateral, simulates the liquidation, and, if the result is profitable, submits it through the configured liquidator contract. Profit is routed to the configured profit receiver.
| Resource | Use |
|---|---|
| liquidation-bot-v3 | Reference bot for account monitoring, oracle polling, opportunity detection, simulation, execution, and operations. |
| EVC integration guide | Understand how liquidations are coordinated through EVC-controlled collateral movement. |
| Data API | Query indexed protocol data for vaults, accounts, prices, liquidations, and timelines. |
| Lens contracts | Read on-chain account and vault state for monitoring and validation. |
Configuration
The reference bot merges configuration from three layers (later layers override earlier ones):
- An
RPC_URL_<chain_id>environment variable, which seeds the RPC endpoint for the matching chain. - A
Config.<chain_id>.tomlfile loaded from the working directory. Ready-made files for every supported chain ship in the repository'sconfigs/directory. - Other environment variables, mapped onto config fields by name (for example
EOA_PRIVATE_KEY,SUBGRAPH_URL_PREFIX).
CHAIN_ID selects which config file is loaded and which RPC_URL_<chain_id> value is used. The shipped TOML files contain the chain-specific contract addresses and subgraph paths, but deliberately exclude secrets, RPC endpoints, and the subgraph host. Those are supplied through environment variables.
Required environment variables
| Variable | Purpose |
|---|---|
CHAIN_ID | Selects which Config.<chain_id>.toml is loaded. |
RPC_URL_<chain_id> | RPC endpoint for the chain. The chain id in the name must match CHAIN_ID. |
SUBGRAPH_URL_PREFIX | Subgraph host, joined with subgraph_url_path from the TOML file to form the full endpoint. |
EOA_ADDRESS | Public address of the signing wallet. Validated against EOA_PRIVATE_KEY on startup. |
EOA_PRIVATE_KEY | Private key for the signing wallet. |
Key config fields
The TOML files define everything chain-specific, including the contract addresses the bot depends on:
evc_address,swapper_address,liquidator_address, and theoracle_lens_address,account_lens_address,vault_lens_address, andutils_lens_addresslens contracts.- an optional
[pyth]table withaddressandendpointkeys (the endpoint must end with/; omit the whole table on chains without a Pyth deployment), andwrapped_native_asset_address. swap_urlandpricing_urlfor collateral-to-debt quotes and profitability evaluation.profit_receiverfor liquidation profit.oracle_polling_interval_secondsandfull_resync_and_check_interval_secondsto tune how aggressively the bot tracks price moves and re-checks accounts.simulation_mode(spins up a local Anvil fork and settles every liquidation against the fork instead of the real network — useful for dry-running against live data).enable_observability_apiandvault_filter(None,Whitelist, orBlacklist) to restrict which vaults the bot tracks.
On startup the bot validates the configuration: it confirms the RPC reports the expected chain id, the signing key matches the configured EOA, and every configured contract address has bytecode deployed. If any check fails, the bot exits.
Observability API
When enable_observability_api is enabled, the bot serves a read-only HTTP API on port 3000:
Do not expose this service directly to the public internet. The reference service binds
0.0.0.0:3000, permits broad CORS, and/accountsexposes tracked positions. Bind privately where supported, firewall the port, or place it behind an authenticated reverse proxy. Restrict CORS, monitor access, and treat the service as operationally sensitive even though its methods are read-only.
GET /health— current state (Syncing,Healthy, orError).GET /accounts— tracked accounts with computed health, dependent oracles, and positions.GET /oracles— known oracles with their latest cached value.
Supported chains
The configs/ directory contains chain-specific configuration. Adding a chain requires compatible deployed contracts, valid addresses, RPC and subgraph/data access, oracle support, code-path compatibility, a reviewed Config.<chain_id>.toml, and end-to-end simulation and submission testing. Confirm current support and addresses against the pinned repository and Contract addresses before production use.
Run it
The bot is a Rust binary (Cargo, edition 2024). Build and run from a directory containing the relevant config file:
Load signing keys from a secret manager. Use a least-privilege, minimally funded signer; keep secrets out of shell history, process listings, and logs; and monitor simulation and submission failures. The environment exports below illustrate required names only and are not a recommended production secret-loading method.
cargo build --release
export CHAIN_ID=1
export RPC_URL_1="https://your-mainnet-rpc"
export SUBGRAPH_URL_PREFIX="https://your-subgraph-host/"
export EOA_ADDRESS="0xYourWalletAddress"
export EOA_PRIVATE_KEY="0xYourPrivateKey"
cd configs
../target/release/liquidation-bot-v3A multi-stage Dockerfile is included. It uses Doppler for secret injection by default; the entrypoint is straightforward to adapt if you supply environment variables another way. The image does not include Foundry, so simulation_mode (which spawns a local Anvil fork) requires adding Foundry to the image or running the bot outside Docker.
Operator checklist
Use this non-exhaustive checklist before running a liquidation bot with real funds:
- Target chain, RPC endpoints, oracle polling and resync intervals, and retry behavior.
- Current EVC, lens, oracle, swapper, liquidator, and Pyth contract addresses for the chain.
- Account-health calculation against the controller vault's
accountLiquiditybehavior. - Oracle routes, pull-oracle (Pyth) update requirements, and stale-price handling.
- Profit threshold, gas model, slippage limits, swap routing, and profit receiver.
- Secret-manager integration, least-privilege signer funding, nonce management, transaction replacement, and submission method.
- Observability API, metrics, logs, alerting, and incident response.
- A
simulation_moderehearsal against a fork and small-size runs before production sizing.
Risks
Liquidation automation is competitive and operationally sensitive. A bot can lose money through stale data, reverted transactions, bad quotes, oracle updates, gas spikes, RPC failures, private-key compromise, or unexpected vault configuration. Treat the reference bot and dashboard as starting points, not guarantees.