Encoding
The first step to executing a trade on-chain is encoding.
Our Rust crate converts your trades into calldata that the Tycho contracts can execute.
See this Quickstart section for an example of how to encode your trade.
Models
These are the models used as input and output of the encoding crate.
The Solution struct defines your order and how it should be filled. This is the input to the encoding module.
sender
Bytes
Address of the sender of the token in
receiver
Bytes
Address of the receiver of the token out. If set to the TychoRouter address, these funds will be assigned to the user's Vault.
token_in
Bytes
The token being sold
amount_in
BigUint
Amount of the input token
token_out
Bytes
The token being bought.
min_amount_out
BigUint
Minimum amount the receiver must receive at the end of the transaction
swaps
Vec<Swap>
List of swaps to fulfil the solution.
user_transfer_type
UserTransferType
How user funds are transferred into the router (see below)
Specifies how user funds (the input token) enter the router:
TransferFromPermit2
Use Permit2 for token transfer. You must approve the Permit2 contract and sign the permit externally.
TransferFrom (default)
Use standard ERC-20 approve + transferFrom. You must approve the TychoRouter to spend your tokens.
UseVaultsFunds
No transfer is performed. Uses tokens already deposited in the TychoRouter vault.
A solution consists of one or more swaps. Each swap represents an operation on a single pool.
The Swap struct has the following attributes:
component
ProtocolComponent
Protocol component from Tycho core
token_in
Bytes
Address of the token you provide to the pool
token_out
Bytes
Address of the token you expect from the pool
split
f64
Percentage of the amount in to be swapped in this operation (for example, 0.5 means 50%)
user_data
Option<Bytes>
Optional user data to be passed to encoding
protocol_state
Option<Arc<dyn ProtocolSim>>
Optional protocol state used to perform the swap
estimated_amount_in
Option<BigUint>
Optional estimated amount in for this Swap. This is necessary for RFQ protocols. This value is used to request the quote.
Split Swaps
Solutions can split one or more token hops across multiple pools. The output of one swap is divided into parts, each used as input for subsequent swaps:
By combining splits, you can build complex trade paths.
We validate split swaps. A split swap is valid if:
The output token is reachable from the input token through the swap path
No tokens are unconnected
Each split amount is smaller than 1 (100%) and at least 0 (0%)
For each set of splits, set the split for the last swap to 0. This tells the router to send all tokens not assigned to the previous splits in the set (i.e., the remainder) to this pool.
The sum of all non-remainder splits for each token is smaller than 1 (100%)
Example Solution
The following diagram shows a swap from ETH to DAI through USDC. ETH arrives in the router and is wrapped to WETH. The solution then splits between three (WETH, USDC) pools and finally swaps from USDC to DAI on one pool.
The Solution object for the given scenario would look as follows:
Swap Group
Protocols like Uniswap V4 eliminate token transfers between consecutive swaps through flash accounting. If your solution contains sequential (non-split) swaps on such protocols, the encoder compresses them into a single swap group, requiring only one call to the executor.
In the example above, the encoder will compress three consecutive swaps into the following swap group to call the Executor:
A solution contains multiple swap groups when it uses different protocols.
Encoding produces an EncodedSolution with these attributes:
swaps
Vec<u8>
The encoded calldata for the swaps.
interacting_with
Bytes
The address of the contract to be called (it can be the Tycho Router or an Executor)
selector
String
The selector of the function to be called.
n_tokens
usize
The number of tokens in the trade (relevant for split swaps only).
permit
Option<PermitSingle>
Optional permit object for the trade (if permit2 is enabled).
Encoder
TychoRouterEncoder prepares calldata for execution via the Tycho Router contract. It supports multi-hop and split swaps.
Builder
Builder options:
swap_encoder_registry— Registry of protocol-specificSwapEncoders used during encoding. Useadd_default_encodersfor built-in support, or add custom encoders for protocols you've implemented locally.router_address— Router address for execution. Defaults to the deployed address for the given chain ( see Tycho addresses).
Builder Example Usage
Swap Encoders
Each protocol needs its own SwapEncoder to define how the protocol encodes swaps into calldata.
The SwapEncoderRegistry manages these encoders. Call add_default_encoders() to use the built-in implementations. This method accepts an optional executors_addresses JSON string with executor addresses for encoding. Pass None to default to config/executor_addresses.json.
If you need to add custom protocol support, register your own encoder implementation:
Encode
Convert solutions into calldata:
This returns a Vec<EncodedSolution> containing only the encoded swaps. It does **not ** build the full calldata. You must encode the full method call yourself. If you use Permit2, you also need to sign the permit object.
The full method call includes the following parameters, which act as execution guardrails:
amountInandtokenIn— the amount and token to be transferred into the TychoRouter from you.minAmountOutandtokenOut— the minimum amount you want to receive. For maximum security, determine this from a * third-party source*.receiver— who receives the final output. Set this to the TychoRouter address to credit output tokens to the vault.nTokens— (split swaps only) the number of distinct tokens in the split routing graph.clientFeeParams— controls fee-taking and client contribution (see Client Fee Signature below). Pass all-zero values if you don't need fees.
The ClientFeeParams struct is defined as:
clientFeeBps
Fee percentage in basis points. 100 = 1%. Set to 0 to disable.
clientFeeReceiver
Address that receives the client's portion of the fee (credited to their vault balance).
maxClientContribution
Maximum amount the client is willing to pay out of pocket if slippage causes the output to fall below minAmountOut. If the shortfall exceeds this value, the transaction reverts. Set to 0 if the client should not subsidize.
deadline
Unix timestamp after which the signature is no longer valid.
clientSignature
EIP-712 signature over all other fields, signed by clientFeeReceiver.
These execution guardrails protect against MEV exploits. Setting them correctly gives you full control over swap security.
Refer to the quickstart for an example of converting an EncodedSolution into full calldata. Tailor the example to your use case. See the TychoRouter contract functions for reference.
Client Fee Signature
If you don't want fees, pass all-zero values: clientFeeBps: 0, clientFeeReceiver: address(0), maxClientContribution: 0, deadline: 0, and an empty clientSignature.
If you do want fees, the clientFeeReceiver must sign the fee parameters using EIP-712. This prevents third parties from spoofing fee configurations. The signature covers the following typed struct:
The EIP-712 domain is:
with name = "TychoRouter", version = "1", and verifyingContract set to the TychoRouter contract address.
Sign fee parameters example
Example of signing the fee parameters in Rust using alloy:
The returned 65-byte signature is passed as the clientSignature field in ClientFeeParams.
Run as a Binary
Installation
Build and install the binary:
After installation, you can use the tycho-encode command from any directory in your terminal.
Commands
The command lets you choose the encoder:
tycho-router: Encodes a transaction using theTychoRouterEncoder.
The commands accept the same options as the builder (more here).
Last updated
Was this helpful?

