Simulation
To enable simulations for a newly added protocol, it must first be integrated into the Tycho monorepo. Please submit a pull request to the repository targeting crates/tycho-simulation.
Native Integration
In order to add a new native protocol, you will need to complete the following high-level steps:
Create a protocol state struct that contains the state of the protocol, and implements the
ProtocolSimtrait (see here).Create a tycho decoder for the protocol state: i.e. implement
TryFromWithBlockforComponentWithStateto your new protocol state.
Each native protocol should have its own module under crates/tycho-simulation/src/evm/protocol.
VM Integration
To create a VM integration, provide a manifest file and an implementation of the corresponding adapter interface. The Tycho monorepo contains the tools to integrate DEXs and other onchain liquidity protocols into Tycho.
Example Implementations
The following exchanges are integrated with the VM approach:
Balancer V2 (see code here)
Install prerequisites
Install Foundry, start by downloading and installing the Foundry installer:
curl -L https://foundry.paradigm.xyz | bashthen start a new terminal session and run
foundryupClone the Tycho monorepo:
git clone https://github.com/propeller-heads/tychoInstall dependencies:
cd ./tycho/protocols/adapter-integration/evm/ forge install
Understanding the ISwapAdapter
Read the documentation of the Ethereum Solidity interface. It describes the functions that need to be implemented and the manifest file.
Additionally, read through the docstring of the ISwapAdapter.sol interface and the ISwapAdapterTypes.sol interface, which defines the data types and errors the adapter interface uses. You can also generate the documentation locally and look at the generated documentation in the ./docs folder:
Implementing the ISwapAdapter interface
Your integration should be in a separate directory in the protocols/adapter-integration/evm/src folder. Start by copying the template directory:
Implement the ISwapAdapter interface in the ./protocols/adapter-integration/evm/src/<your-adapter-name>.sol file. See Balancer V2 implementation for reference.
Testing your implementation
Set up test files:
Copy
evm/test/TemplateSwapAdapter.t.solRename to
<your-adapter-name>.t.sol
Write comprehensive tests:
Test all implemented functions.
Use fuzz testing (see Foundry test guide, especially the chapter for Fuzz testing)
Reference existing test files:
BalancerV2SwapAdapter.t.sol
Configure fork testing (run a local mainnet fork against actual contracts and data):
Set
ETH_RPC_URLenvironment variableUse your own Ethereum node or services like Infura
Run the tests with
Add implementation to Tycho simulation
Once you have the swap adapter implemented for the new protocol, you will need to:
Generate the adapter runtime file by running the
protocols/adapter-integration/evm/scripts/buildRuntime.shscript with the proper input parameters. For example, in order to build theBalancer V2runtime, the following command can be run:\Add the associated adapter runtime file to
crates/tycho-simulation/src/evm/protocol/vm/assets. Make sure to name the file according to the protocol name used by Tycho Indexer in the following format:<Protocol><Version>Adapter.evm.runtime. For example:vm:balancer_v2will beBalancerV2Adapter.evm.runtime. Following this naming format is important as we use an automated name resolution for these files.
Filtering
If your implementation does not support all pools indexed for a protocol, you can create a filter function to handle this. Add your filter to filters.rs alongside the existing ones, and add your protocol name to the EXCHANGES_REQUIRING_FILTER constant in evm/stream.rs. This warns callers if they stream your protocol without providing the required filter.
Gas Estimation
The gas estimator builds total execution gas from two components: the simulation-reported swap gas and token-transfer overhead that simulation does not capture. Which overhead applies depends on your protocol's behavior.
Native Integrations
Your get_amount_out implementation must return a gas estimate. Measure only what happens inside the protocol's swap() call, including any token transfers that occur during a callback.
After implementing, add your protocol to the relevant constant slices in gas_estimator.rs:
PROTOCOLS_CALLBACK: The pool pulls tokens inside a callback fired duringswap(). The simulation captures that transfer, so the estimator adds no separate input-transfer cost.PROTOCOLS_OPTIMIZABLE_TRANSFER_IN: The router might send tokens directly to the pool, skipping the router-to-pool hop. The estimator adds no router-to-pool transfer cost for non-split strategies.PROTOCOLS_NEEDING_APPROVAL: The pool pulls tokens from the router viaapprove+transferFrom(ProtocolWillDebit). The simulation includes thetransferFromgas, but not theapprove(25,000 gas); the estimator adds it separately.PROTOCOLS_OUTPUT_TO_ROUTER: The pool sends output tomsg.sender(the router) instead of to an explicit receiver. The estimator adds an extra forward transfer from the router to the final receiver.
A protocol can appear in more than one list.
VM Integrations
In your adapter contract's swap function, measure gas with gasleft() and return it in the Trade struct. The measurement must cover only the pool call itself.
Do not include gas for:
Token transfers (input or output): the Dispatcher handles these via
TransferManagerapprove()calls: also handled by the Dispatcher
Including them would double-count with what the gas estimator adds based on your protocol's category.
Last updated
Was this helpful?

