evm-dex-pool
Reusable Rust library for EVM DEX pool state management — fetch pools from chain, keep them in sync with events, and estimate swap outputs.
Installation
[]
= { = "../evm-dex-pool", = ["rpc", "registry", "collector"] }
| Feature | What it enables |
|---|---|
rpc |
Fetch pool state from RPC (fetch_v2_pool, fetch_v3_pool) |
registry |
PoolRegistry — thread-safe concurrent pool storage |
collector |
Event collection system — keeps pools in sync with chain via RPC polling or WebSocket |
Usage
1. Create a Registry and Add Pools
use ;
use Arc;
let registry = new;
// Register event topics so the collector knows what to listen for
registry.add_topics;
registry.add_topics;
registry.add_profitable_topics;
registry.add_profitable_topics;
// Add pools (see "Fetching Pools from RPC" below)
registry.add_pool;
registry.add_pool;
2. Start the Collector (Bootstrap)
The collector keeps pool state in sync with the chain. Use start_collector for the simplest setup:
use ;
use mpsc;
// Optional: channel to receive swap events for downstream processing
let = ;
let config = CollectorConfig ;
start_collector.await?;
// Consume swap events (optional)
spawn;
Collector modes:
| Config | Mode | Behavior |
|---|---|---|
use_websocket: true |
WebSocket | Bootstraps via RPC, then streams live events. Fastest. |
use_pending_blocks: true |
PendingBlock | Polls confirmed blocks + pending block for speculative state. |
| Both false | LatestBlock | Polls RPC every wait_time ms. Simplest. |
3. Estimate Swap Outputs
Read a pool from the registry and calculate swap amounts:
if let Some = registry.get_pool
4. Batch Fetch Pools into Registry
Use fetch_pools_into_registry to auto-detect pool types, fetch state from chain, and add them to the registry in parallel with retry:
use ;
let config = PoolFetchConfig ;
let pool_addresses: = vec!;
// Returns addresses of newly fetched pools (skips pools already in registry)
let fetched = fetch_pools_into_registry.await?;
// Do app-specific work with newly fetched pools
for addr in fetched
Pool type detection is automatic — it calls liquidity() (V3-specific) to distinguish V2 from V3. You can also call the lower-level functions directly:
use ;
let pool_type = identify_pool_type.await?;
let pool = fetch_pool.await?;
registry.add_pool;
5. Fetching Individual Pools from RPC
use fetch_v2_pool;
use ;
// Fetch a V2 pool
let v2_pool = fetch_v2_pool.await?;
// Fetch a V3 pool + tick data
let mut v3_pool = fetch_v3_pool.await?;
fetch_v3_ticks.await?;
Optional: Custom Metrics
Implement CollectorMetrics to plug in your own metrics system:
use CollectorMetrics;
// Pass to start_collector
start_collector.await?;
Pass None to disable metrics.
Pool Types Supported
- UniswapV2Pool — constant product (
x * y = k) and stable swap curves - UniswapV3Pool — concentrated liquidity with tick-based pricing (supports UniswapV3, PancakeV3, AlgebraV3, RamsesV2 variants)
- ERC4626 — vault-based pools (deposit/withdraw pricing)
All pool types implement PoolInterface which provides calculate_output, calculate_input, apply_swap, apply_log, tokens, fee, address, etc.