Overview
The Filler Bot is a keeper bot that matches orders against resting liquidity on the Drift protocol. It performs three main functions:- Swift Order Matching: Matches swift orders (fast, off-chain signed orders) against resting limit orders in the orderbook
- Auction Order Filling: Fills on-chain auction orders by finding the best available liquidity
- Limit Order Uncrossing: Identifies and executes crossed limit orders where bid prices exceed ask prices
How It Works
Event Flow
The Filler Bot operates through several concurrent event streams:- gRPC Slot Updates: Triggers periodic orderbook scanning for crosses
- gRPC Account Updates: Updates the DLOB with new/modified orders
- Swift Order Stream: Receives new swift orders via websocket
- Pyth Price Feeds: Provides real-time oracle price updates
- Appropriate compute unit limits
- Dynamic priority fees (based on current network conditions)
- Fill instructions with optimal maker-taker matching
Transaction Lifecycle
- Detection: Cross or fillable order identified
- Building: Transaction constructed with fill instructions
- Sending: Signed transaction sent to Solana network
- Confirmation: Transaction status monitored via gRPC updates
- Metrics: Performance tracked (fills, revenue, competition)
Running the Filler Bot
Basic Usage
Fill Specific Markets
Configuration
CLI Flags
Enable the filler bot mode. This is the default mode when no other bot flag is specified.
Fill orders for all available markets. When enabled, this overrides the
--market-ids flag and the bot will monitor all perpetual markets (excluding bet markets and uninitialized markets).Comma-separated list of perpetual market indices to fill orders for. Can also be set via the
MARKET_IDS environment variable.Example: --market-ids "0,1,2,3,4" to fill SOL, BTC, ETH, APT, and ARB markets.Compute unit limit for swift order fill transactions. Swift fills typically require more compute units due to signature verification and off-chain order validation.
Compute unit limit for regular auction and limit order fill transactions. Standard fills generally require fewer compute units than swift fills.
Base priority fee in microlamports per compute unit. The actual priority fee may be dynamically adjusted based on network congestion and recent transaction data.
Connect to Solana mainnet-beta. When set to false, connects to devnet. Can also be set via the
MAINNET environment variable.Enable dry-run mode. Transactions are simulated but not actually sent to the network. Useful for testing configuration and strategy without risking funds. Can also be set via the
DRY_RUN environment variable.Sub-account ID to use for the bot’s Drift account. Allows running multiple bots with different sub-accounts from the same wallet.
Environment Variables
Required
Base58-encoded private key for the bot’s Solana wallet. This wallet should have sufficient SOL for transaction fees and USDC for settling trades.
Solana RPC endpoint URL. Use a high-performance RPC provider for best results.Example:
https://api.mainnet-beta.solana.comDrift gRPC endpoint for real-time account and slot updates.Example:
https://api.rpcpool.comAuthentication token for the gRPC endpoint.
Pyth Lazer access token for real-time price feeds. The bot uses Pyth for accurate oracle price data.
Optional
Port for the Prometheus metrics HTTP server. Metrics include fill counts, revenue, transaction success rates, and more.
Default market IDs to fill. Can be overridden by the
--market-ids CLI flag.Monitoring
The Filler Bot exposes several HTTP endpoints for monitoring:http://localhost:9898/metrics- Prometheus metricshttp://localhost:9898/health- Health check endpointhttp://localhost:9898/dashboard- Human-readable dashboard
Key Metrics
- Fills: Total number of successful fills
- Revenue: Profit from maker rebates and taker fees
- Transaction Success Rate: Percentage of sent transactions that confirmed successfully
- Competition: Orders that were filled by others before us
- Order DNE: “Order Does Not Exist” errors (order was cancelled or already filled)
Performance Tuning
Common Issues
Order Does Not Exist Errors
This is normal and indicates healthy competition. It means another keeper filled the order before your transaction landed. Monitor theorder_dne_count metric to understand competition levels.
Transaction Timeouts
If transactions frequently timeout:- Verify your RPC endpoint is reliable and low-latency
- Increase priority fees
- Check network congestion on Solana
No Fills
If the bot is running but not executing fills:- Verify the markets you’re monitoring have active orderbook activity
- Check that oracle prices are updating (look for gRPC slot updates in logs)
- Ensure your wallet has sufficient USDC balance for settling trades
- Verify gRPC and Pyth subscriptions are connected (check logs for “subscribed” messages)
Source Code Reference
The Filler Bot implementation can be found insrc/filler.rs. Key components:
- FillerBot struct (
src/filler.rs:47): Main bot structure - FillerBot::new (
src/filler.rs:62): Initialization and subscription setup - FillerBot::run (
src/filler.rs:144): Main event loop - Config struct (
src/main.rs:27): CLI configuration options