For the complete documentation index, see llms.txt. This page is also available as Markdown.

Simulation

Simulate interactions with any protocol.

Tycho Simulation is a Rust crate that provides powerful tools for interacting with protocol states, calculating spot prices, and simulating token swaps.

The crate lives at crates/tycho-simulation inside the Tycho monorepo.

✨ New: Sub-Second Latency with Partial Blocks

Tycho now provides early support for partial blocks on Base, enabling sub-second latency by streaming pre-confirmation updates. Enable this feature with .enable_partial_blocks() on your ProtocolStreamBuilder.

Installation

The tycho-simulation package is available on crates.io.

Add it to your project's Cargo.toml:

Note: Replace x.y.z with the latest version number from crates.io. Using the latest release ensures you have the most up-to-date features and bug fixes.

Main Interface

All protocols implement the ProtocolSim trait (see definition here). It has the main methods:

Spot price

spot_price returns the pool's current marginal price.

Get amount out

get_amount_out simulates token swaps.

You receive a GetAmountOutResult , which is defined as follows:

new state allows you to, for example, simulate consecutive swaps in the same protocol.

Please refer to the in-code documentation of the ProtocolSim trait and its methods for more in-depth information.

Fee

fee returns the fee of the protocol as a ratio. For example if the fee is 1%, the value returned would be 0.01.

If the fee is dynamic, it returns the minimal fee.

Get limits

get_limits returns a tuple containing the maximum amount in and out that can be traded between two tokens.

If there are no hard limits to the swap (for example for Uniswap V2), the returned amount will be a "soft" limit, meaning that the actual amount traded could be higher but it's advised to not exceed it.

Swap to price

swap_to_price returns the amount of token_in required to move the pool's marginal price down to a target price, and the amount of token_out received. The target_price is denoted as token_out (numerator) per token_in (denominator) net of all fees.

Price represents a price as a rational fraction (numerator / denominator).

Trade represents a trade between two tokens at a given price on a pool.

Query supply

query_supply returns the maximum amount of token_out a pool can supply, and corresponding token_in demand, while respecting a minimum trade price. The target_price is denoted as token_out (numerator) per token_in (denominator) net of all fees.

Please refer to the in-code documentation of the ProtocolSim trait and its methods for more in-depth information.

Streaming Protocol States

To maintain up-to-date states of the protocols you wish to simulate over, you can use a Tycho Indexer stream. Such a stream can be set up in 2 easy steps:

Step 1: Fetch tokens

Collect token metadata up front and pass it to the stream builder in step 2. This token set is used to decode startup snapshots and initialize protocol states correctly. To simplify this, a util function called load_all_tokens is supplied and can be used as follows:

Step 2: Create a stream

You can use the ProtocolStreamBuilder to easily set up and manage multiple protocols within one stream. An example of creating such a stream with Uniswap V2 and Balancer V2 protocols is as follows:

set_tokens(...) does not act as an ongoing stream filter. New snapshots/components streamed later include the token metadata required for decoding.

Some protocols, such as Balancer V2 and Curve, require a pool filter to be defined to filter out unsupported pools. If a protocol needs a pool filter and the user does not provide one, a warning will be raised during the stream setup process.

The stream created emits Update messages which consist of:

  • block number_or_timestamp- the block this update message refers to

  • new_pairs- new components witnessed (either recently created or newly meeting filter criteria)

  • removed_pairs- components no longer tracked (either deleted due to a reorg or no longer meeting filter criteria)

  • states- the updated ProtocolSim states for all components modified in this block

The first message received will contain states for all protocol components registered to. Thereafter, further block updates will only contain data for updated or new components.

If you want to restrict processing to specific tokens (for example USDC/WETH only), apply that filter in your own consumer logic when reading new_pairs and states.

Note: For efficiency, ProtocolSim states contain simulation-critical data only. Reference data such as protocol names and token information is provided in the ProtocolComponent objects within the new_pairs field. Consider maintaining a store of these components if you need this metadata.

For a full list of supported protocols and the simulation state implementations they use, see Supported Protocols.

ProtocolStreamBuilder supports the same streaming options as the Tycho Client, with one difference: TVL estimates are always included in the simulation package and cannot be disabled.

Example: Consuming the Stream and Simulating

This simplified example shows how to process the stream created above and run simulations on the updated pools. Since the first message of the stream contains all pools, this means the first iteration of the loop will simulate on everything.

In this example we choose 2 tokens: a buy and a sell token, and simulate only on pools that contain those tokens.

Example Use Case: Token Price Printer

You can find an example of a price printer here.

Clone the repo, then run:

You'll need an RPC to fetch some static protocol info. You can use any RPC provider – e.g. set one up with Infura.

You will see a UI where you can select any pool, press enter, and simulate different trade amounts on the pool.

The program prints logs automatically to a file in the logs directory in the repo.

Last updated

Was this helpful?