Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Fynd
A high-performance DeFi route-finding engine built on Tycho. Finds optimal swap routes across multiple DeFi protocols in real-time.
[!CAUTION] Alpha Software — Unaudited Contracts
Fynd's smart contracts (TychoRouter V3, Vault, Executors) are still undergoing a security audit. Funds stored in the router (including vault deposits) may be lost. Use at your own discretion.
Features
- Multi-protocol routing - Routes through your favorite on-chain liquidity protocol, like Uniswap, Balancer, Curve, RFQ protocols, or any other protocol supported by Tycho.
- Real-time market data - Tycho Stream keeps all liquidity states synchronized every block
- Multi-algorithm competition - Multiple solver pools run different algorithm configurations in parallel; the best result wins
- Gas-aware ranking - Solutions are ranked by net output after gas costs, not just raw output
- Sub-100ms solves - Dedicated OS threads for CPU-bound route finding, separate from the async I/O runtime
- Production-ready - Prometheus metrics, structured logging, health endpoints, graceful shutdown
- Extensible - Implement the
Algorithmtrait to add new routing strategies with zero framework changes - Modular - Use just the core solving logic, or build a custom HTTP server with your own middleware
Architecture
Fynd is organized into three crates:
fynd-core- Pure solving logic with no HTTP dependencies. Use this if you want to integrate Fynd's routing algorithms into your own application.fynd-rpc- HTTP RPC server builder with customizable middleware. Use this to build a custom HTTP server with your own configuration.fynd- Complete CLI application that runs an HTTP RPC server. Use this to run Fynd as a standalone service.
Prerequisites
- Rust 1.92+
- A Tycho API key (get one here)
Run the Solver
# Clone and build
# Set required environment variables
# Run
Note:
--rpc-urldefaults tohttps://eth.llamarpc.com. For production, provide a dedicated endpoint:
The solver starts on http://localhost:3000 by default.
Including RFQ Protocols
You can include RFQ (Request-for-Quote) protocols alongside on-chain protocols:
Limitations:
- RFQ protocols cannot run alone — at least one on-chain protocol is required.
Environment variables:
- RFQ protocols typically require API keys, which are passed via environment variables. Check the RFQ protocol docs for the specific variables each protocol needs.
Run on a specific chain
You can run on any chain supported by Tycho (see Tycho Hosted endpoint)
Request a Quote
Check Health
API Reference
POST /v1/quote
Submit one or more swap orders and receive optimal routes.
Request:
| Field | Type | Required | Description |
|---|---|---|---|
orders[].token_in |
address | Yes | Token to sell |
orders[].token_out |
address | Yes | Token to buy |
orders[].amount |
string | Yes | Amount in token units (integer string) |
orders[].side |
string | Yes | "sell" (exact input) |
orders[].sender |
address | Yes | Sender address |
orders[].receiver |
address | No | Receiver (defaults to sender) |
options.timeout_ms |
integer | No | Solve timeout in ms (default: 100) |
options.min_responses |
integer | No | Early return threshold (default: 0, wait for all) |
options.max_gas |
string | No | Max gas filter (no limit if omitted) |
options.encoding_options.slippage |
float | No | Slippage tolerance for encoded transactions (e.g., 0.01 for 1%). No encoding if encoding_options is omitted |
options.encoding_options.transfer_type |
string | No | Input token transfer method: transfer_from (default) or transfer_from_permit2 |
options.encoding_options.permit |
object | No | Permit2 single-token authorization. Required when using transfer_from_permit2 |
options.encoding_options.permit2_signature |
string | No | Permit2 signature (hex-encoded). Required when permit is set |
options.encoding_options.client_fee_params |
object | No | Client fee configuration. See Client Fees |
Response:
GET /v1/health
Returns service health status. HTTP 200 if healthy, 503 if unhealthy.
The service is healthy when market data is fresh (< 60s old), derived data has been
computed at least once, and gas price is not stale (when --gas-price-stale-threshold-secs
is configured). The derived_data_ready field indicates overall readiness, not per-block
freshness — algorithms that require fresh derived data will wait for recomputation before
solving.
Configuration
CLI / Environment Variables
| Flag | Env Var | Default | Description |
|---|---|---|---|
--rpc-url |
RPC_URL |
https://eth.llamarpc.com |
Ethereum RPC endpoint for the target chain |
--tycho-url |
TYCHO_URL |
(chain-specific) | Tycho URL (e.g. tycho-fynd-ethereum.propellerheads.xyz) |
--tycho-api-key |
TYCHO_API_KEY |
- | Tycho API key |
--chain |
- | Ethereum |
Target chain |
-p, --protocols |
- | (all available) | Protocols to index (comma-separated). Auto-fetched from Tycho RPC if omitted. |
--http-host |
HTTP_HOST |
0.0.0.0 |
HTTP bind address |
--http-port |
HTTP_PORT |
3000 |
API port |
--min-tvl |
- | 10.0 |
Minimum pool TVL in native token |
--worker-router-timeout-ms |
- | 100 |
Default solve timeout |
-w, --worker-pools-config |
WORKER_POOLS_CONFIG |
worker_pools.toml |
Worker pools config |
--blocklist-config |
BLOCKLIST_CONFIG |
blocklist.toml |
Path to blocklist TOML config file |
--gas-price-stale-threshold-secs |
- | (disabled) | Health returns 503 when gas price exceeds this age |
See --help for the full list.
Find the list of all available protocols on Tycho here
Worker Pools (worker_pools.toml)
Configure solver pools with different algorithms and parameters:
[]
= "most_liquid"
= 5
= 2
= 100
[]
= "most_liquid"
= 3
= 2
= 3
= 5000
A Worker Pool runs a configurable number of Worker threads, all using the same algorithm and pulling tasks from a shared queue. Each worker handles one order at a time — so a pool with 5 workers can solve up to 5 orders concurrently.
Multiple pools run in parallel, each producing its own solution per order. The system then picks the best result across pools within the timeout.
Example: Given the config above and 3 incoming orders:
fast_2hopassigns 1 worker per order (3/5 workers busy)deep_3hopassigns 1 worker per order (3/3 workers busy)
Each order gets 2 candidate solutions — one from each pool — and the best is selected.
Blocklist Config
By default, Fynd loads blocklist.toml from the working directory. The default excludes components with known
simulation issues (e.g., rebasing tokens). Override with --blocklist-config:
The config file uses a [blocklist] section with component IDs to exclude:
[]
= [
"0x86d257cdb7bc9c0df10e84c8709697f92770b335",
]
Observability
- Metrics: Prometheus endpoint at
http://localhost:9898/metrics - Logging: Structured logging via
RUST_LOG(e.g.,RUST_LOG=info,fynd=debug) - Health:
GET /v1/healthreturns data freshness and pool count
Extensibility
Using a Custom Algorithm
Implement the Algorithm trait and plug it into a WorkerPoolBuilder via with_algorithm() — no changes to
fynd-core required:
let = new
.name
.with_algorithm
.algorithm_config
.num_workers
.build?;
See the custom_algorithm example for a full walkthrough.