Encoding
Last updated
Last updated
The first step to execute a trade on chain is encoding.
Our Rust offers functionality to convert your trades into calldata, which the Tycho contracts can execute.
See this section for an example of how to encode your trade.
These are the models used as input and output of the encoding crate.
The Solution
struct specifies the details of your order and how it should be filled. This is the input of the encoding module.
The Solution
struct consists of the following attributes:
given_token
Bytes
The token being sold (exact in) or bought (exact out)
given_amount
BigUint
Amount of the given token
checked_token
Bytes
The token being bought. This token's final balance will be checked by the router using checked_amount
.
sender
Bytes
Address of the sender of the given token
receiver
Bytes
Address of the receiver of the checked token
exact_out
bool
False if the solution is an exact input solution (i.e. solves a sell order). Currently only exact input solutions are supported.
router_address
Bytes
swaps
Vec<Swap>
List of swaps to fulfil the solution.
checked_amount
BigUint
Minimum amount out to be checked for the solution to be valid if passing through the TychoRouter
.
native_action
Option<NativeAction>
Our router accepts wrapping native tokens to wrapped token before performing the first swap, and unwrapping wrapped tokens to native tokens after the final swap, before sending the funds to the receiver.
In order to perform this, the native_action
parameter of the solution must be set to either Some(NativeAction.WRAP)
or Some(NativeAction.UNWRAP)
.
When wrapping:
The given_token
of the solution should be ETH
The token_in
of the first swap should be WETH
When unwrapping:
The checked_token
of the solution should be ETH
The token_out
of the final swap should be WETH
A solution consists of one or more swaps. A swap represents a swap operation to be performed on a pool.
The Swap
struct has the following attributes:
component
ProtocolComponent
Protocol component from Tycho core
token_in
Bytes
Token you provide to the pool
token_out
Bytes
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%)
Solutions can have splits where one or more token hops are split between two or more pools. This means that the output of one swap can be split into several parts, each used as the input for subsequent swaps. The following are examples of different split configurations:
By combining splits creatively, you can build highly customized and complex trade paths.
We perform internal validation on split swaps. A split swap is considered valid if:
The checked token is reachable from the given token through the swap path
There are no tokens that are unconnected
Each split amount is small than 1 (100%) and larger or equal to 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%)
Certain protocols, such as Uniswap V4, allow you to save token transfers between consecutive swaps thanks to their flash accounting. In case your solution contains sequential (non-split) swaps of such protocols, our encoders compress these consecutive swaps into a single swap group, meaning that a single call to our executor is sufficient for performing these multiple swaps.
In the example above, the encoder will compress three consecutive swaps into the following swap group to call the Executor:
One solution will contain multiple swap groups if different protocols are used.
The output of encoding is EncodedSolution
. It has the following 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.
permit
Option<PermitSingle>
Optional permit object for the trade (if permit2 is enabled).
Tycho Execution provides two main encoder types:
TychoRouterEncoder: This encoder prepares calldata for execution via the Tycho Router contract. It supports complex swap strategies, including multi-hop and split swaps. Use this when you want Tycho to handle routing and execution within its own router contract.
Choose the encoder that aligns with how you plan to route and execute trades.
For each encoder, there is a corresponding builder:
TychoRouterEncoderBuilder
TychoExecutorEncoderBuilder
Both builders require the target chain to be set.
You can convert solutions into calldata using:
The full method call includes the following parameters, which act as execution guardrails:
amountIn
and tokenIn
– the amount and token to be transferred into the TychoRouter/Executor from you
minAmountOut
and tokenOut
– the minimum amount you want to receive of token out. For maximum security, this min amount should be determined from a third party source.
receiver
– who receives the final output
wrap/unwrap
flags – if native token wrapping is needed
isTransferFromAllowed
– if this should perform a transferFrom
to retrieve the input funds. This will be false if you send tokens to the router in the same transaction before the swap.
These execution guardrails protect against exploits such as MEV. Correctly setting these guardrails yourself gives you full control over your swap security and ensures that the transaction cannot be exploited in any way.
First, build and install the binary:
After installation, you can use the tycho-encode
command from any directory in your terminal.
The command lets you choose the encoder:
tycho-router
: Encodes a transaction using the TychoRouterEncoder
.
tycho-execution
: Encodes a transaction using the TychoExecutorEncoder
.
Example
Here's a complete example that encodes a swap from WETH to DAI using Uniswap V2 and the TychoRouterEncoder
with Permit2 on Ethereum:
Address of the router contract to be used. See Tycho addresses .
If set, the native token will be wrapped before the swap or unwrapped after the swap (more ).
To create a Swap
, use the new
where you can pass any struct that implements Into<ProtocolComponent>
.
TychoExecutorEncoder: This encoder prepares calldata for direct execution of individual swaps using the Executor contracts, bypassing the router entirely. It encodes one swap at a time and is ideal when integrating Tycho Executors into your own router contract. See more details .
user_transfer_type: UserTransferType
Defines how to funds will be transferred from the user. The options are TransferFromPermit2
, TransferFrom
and None
(see more about token transfers ).
router_address
Router address to use for execution (defaults to the address corresponding to the given chain in config/router_addresses.json
). See Tycho addresses .
This method returns a Vec<
>
, which contains only the encoded swaps of the solutions. It does not build the full calldata. You must encode the full method call yourself. If you are using Permit2 for token transfers, you need to sign the permit object as well.
Refer to the code for an example of how to convert an EncodedSolution
into full calldata. You must tailor this example to your use case to ensure that arguments are safe and correct. See the functions defined in the TychoRouter
contract for reference.
There is another method in our encoder that you can use for testing purposes.
This method returns full Transaction
structs, ready to submit. It uses our example encoding logic internally (i.e., encode_tycho_router_call
), which is meant for development and prototyping only.
We do not recommend using this in production, as it takes control away from you and may not meet your security or routing needs.
The commands accept the same options as the builders (more ).