Supported Protocols
Currently, Tycho supports the following protocols:
uniswap_v2
Native (UniswapV2State)
1 μs (0.001 ms)
Ethereum, Base, Unichain, Arbitrum, Polygon, BSC, Robinhood
uniswap_v3
Native (UniswapV3State)
20 μs (0.02 ms)
Ethereum, Base, Unichain, Arbitrum, Polygon, BSC, Robinhood
uniswap_v4
Native (UniswapV4State)
3 μs (0.003 ms)
Ethereum, Base, Unichain, Arbitrum, Polygon, BSC, Robinhood
Only core uniswap V4 pools are supported on this native implementation.
uniswap_v4_hooks
Hybrid (UniswapV4State)
[DCI indexed]
1 ms
Ethereum
All composable hooks are supported.
Angstrom: see more details below.
recommended: set a high startup timeout on the stream builder: .startup_timeout(Duration::from_secs(120))
vm:balancer_v2
VM (EVMPoolState)
[DCI indexed]
0.5 ms
Ethereum
A few pools are currently unsupported. Use balancer_v2_pool_filter
vm:curve
Hybrid (CurveState)
[DCI indexed]
30 μs (0.03 ms)
Ethereum
Pools with rate-bearing or rebasing coins are unsupported. Use curve_filter.
NOTE: curve requires a node RPC to fetch some code at startup. Please set the RPC_URL env var.
sushiswap_v2
Native (UniswapV2State)
1 μs (0.001 ms)
Ethereum
pancakeswap_v2
Native (PancakeswapV2State)
1 μs (0.001 ms)
Ethereum, BSC
pancakeswap_v3
Native (UniswapV3State)
20 μs (0.02 ms)
Ethereum, Base, Arbitrum, BSC
quickswap_v2
Native (UniswapV2State)
3 μs (0.003 ms)
Polygon
ekubo_v2
Native (EkuboState)
1.5 μs (0.0015 ms)
Ethereum
ekubo_v3
Native (EkuboV3State)
9μs
Ethereum
Some extensions are unsupported. Use ekubo_v3_extension_filter. It also drops SignedExclusiveSwap pools, which need a per-swap signature passed to the encoder as user_data. If you can supply that signature, use ekubo_v3_extension_filter_with_signed_exclusive_swap instead to keep those pools.
vm:maverick_v2
VM (EVMPoolState)
-
Ethereum
aerodrome_v1
Native (AerodromeV1State)
3 μs (0.003 ms)
Base
aerodrome_slipstreams
Native
(AerodromeSlipstreamsState)
-
Base
Dynamic-fee pools untouched so far in the execution block quote the worse of the initial and dynamic fee, so the output is never over-quoted. If your submission path lands the swap first in the block, opt in per registration: exchange_with_decoder_context with DecoderContext::new().assume_first_in_block(true).
velodrome_slipstreams
Native
(VelodromeSlipstreamsState)
-
Unichain
lunarbase
Native (LunarBaseState)
7 μs (0.007 ms)
Base
rocketpool
Native (RocketpoolState)
-
Ethereum
Note: the DepositPool was recently updated to v1.4. This new version is supported by tycho_simulation > v0.248.0 and above.
fluid_v1
Native (FluidV1)
[DCI indexed]
-
Ethereum
Note: paused pools are still indexed. To filter them out use fluid_v1_paused_pools_filter.
erc4626
Native (ERC4626State)
[DCI indexed]
-
Ethereum
A few vaults are unsupported. Use erc4626_filter
For RFQ protocols that fetch prices from market makers via WebSocket or API, see Request for Quote Protocols.
Integration Types
There are three types of protocol integrations:
Native protocols have been implemented using an analytical approach and are ported to Rust - faster simulation.
VM protocols execute the VM bytecode locally - this is easier to integrate the more complex protocols, however has slower simulation times than a native implementation.
Some VM protocols are DCI indexed. DCI is our Dynamic Contract Indexer and provides more flexibility on indexing restraints. Note - these protocols tend to serve a lot of data and experience occasional streaming delays.
Hybrid uses a combination of the two - native for general protocol logic portable to Rust, and VM for the more complex or pool-specific logic.
Interested in adding a protocol? Refer to the Tycho Simulation for DEXs documentation for implementation guidelines.
Protocol-Specific Details
While most protocols work out of the box, some require additional configuration or have specific considerations you should be aware of.
Angstrom (Uniswap V4 Hook)
Angstrom locks its pools at the start of every block. A swap that trades against one in the same block must carry a pool unlock attestation, which Tycho fetches from Angstrom's API, as its hook data. If the transaction lands after the attested blocks have passed, the attestation no longer unlocks the pool.
Required configuration:
Set the
ANGSTROM_API_KEYenvironment variable (request one from the Angstrom team directly)Set
ANGSTROM_BLOCKS_IN_FUTUREenvironment variable (if you want to override the default value of 10 blocks). Important trade-off: The more blocks you fetch, the more calldata will be sent to the Tycho Router, making execution more gas expensive.
If ANGSTROM_API_KEY is not set, ProtocolStreamBuilder excludes Angstrom pools from uniswap_v4_hooks by default (unless you pass your own filter function), since routes over these pools would fail at encoding without attestations.
Attestations are prefetched, so encoding an Angstrom swap makes no API call. A background thread refreshes the attestation window twice per block and encoding reads the result from a process-wide cache. The thread starts when you build a SwapEncoderRegistry for Ethereum with ANGSTROM_API_KEY set, and it reads all three environment variables once, at that point.
Two consequences for your setup:
Build the encoder once at startup and reuse it. Encoding still works if you build a new encoder per quote, but the first Angstrom swap it encodes waits for the first fetch to finish.
Watch your logs for
Angstrom attestation cache is cold or stale. When the cached window is more than one block old, encoding fetches a fresh one inline and logs that warning. Encoding then pays the API round trip, so a steady stream of these means the background refresh is failing — the refresh logs its own error alongside them.
Last updated
Was this helpful?

