From 2c4534759dce6fd1b87c95c885d0fe53e301f0b8 Mon Sep 17 00:00:00 2001 From: hweawer Date: Thu, 11 Jun 2026 08:59:06 +0200 Subject: [PATCH 1/4] feat: Bots docs --- docs/guides/late-prover-bot.md | 78 +++++++++++++++++++++++++++++++ docs/guides/validator-exit-bot.md | 76 ++++++++++++++++++++++++++++++ sidebars.js | 2 + 3 files changed, 156 insertions(+) create mode 100644 docs/guides/late-prover-bot.md create mode 100644 docs/guides/validator-exit-bot.md diff --git a/docs/guides/late-prover-bot.md b/docs/guides/late-prover-bot.md new file mode 100644 index 000000000..5643e0d38 --- /dev/null +++ b/docs/guides/late-prover-bot.md @@ -0,0 +1,78 @@ +# Late Prover Bot + +## Introduction + +Late Prover Bot monitors the beacon chain for validator exit requests that have passed their required deadline. When a validator fails to exit on time, the bot generates a cryptographic Merkle proof of the delay and submits it to the `ValidatorExitDelayVerifier` smart contract, enabling penalty enforcement on the responsible node operator. + +## Requirements + +### Hardware + +- 1-core CPU +- 8GB RAM + +### Nodes + +- Ethereum EL RPC service +- Ethereum CL API service (Beacon Node) + +## How to use + +The bot runs as a daemon, continuously processing finalized beacon chain roots. For each root, it discovers `ValidatorsExitBusOracle` events in the corresponding EL block range, groups validators by their exit deadline slot, and generates proofs for any that have exceeded their deadline. Proofs are submitted in batches via `verifyValidatorExitDelay()` (or `verifyHistoricalValidatorExitDelay()` for older roots). + +### Envs + +Required variables are (mainnet): + +| Variable | Default | Description | +|---|---|---| +| `CHAIN_ID` | - | Ethereum chain ID. `1` for mainnet, `17000` for Holesky | +| `EL_RPC_URLS` | - | Comma-separated list of EL RPC endpoints | +| `CL_API_URLS` | - | Comma-separated list of CL Beacon API endpoints | +| `LIDO_LOCATOR_ADDRESS` | - | Lido Locator contract address. Addresses for each network can be found [here](/deployed-contracts/) | +| `TX_SIGNER_PRIVATE_KEY` | - | Private key used to sign and submit transactions. Not required when `DRY_RUN=true` | +| --- | --- | --- | +| `DRY_RUN` | `false` | If `true`, proofs are generated but transactions are not sent | +| `DAEMON_SLEEP_INTERVAL_MS` | `300000` | Sleep interval between daemon cycles (ms) | +| `TX_GAS_LIMIT` | `2000000` | Hard gas limit for transactions. Increase if processing large batches | +| `VALIDATOR_BATCH_SIZE` | `50` | Maximum number of validators per transaction | +| `TX_MIN_GAS_PRIORITY_FEE` | `50000000` | Minimum priority fee (wei) | +| `TX_MAX_GAS_PRIORITY_FEE` | `10000000000` | Maximum priority fee (wei) | +| `TX_GAS_PRIORITY_FEE_PERCENTILE` | `25` | Priority fee percentile from the last block's fee history | +| `TX_GAS_FEE_HISTORY_DAYS` | `1` | Days of gas fee history used for base fee estimation | +| `TX_GAS_FEE_HISTORY_PERCENTILE` | `50` | Percentile for base fee estimation | +| `HTTP_PORT` | `8080` | Port for health check and Prometheus metrics endpoints | +| `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` | +| `LOG_FORMAT` | `simple` | Log format: `simple` or `json` | + +Optional variables can be found [here](https://github.com/lidofinance/late-prover-bot#readme). + +## Running + +### Source Code + +1. Clone repository and install requirements: + ```bash + git clone git@github.com:lidofinance/late-prover-bot.git + cd late-prover-bot + ``` +2. Install dependencies: + ```bash + yarn install + yarn run typechain + yarn build + ``` +3. Run the bot: + ```bash + yarn run start:prod + ``` + +### Docker + +Docker image can be found [here](/guides/tooling/#late-prover-bot). + +## Monitoring + +Prometheus metrics and health check are available on the same port: +- `http://localhost:${HTTP_PORT}/metrics` +- `http://localhost:${HTTP_PORT}/health` diff --git a/docs/guides/validator-exit-bot.md b/docs/guides/validator-exit-bot.md new file mode 100644 index 000000000..cd46e9dc1 --- /dev/null +++ b/docs/guides/validator-exit-bot.md @@ -0,0 +1,76 @@ +# Validator Exit Bot + +## Introduction + +Validator Exit Bot automates triggering exits for Lido validators that have missed their exit deadline. The bot monitors the [ValidatorExitBusOracle](/guides/oracle-spec/validator-exit-bus) for exit requests, checks the current status of each validator on the beacon chain, and uses [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) triggerable exits to force the exit of any validator that has not exited on time. Exit trigger fees are paid from the bot's account and refunded by the withdrawal vault. + +## Requirements + +### Hardware + +- 1-core CPU +- 1GB RAM + +### Nodes + +- Ethereum EL RPC service +- Ethereum CL API service (Beacon Node) + +## How to use + +On startup the bot fetches historical `ExitDataProcessing` events from the `ValidatorExitBusOracle` for the configured lookback period. It then runs in a continuous loop: for each validator in its state, the bot checks whether the validator has already exited on the CL, and if not, whether it has missed its exit deadline. Validators past their deadline are included in a batched `trigger_exits` transaction. The bot's address is set as the refund recipient to recover the per-validator withdrawal request fee. + +### Envs + +Required variables are (mainnet): + +| Variable | Default | Description | +|---|---|---| +| `WEB3_RPC_ENDPOINTS` | - | Comma-separated list of EL RPC endpoints | +| `CONSENSUS_CLIENT_URL` | - | CL Beacon API endpoint | +| `WALLET_PRIVATE_KEY` | - | Private key used to send transactions. Omit to run in dry mode (no transactions sent) | +| --- | --- | --- | +| `LIDO_LOCATOR` | `0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb` | Lido Locator address. Other networks can be found [here](/deployed-contracts/) | +| `MODULES_WHITELIST` | *(all)* | Comma-separated staking module IDs to process (e.g. `1` for Curated, `2` for Simple DVT) | +| `LOOKBACK_DAYS` | `7` | Days of historical events to process on first startup | +| `BLOCKS_BETWEEN_EXECUTION` | `25` | Minimum blocks to wait between bot cycles | +| `SLEEP_INTERVAL_SECONDS` | `60` | Sleep time between cycles (seconds) | +| `DRY_RUN` | `false` | If `true`, transactions are built but not submitted | +| `MIN_PRIORITY_FEE` | `50 mwei` | Minimum priority fee for transactions | +| `MAX_PRIORITY_FEE` | `1 gwei` | Maximum priority fee for transactions | +| `MAX_GAS_FEE` | `10 gwei` | Bot will wait for a lower gas price if the current fee exceeds this threshold | +| `CONTRACT_GAS_LIMIT` | `15000000` | Gas limit for contract calls | +| `GAS_PRIORITY_FEE_PERCENTILE` | `15` | Priority fee percentile from recent blocks | +| `PROMETHEUS_PORT` | `9000` | Port for Prometheus metrics | +| `SERVER_PORT` | `9010` | Port for health check server | +| `LOG_LEVEL` | `INFO` | Log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` | + +Optional variables can be found [here](https://github.com/lidofinance/validator-exit-bot#readme). + +## Running + +### Source Code + +1. Clone repository and install requirements: + ```bash + git clone git@github.com:lidofinance/validator-exit-bot.git + cd validator-exit-bot + ``` +2. Install requirements: + ```bash + poetry install + ``` +3. Run validator exit bot: + ```bash + poetry run python -m src.main + ``` + +### Docker + +Docker image can be found [here](/guides/tooling/#validator-exit-bot). + +## Monitoring + +Prometheus metrics will be available on endpoint `http://localhost:${PROMETHEUS_PORT}/metrics`. + +Health check endpoint: `http://localhost:${SERVER_PORT}/health`. diff --git a/sidebars.js b/sidebars.js index c9da09861..f145dd2b4 100644 --- a/sidebars.js +++ b/sidebars.js @@ -73,6 +73,8 @@ module.exports = { 'guides/kapi-guide', 'guides/reward-distributor-bot', 'guides/depositor-bot', + 'guides/late-prover-bot', + 'guides/validator-exit-bot', ], }, 'guides/protocol-levers', From 233cf3721ed2d78eb86803e7cbf36a5fa5ddb8b8 Mon Sep 17 00:00:00 2001 From: hweawer Date: Tue, 23 Jun 2026 13:34:11 +0200 Subject: [PATCH 2/4] fix: docs details --- docs/guides/late-prover-bot.md | 12 ------------ docs/guides/tooling.md | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/guides/late-prover-bot.md b/docs/guides/late-prover-bot.md index 5643e0d38..a1ecc7e8a 100644 --- a/docs/guides/late-prover-bot.md +++ b/docs/guides/late-prover-bot.md @@ -31,19 +31,7 @@ Required variables are (mainnet): | `CL_API_URLS` | - | Comma-separated list of CL Beacon API endpoints | | `LIDO_LOCATOR_ADDRESS` | - | Lido Locator contract address. Addresses for each network can be found [here](/deployed-contracts/) | | `TX_SIGNER_PRIVATE_KEY` | - | Private key used to sign and submit transactions. Not required when `DRY_RUN=true` | -| --- | --- | --- | | `DRY_RUN` | `false` | If `true`, proofs are generated but transactions are not sent | -| `DAEMON_SLEEP_INTERVAL_MS` | `300000` | Sleep interval between daemon cycles (ms) | -| `TX_GAS_LIMIT` | `2000000` | Hard gas limit for transactions. Increase if processing large batches | -| `VALIDATOR_BATCH_SIZE` | `50` | Maximum number of validators per transaction | -| `TX_MIN_GAS_PRIORITY_FEE` | `50000000` | Minimum priority fee (wei) | -| `TX_MAX_GAS_PRIORITY_FEE` | `10000000000` | Maximum priority fee (wei) | -| `TX_GAS_PRIORITY_FEE_PERCENTILE` | `25` | Priority fee percentile from the last block's fee history | -| `TX_GAS_FEE_HISTORY_DAYS` | `1` | Days of gas fee history used for base fee estimation | -| `TX_GAS_FEE_HISTORY_PERCENTILE` | `50` | Percentile for base fee estimation | -| `HTTP_PORT` | `8080` | Port for health check and Prometheus metrics endpoints | -| `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` | -| `LOG_FORMAT` | `simple` | Log format: `simple` or `json` | Optional variables can be found [here](https://github.com/lidofinance/late-prover-bot#readme). diff --git a/docs/guides/tooling.md b/docs/guides/tooling.md index 6d2cdc8e6..63a954ce7 100644 --- a/docs/guides/tooling.md +++ b/docs/guides/tooling.md @@ -70,3 +70,25 @@ Lido keys HTTP API. - **Last update date**: 1 April, 2025 - [**Repository**](https://github.com/lidofinance/lido-keys-api/tree/2.2.1) - [**Documentation**](/guides/kapi-guide/) + +## Validator Exit Bot + +Bot that automates triggering exits for Lido validators that have missed their exit deadline using [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) triggerable exits. + +- **Version**: 1.0.1 +- **Docker image**: sha256:0a649a5eff41a9c05ee82bc974ba4b40943ea2225c37568d52a9f3416f75f31c, [lidofinance/validator-exit-bot@sha256-0a649a5eff41a9c05ee82bc974ba4b40943ea2225c37568d52a9f3416f75f31c](https://hub.docker.com/layers/lidofinance/validator-exit-bot/1.0.1/images/sha256-0a649a5eff41a9c05ee82bc974ba4b40943ea2225c37568d52a9f3416f75f31c) +- **Commit hash**: [lidofinance/validator-exit-bot@edf5daf](https://github.com/lidofinance/validator-exit-bot/commit/edf5daf684f48f8a2b989e49dde0f2afc72565f8) +- **Last update date**: 9 February 2026 +- [**Repository**](https://github.com/lidofinance/validator-exit-bot/tree/1.0.1) +- [**Documentation**](/guides/validator-exit-bot) + +## Late Prover Bot + +Bot that monitors the beacon chain for validators that missed their exit deadline and submits Merkle proofs of the delay to the `ValidatorExitDelayVerifier` contract. + +- **Version**: 1.0.5 +- **Docker image**: sha256:eb23b4fb757dcdc9d2c418941a2a29ce3513a3800d20e3fa162a594519b7f52c, [lidofinance/late-prover-bot@sha256-eb23b4fb757dcdc9d2c418941a2a29ce3513a3800d20e3fa162a594519b7f52c](https://hub.docker.com/layers/lidofinance/late-prover-bot/1.0.5/images/sha256-eb23b4fb757dcdc9d2c418941a2a29ce3513a3800d20e3fa162a594519b7f52c) +- **Commit hash**: [lidofinance/late-prover-bot@59d102a](https://github.com/lidofinance/late-prover-bot/commit/59d102a25c096e21c76798d0bdae7cae0ba65f56) +- **Last update date**: 28 April 2026 +- [**Repository**](https://github.com/lidofinance/late-prover-bot/tree/1.0.5) +- [**Documentation**](/guides/late-prover-bot) From 0b3c76bf8e6d3fec02c7e0762bc622091d659370 Mon Sep 17 00:00:00 2001 From: hweawer Date: Fri, 26 Jun 2026 13:57:10 +0200 Subject: [PATCH 3/4] remove redundant variables --- docs/guides/validator-exit-bot.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/docs/guides/validator-exit-bot.md b/docs/guides/validator-exit-bot.md index cd46e9dc1..d91a7e4b7 100644 --- a/docs/guides/validator-exit-bot.md +++ b/docs/guides/validator-exit-bot.md @@ -29,21 +29,8 @@ Required variables are (mainnet): | `WEB3_RPC_ENDPOINTS` | - | Comma-separated list of EL RPC endpoints | | `CONSENSUS_CLIENT_URL` | - | CL Beacon API endpoint | | `WALLET_PRIVATE_KEY` | - | Private key used to send transactions. Omit to run in dry mode (no transactions sent) | -| --- | --- | --- | | `LIDO_LOCATOR` | `0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb` | Lido Locator address. Other networks can be found [here](/deployed-contracts/) | -| `MODULES_WHITELIST` | *(all)* | Comma-separated staking module IDs to process (e.g. `1` for Curated, `2` for Simple DVT) | -| `LOOKBACK_DAYS` | `7` | Days of historical events to process on first startup | -| `BLOCKS_BETWEEN_EXECUTION` | `25` | Minimum blocks to wait between bot cycles | -| `SLEEP_INTERVAL_SECONDS` | `60` | Sleep time between cycles (seconds) | | `DRY_RUN` | `false` | If `true`, transactions are built but not submitted | -| `MIN_PRIORITY_FEE` | `50 mwei` | Minimum priority fee for transactions | -| `MAX_PRIORITY_FEE` | `1 gwei` | Maximum priority fee for transactions | -| `MAX_GAS_FEE` | `10 gwei` | Bot will wait for a lower gas price if the current fee exceeds this threshold | -| `CONTRACT_GAS_LIMIT` | `15000000` | Gas limit for contract calls | -| `GAS_PRIORITY_FEE_PERCENTILE` | `15` | Priority fee percentile from recent blocks | -| `PROMETHEUS_PORT` | `9000` | Port for Prometheus metrics | -| `SERVER_PORT` | `9010` | Port for health check server | -| `LOG_LEVEL` | `INFO` | Log level: `DEBUG`, `INFO`, `WARNING`, `ERROR` | Optional variables can be found [here](https://github.com/lidofinance/validator-exit-bot#readme). From 2285783509d763ad4805491e8ee14646094b7626 Mon Sep 17 00:00:00 2001 From: hweawer Date: Mon, 29 Jun 2026 14:00:27 +0200 Subject: [PATCH 4/4] fix: comments --- docs/guides/late-prover-bot.md | 2 +- docs/guides/validator-exit-bot.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/late-prover-bot.md b/docs/guides/late-prover-bot.md index a1ecc7e8a..cfd6a8ebe 100644 --- a/docs/guides/late-prover-bot.md +++ b/docs/guides/late-prover-bot.md @@ -26,7 +26,7 @@ Required variables are (mainnet): | Variable | Default | Description | |---|---|---| -| `CHAIN_ID` | - | Ethereum chain ID. `1` for mainnet, `17000` for Holesky | +| `CHAIN_ID` | - | Ethereum chain ID. `1` for mainnet, `560048` for Hoodi | | `EL_RPC_URLS` | - | Comma-separated list of EL RPC endpoints | | `CL_API_URLS` | - | Comma-separated list of CL Beacon API endpoints | | `LIDO_LOCATOR_ADDRESS` | - | Lido Locator contract address. Addresses for each network can be found [here](/deployed-contracts/) | diff --git a/docs/guides/validator-exit-bot.md b/docs/guides/validator-exit-bot.md index d91a7e4b7..fba49b990 100644 --- a/docs/guides/validator-exit-bot.md +++ b/docs/guides/validator-exit-bot.md @@ -29,7 +29,7 @@ Required variables are (mainnet): | `WEB3_RPC_ENDPOINTS` | - | Comma-separated list of EL RPC endpoints | | `CONSENSUS_CLIENT_URL` | - | CL Beacon API endpoint | | `WALLET_PRIVATE_KEY` | - | Private key used to send transactions. Omit to run in dry mode (no transactions sent) | -| `LIDO_LOCATOR` | `0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb` | Lido Locator address. Other networks can be found [here](/deployed-contracts/) | +| `LIDO_LOCATOR` | `0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb` | Lido Locator address for Ethereum mainnet. Addresses for other supported networks can be found [here](/deployed-contracts/) | | `DRY_RUN` | `false` | If `true`, transactions are built but not submitted | Optional variables can be found [here](https://github.com/lidofinance/validator-exit-bot#readme).