Skip to content

tfrmma/rfq-solver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

RFQ Solver — Intent-Based Market Maker

Rust solver for UniswapX Dutch auction intents. The solver internalises retail flow by pricing against it off-chain and hedging residual inventory on Binance/OKX.

Architecture

┌──────────────────────────────────────────────────────────────────────┐
│                         rfq-solver                                    │
│                                                                        │
│  ┌─────────────────────────────────────────────────────────────────┐  │
│  │                    Auction Loop (200ms)                          │  │
│  │  poll UniswapX → parse intent → quote → fill on-chain → hedge   │  │
│  └──────┬──────────────────────────────────┬────────────────────────┘  │
│         │                                   │                           │
│  ┌──────▼──────────┐            ┌──────────▼──────────────────────┐   │
│  │  Pricing Engine │            │        Hedge Engine              │   │
│  │                 │            │                                  │   │
│  │  mid_price      │            │  Binance REST  ←→  OKX REST     │   │
│  │  + fee_model    │            │  Market order (immediate delta   │   │
│  │  + slippage_est │            │  neutral hedge after each fill)  │   │
│  │  + inv_skew     │            └──────────────────────────────────┘   │
│  └──────┬──────────┘                                                   │
│         │                                                               │
│  ┌──────▼──────────────────────────────┐                              │
│  │        CEX Feed Manager              │                              │
│  │  Binance WS ──►  BookCache           │                              │
│  │  OKX WS     ──►  (DashMap, lockfree) │                              │
│  └──────────────────────────────────────┘                              │
└──────────────────────────────────────────────────────────────────────┘

Pricing Model

execution_price = mid ± (fee_component + slippage_component + inventory_skew)
Component Formula
Fee (protocol_fee + cex_taker_fee + gas + margin) / qty
Slippage Book-walk simulation on top-of-book; square-root for large sizes
Inventory Skew γ × (net_pos / max_pos) × mid × qty

Where γ (gamma) is the inventory risk-aversion parameter (default 0.5%).

Dutch Decay

UniswapX orders linearly decay their output:

output(t) = start_amount − (start_amount − end_amount) × (t − t₀) / (T − t₀)

The solver must fill at or above end_amount (floor). The edge is:

edge = execution_price − hedge_cost_per_unit

Trades are only executed when edge_bps ≥ min_edge_bps (default: 1 bps).

Workspace Structure

rfq-solver/
├── crates/
│   ├── pricing/       Core pricing: quote engine, fees, slippage, inventory
│   ├── cex-client/    Binance + OKX WebSocket feeds + REST hedging clients
│   ├── chain-client/  UniswapX order book, intent parsing, reactor settlement
│   ├── hedger/        Hedge engine, position tracker, P&L accounting
│   └── solver/        Main binary: auction loop, config, Prometheus metrics
├── config/
│   └── .env.example   Environment variable template
└── README.md

Setup

Prerequisites

  • Rust 1.78+ (rustup update stable)
  • Funded Ethereum wallet (solver address)
  • Binance and/or OKX API keys with trading permissions
  • Ethereum RPC endpoint (Infura, Alchemy, or public LlamaRPC)

Run

cp config/.env.example .env
# fill in .env with your credentials

cargo build --release
RUST_LOG=info ./target/release/rfq-solver

Monitoring

Prometheus metrics are exposed on http://localhost:9090/metrics.

Key metrics to alert on:

Metric Alert Condition
rfq_hedge_failures_total Any increment → CRITICAL
rfq_pnl_usd Falling below threshold
rfq_inventory_utilisation > 80% → WARNING

Production Hardening Checklist

  • Wire hmac + sha2 crates for real HMAC-SHA256 (replace stub in rest.rs)
  • Wire Alloy provider in ReactorClient::fill_intent (replace stub)
  • Wire Alloy provider in EthRpcClient::gas_snapshot for live gas
  • Add ERC20.approve(reactor, MAX_UINT) setup script for output tokens
  • Implement emergency hedge / circuit breaker on hedge failure
  • Add max slippage check before on-chain settlement
  • Persist fills to PostgreSQL for audit trail
  • Add Grafana dashboard for monitoring P&L and inventory
  • Implement MEV protection (Flashbots / MEV Blocker RPC)
  • Add multi-asset support beyond ETH pairs

Key Design Decisions

Why immediate full hedge? Simpler P&L accounting and eliminates directional risk during the latency window. The 12-second Ethereum block time is the main exposure window.

Why DashMap for book cache? Lock-free reads on the hot path (quote generation). The book is updated at ~50-100 msg/sec; a Mutex<HashMap> would create contention.

Why Decimal (not f64) for prices? Floating-point rounding errors compound in financial arithmetic. rust_decimal is 128-bit fixed-point and exact for the precision needed.

Why market orders for hedging? Speed over price. For retail-sized flow (< 10 ETH), market impact on Binance is minimal (~1-2 bps) and the priority is delta neutrality within milliseconds.

About

RFQ Solver & Intent-Based Market Maker written in Rust. Designed to internalize non-toxic retail flow from networks like UniswapX, 1inch Fusion, and CowSwap. Features an ultra-low latency pricing and routing engine that models immediate CEX hedging, inventory risk skewing, and execution costs via real-time WebSockets and RPCs.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors