System Components
Keep-rs keeper bots are built on a modular architecture designed for high-performance, real-time order matching and liquidation on the Drift Protocol. The main components include:DriftClient
TheDriftClient is the core interface to the Drift Protocol. It provides:
- Access to on-chain program data (markets, users, oracles)
- Transaction building and submission capabilities
- Account state management
- Blockhash subscription for transaction validity
The DriftClient is “leaked” as a static reference in both filler and liquidator bots to enable efficient shared access across async tasks without ownership constraints.
DLOB (Decentralized Limit Order Book)
The DLOB maintains an in-memory representation of all resting limit orders across markets. Key features:- Real-time orderbook state updated via gRPC subscriptions
- Cross detection for auction orders, swift orders, and limit orders
- Top maker queries for matching against liquidations
- Efficient data structure for fast order matching
DLOBNotifier
TheDLOBNotifier processes incoming events and updates the DLOB state:
- Slot updates trigger price recalculations
- Account updates modify user orders in the orderbook
- Batches events for efficient processing
- Emits
DLOBEventnotifications (slot/price updates, order changes)
TxWorker
A dedicated background thread that handles transaction lifecycle:- Signing and Sending: Receives transaction requests via channel, signs with wallet, sends to RPC
- Confirmation Tracking: Monitors gRPC transaction updates for confirmations
- Pending Transaction Management: Maintains a circular buffer of pending transactions
- Metrics Collection: Records success/failure rates, latency, and fill rates
The TxWorker uses a separate thread to avoid blocking the main event loop during transaction operations.
gRPC Subscriptions
Real-time data feeds from Drift’s gRPC service provide: Slot Updates- New slot notifications every ~400ms
- Triggers DLOB updates and cross detection cycles
- Used for auction price calculations
- User account changes (orders, positions, balances)
- Market account changes (AMM state, liquidity)
- Oracle price updates
- Updates DLOB state and triggers margin checks (liquidator)
- Confirmation status of submitted transactions
- Routed to TxWorker for confirmation handling
- Enables transaction result parsing and metrics
Priority Fee Subscriber
ThePriorityFeeSubscriber dynamically adjusts transaction priority fees:
- Monitors recent transactions for relevant markets
- Calculates percentile-based fees (50th, 60th, etc.)
- Ensures competitive transaction inclusion without overpaying
Swift Order Stream
For the Filler bot, a WebSocket connection receives off-chain Swift orders:- Real-time order notifications from Drift’s Swift order system
- Orders are matched against resting liquidity in the DLOB
- Provides low-latency order matching opportunities
MarketState (Liquidator)
The liquidator usesMarketState for margin calculations:
- Caches market metadata and oracle prices
- Provides margin requirement calculations
- Identifies liquidatable, high-risk, and safe accounts
Component Interaction
The components work together in a continuous event-driven loop:- Event Sources (gRPC, Swift) push updates to the system
- DLOBNotifier processes events and updates the DLOB
- Bot Logic (Filler/Liquidator) detects opportunities using DLOB state
- TxWorker executes transactions and tracks confirmations
- Blockchain confirms transactions, triggering metrics updates
Bot Lifecycle
Initialization
- Load configuration from environment variables
- Connect to Solana RPC and Drift gRPC endpoints
- Initialize DriftClient with bot’s wallet
- Create DLOB and DLOBNotifier
- Spawn TxWorker thread
- Subscribe to gRPC events (accounts, slots, transactions)
- Subscribe to additional feeds (Swift orders, Pyth prices)
- Start metrics HTTP server
Main Loop
The bot enters a continuoustokio::select! loop that processes:
Filler Bot:
- New slots → Check for auction and limit order crosses
- Swift orders → Match against resting liquidity
- Pyth price updates → Update oracle prices for better execution
- gRPC events (up to 32 per batch) → Update user accounts and oracles
- Margin checks → Identify liquidatable and high-risk users
- Liquidation worker → Process liquidatable users with rate limiting
- Periodic full sweeps → Recheck all users every 64 cycles
Transaction Execution
When an opportunity is detected:- Build Transaction: Create Drift instruction with necessary accounts
- Add Compute Budget: Set priority fee and CU limit
- Submit to TxWorker: Send via channel to worker thread
- Worker Signs & Sends: Sign with wallet and submit to RPC
- Track Pending: Add to pending transaction buffer
- Await Confirmation: Worker receives gRPC transaction update
- Parse Result: Extract logs, compare to intent, update metrics
Performance Considerations
Async Architecture
- Main loop uses
tokio::select!with biased selection for priority handling - Swift orders processed first to capture time-sensitive opportunities
- Slot updates processed with lower priority
Memory Management
- Static references (
&'static) avoid clone overhead for shared data - Circular buffers (PendingTxs) prevent unbounded memory growth
- Slot limiters track recent order attempts to avoid spam
Rate Limiting
- Order slot limiter prevents repeated attempts on same order
- Liquidation rate limiting (5 slots minimum between attempts)
- Priority fee calculation uses percentiles to balance cost and speed
The architecture is optimized for sub-slot latency, aiming to detect and execute opportunities within the ~400ms Solana slot time.
Configuration
Bots are configured via environment variables:--mainnet/--devnet: Network selection--filler/--liquidator: Bot type--dry: Simulation mode (no actual transactions)--markets: Specific markets to operate on