Quote Pipeline & Auction#
The RFQ auction engine is the core of TetraFi's execution layer. It broadcasts trade requests to qualified solvers, collects competing quotes, and selects the winner using UCCP pricing.
RFQ Flow#
RFQ Auction Flow
RFQ Sequence
End-to-End Execution Walkthrough
RFQ and Streaming Price Flow
Shows the RFQ request, solver fan-out, ranked quote response, and the streaming price ladder mode used before a firm RFQ result.
const rfq = await tetrafi.rfq.create({ pair: "USDC/USDT", side: "buy", amount: "1000000.00", corridor: "ethereum-optimism", maxSlippage: 0.001,});console.log(`RFQ: {rfq.id}, status: {rfq.status}`);Quote Preferences#
Four modes via quotePreference parameter:
- Default Ranked ascending by
eta- fastest fill wins - Taker pays small premium for speed
- Use: urgent treasury ops, rebalancing
Swap Types#
Every RFQ is either Exact Input ("I have X, how much Y?") or Exact Output ("I need Y, how much X does it cost?"). The swap type is carried on the MandateOutput context byte and resolved by the OutputSettler at fill time.
See Settlement Flows → Order Types for the full context-byte reference, including Limit, Dutch Auction, and Exclusive variants.
Selection Strategies#
Solver selection is configured per-request via solverOptions. Three strategies control which solvers receive the RFQ:
| Strategy | Mechanism | When Used |
|---|---|---|
| All | Query every viable solver, sorted by compatibility score | Low solver count - maximum competition |
| Sampled | Weighted random selection with exponential decay by rank | High solver count - reduces fan-out |
| Priority | Only solvers above a configurable compatibility threshold | Quality filtering, SLA enforcement |
Solver Reputation#
Solver reliability is tracked on a 24-hour rolling window. Fill rate = successful_fills / (successful_fills + repudiations).
| Fill Rate | Status | Effect |
|---|---|---|
| ≥ 90% | Active | Full RFQ participation |
| 80–89% | Warning | Logged to evidence ledger, no ranking penalty |
| 50–79% | Probation | Ranking weight reduced 50% |
| under 50% | Disabled | Excluded from RFQ, admin reset required |
Batch Auction & Intent Netting#
When multiple RFQs arrive for the same corridor within a batch window, the engine can net them - offsetting flows cancel out, reducing solver capital and gas costs. Four matching modes (Simple, Batching, Intermediate, Ring) are covered in detail in Intent Netting → Matching Engine.
Solver Auction and Ranking
Shows eligibility filtering, solver quote collection, ranking, and the winning signed order handoff.
Dutch Auction Fallback#
If no solver responds within the RFQ window, the order can fall back to a Dutch auction mode with three time-based phases:
| Phase | Window | Max Fee | Solver Tier |
|---|---|---|---|
| SAFE | 0–2 min | 1 bps | Highest-rated solvers only |
| BALANCED | 2–10 min | 3 bps (linear ramp from 1 bps) | Broader solver set |
| FAST | 10+ min | Premium | Widest solver set, or cancel |
The fee ramps linearly between phases, attracting solvers by offering improving economics over time.
Solver Adapter Architecture#
Two-layer adapter pattern normalizes solver protocols:
- Layer 1 (
SolverAdapter) - protocol-specific → standardGetQuoteRequest/Response - Layer 2 (
SolverAdapterTrait) - runtime config, metrics, error categorization, timeouts
TetraFi#
Native protocol for the reference OIF solver. Richest metadata surface.
OIF#
Follows the Open Intents Framework v0 REST spec; on-chain side implements ERC-7683. Plain HTTPS - solver hosts POST /quotes.
Across#
Bridge integration. Route-based quoting mapped to TetraFi corridors.
Solver Integration Contract#
The contract below is the Open Intents Framework v0 REST spec - an open standard, not a TetraFi-specific protocol. Any solver already OIF-compliant against other intent networks can be pointed at TetraFi with configuration alone. On-chain, TetraFi implements ERC-7683 StandardOrder typed data, signed by takers via EIP-712.
TetraFi's aggregator calls your HTTPS endpoints during the auction window. You do not maintain a persistent connection to TetraFi to receive RFQs - there is no SDK or WebSocket required for quote participation.
Four endpoints your solver must expose (OIF v0, camelCase wire format):
| Method | Path | Purpose |
|---|---|---|
GET | /tokens | Capability probe - declare supported chains, tokens, and settler addresses |
POST | /quotes | Return competing quotes for an intent (quote = response body, unsigned typed data) |
POST | /orders | Accept the signed order once your quote wins |
GET | /orders/{orderId} | Report current solver-side order status |
POST /quotes#
Request
1{2 "user": "0x…",3 "intent": { "inputToken": "0x…", "outputToken": "0x…", "inputAmount": "1000000000000", "originChainId": 8453, "destinationChainId": 10 },4 "supportedTypes": ["oif-swap", "oif-escrow-v0"]5}Response
1{2 "quotes": [3 {4 "quoteId": "qt_…",5 "order": { /* StandardOrder - see Settlement Flows */ },6 "validUntil": 1734375600,7 "eta": 12,8 "provider": "acme",9 "failureHandling": "refund",10 "partialFill": false,11 "preview": { "outputAmount": "999725000000", "feeBps": 2.75 },12 "metadata": {}13 }14 ]15}POST /orders#
Request
1{2 "order": { /* StandardOrder */ },3 "signature": "0x…",4 "quoteId": "qt_…",5 "originSubmission": { "txHash": "0x…" },6 "metadata": {}7}Response: { "orderId": "…", "status": "Deposited | Filled | Attested | Claimed | Refunded", "message": "…", "order": { … }, "metadata": {} }
Auth#
Either JWT via POST /auth/register + POST /auth/refresh (OIF-defined), or a pre-shared bearer header - configured per solver at onboarding.
Push updates are optional - and pull-only for solvers. WebSocket (orders:* topic) and webhooks push post-fill order state to solvers; the public WS does not accept streamed quotes or push RFQs from TetraFi. Polling GET /orders/{orderId} on your own server is fully supported by the OIF contract and is the simplest integration path. Non-OIF streaming integrations require a custom SolverAdapter written by the TetraFi team. See the Solver Integration Guide for the end-to-end flow.
Timeout Configuration#
| Parameter | Default | Range |
|---|---|---|
per_solver_timeout_ms | 0ms | 100–30,000 ms |
global_timeout_ms | 0ms | 100–60,000 ms |
fill_deadline | 0s | On-chain deadline |
The aggregator terminates early once min_quotes have been received, avoiding unnecessary wait time.