Reusable local DEX route aggregator for liquidation systems.
This crate owns the DEX routing runtime only:
- Pool index loading.
- AMM instance construction and state synchronization.
- Direct / bridge / multi-hop path discovery.
- Route simulation and split-route optimization.
- Solidity
DexRouter.SwapRoutecompatible output.
It intentionally does not own protocol-specific liquidation logic:
- No Aave or Morpho user state.
- No health-factor computation.
- No executor or transaction broadcasting.
- No database.
- No PoolIndex generation pipeline.
- No direct dependency on application PriceService modules.
Applications provide:
DexAggregatorConfig- chain provider
- optional
DexAggregatorNotifier - request-time pricing context
- protocol-specific liquidation request mapping
The crate provides:
DexAggregatorRouteCalculatorRouteRequestRouteCalculationRequestRouteBatchRequestAggregatedSwapRoutesSwapRoute/SwapStep
The aggregator does not call external price services during route calculation. Applications pass prices at request time:
- Single request:
RoutePricingContext - Batch request: shared
Arc<RoutePricingSnapshot>
This avoids async service calls, lock contention, and repeated price reads inside the hot route calculation path.
The crate exposes a minimal notifier trait:
#[async_trait::async_trait]
pub trait DexAggregatorNotifier: Send + Sync {
async fn notify(&self, title: &str, body: &str);
}If no notifier is provided, NoopDexAggregatorNotifier is used and notifications are ignored.
Ignored tokens are passed through DexAggregatorConfig::ignored_tokens.
The aggregator still returns route errors normally, but suppresses noisy route-failure notifications for ignored pairs.
This crate consumes an existing NDJSON PoolIndex file through DexAggregatorConfig::pool_index_path.
PoolIndex generation is intentionally out of scope for the first extraction phase.
The repository includes the first migrated Ethereum mainnet baseline from the Aave liquidation project:
test-data/pool_index_1.jsontest-data/aave_verification_routes_baseline.json
Useful commands:
just test
ETHEREUM_RPC_URL=... just verify-eth-routes
ETHEREUM_RPC_URL=... just generate-verification-routes
MAINNET_RPC_URL=... just forge-verify-routesverify-eth-routes checks live Rust route selection against real AMM state.
generate-verification-routes writes test-data/verification_routes.json.
forge-verify-routes executes those vectors on a mainnet fork through the
deployed DexRouter.
See docs/route-validation.md for the full validation boundary.
PoolIndex owns an instance-level AddressNormalizer.
There is no process-global address normalization state in runtime path discovery.