Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

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.

ResourceUse
liquidation-bot-v3Reference bot for account monitoring, oracle polling, opportunity detection, simulation, execution, and operations.
EVC integration guideUnderstand how liquidations are coordinated through EVC-controlled collateral movement.
Data APIQuery indexed protocol data for vaults, accounts, prices, liquidations, and timelines.
Lens contractsRead on-chain account and vault state for monitoring and validation.

Configuration

The reference bot merges configuration from three layers (later layers override earlier ones):

  1. An RPC_URL_<chain_id> environment variable, which seeds the RPC endpoint for the matching chain.
  2. A Config.<chain_id>.toml file loaded from the working directory. Ready-made files for every supported chain ship in the repository's configs/ directory.
  3. 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

VariablePurpose
CHAIN_IDSelects 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_PREFIXSubgraph host, joined with subgraph_url_path from the TOML file to form the full endpoint.
EOA_ADDRESSPublic address of the signing wallet. Validated against EOA_PRIVATE_KEY on startup.
EOA_PRIVATE_KEYPrivate 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 the oracle_lens_address, account_lens_address, vault_lens_address, and utils_lens_address lens contracts.
  • an optional [pyth] table with address and endpoint keys (the endpoint must end with /; omit the whole table on chains without a Pyth deployment), and wrapped_native_asset_address.
  • swap_url and pricing_url for collateral-to-debt quotes and profitability evaluation.
  • profit_receiver for liquidation profit.
  • oracle_polling_interval_seconds and full_resync_and_check_interval_seconds to 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_api and vault_filter (None, Whitelist, or Blacklist) 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 /accounts exposes 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, or Error).
  • 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-v3

A 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 accountLiquidity behavior.
  • 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_mode rehearsal 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.

Read next