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.
Installation
The tycho-simulation package is available on crates.io.
Add it to your project's Cargo.toml:
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.
Get limits
get_limits returns a tuple containing the maximum amount in and out that can be traded between two tokens.
Query pool swap
query_pool_swap returns the swap volume that achieves a price goal on the pool, together with the pool's state after that swap.
The SwapConstraint you pass in QueryPoolSwapParams sets the goal:
SwapConstraint::TradeLimitPrice— maximise the trade while keepingamount_out / amount_inat or above a limit price.SwapConstraint::PoolTargetPrice— move the pool's marginal price down to a target price.
Both variants take a tolerance fraction that loosens the search, and optional min_amount_in / max_amount_in bounds. Prices use token_out (numerator) per token_in (denominator), net of all fees.
Price represents a price as a rational fraction (numerator / denominator).
PoolSwap holds the resulting trade, read through its accessors:
price_points are the points on the price curve the search passed through. Reuse them as bounds for subsequent searches on the same pool.
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.
ProtocolStreamBuilder applies a curated blocklist of pools that are known to break simulation (for example, rebasing-token and insolvent pools) by default, so the stream excludes them automatically. To exclude additional components, pass their IDs to blocklist_components(...).
The stream created emits Update messages which consist of:
block number_or_timestamp- the block this update message refers tonew_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 updatedProtocolSimstates 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,
ProtocolSimstates contain simulation-critical data only. Reference data such as protocol names and token information is provided in theProtocolComponentobjects within thenew_pairsfield. 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.
Partial Blocks (Flashblocks)
Some chains, such as Base, support flash blocks — pre-confirmation updates that contain parts of a future block before its construction is finished. Enable this on your stream to receive sub-block latency updates as they arrive. On chains without flash block support, enabling this flag is unsupported.
Block hashes in partial block messages are unstable — they change between partial updates and will differ from the final block hash. Do not use them as persistent identifiers or cache keys. See the Substreams documentation for details.
Example Use Case: Token Price Printer
You can find an example of a price printer here.
Clone the repo, then run:
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?

