Encoding
The first step to execute a trade on chain is encoding.
Our Rust crate offers functionality to convert your trades into calldata, which the Tycho contracts can execute.
See this Quickstart section for an example of how to encode your trade.
Encoders
Builder
To create an EVMTychoEncoder
, you need to use an EVMEncoderBuilder
. A valid encoder needs to have a chain and a strategy encoder set. More info about the strategies can be found here.
To simplify the setup, we provide shortcut methods for common use cases:
tycho_router
: Uses the TychoRouter contract, assuming that you transfer the input token to the contract in the same transaction.tycho_router_permit2
: Uses Permit2 for token approvals and transfers. This method requires a signer private key.direct_execution
: Generates calldata for direct execution via the Executor contracts, bypassing the Tycho router. This is useful if you're integrating Tycho Executors with your own routing logic. See more details here.
Example Usage
Strategy
When initializing the EVMEncoderBuilder, you must define a strategy. The strategy determines how the trade is encoded.
Currently, we support two encoding strategies:
Split Swap Strategy: Enables multi-hop trade execution via the Tycho Router. Supports split swap solutions.
Executor Strategy: Generates calldata for direct execution via the Executor contracts (no router interaction). Supports multi-swap trades only if all swaps can be compressed into a single Swap Group, otherwise, only single-hop trades are supported.
Models
Solution Struct
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 (exact in) or sold (exact out). This token's final balance will be checked by the router if you provide a 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
Address of the router contract to be used.
swaps
Vec<Swap>
List of swaps to fulfill the solution.
slippage
Option<f64>
If set, this value will be applied to expected_amount
and will become the checked_amount if greater than the user-inputted checked_amount
(exact in) or less than the user-inputted checked_amount
(exact out).
expected_amount
Option<BigUint>
Amount expected to receive (exact in) or pay (exact out) for this solution. Slippage is applied onto this amount.
checked_amount
Option<BigUint>
Minimum amount out (exact in) or maximum amount in (exact out) to be checked for the solution to be valid. If not set, no checks will be performed.
native_action
Option<NativeAction>
Wrapping and Unwrapping
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 ETHThe
token_in
of the first swap should be WETH
When unwrapping:
The
checked_token
of the solution should be ETHThe
token_out
of the final swap should be WETH
Swap Struct
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%)
To create a Swap
, use the new
function where you can pass any struct that implements Into<ProtocolComponent>
.
Split Swaps
Solutions can have splits where one or more token hops are split between two or more pools. 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%)
Swap Group
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 UniswapV4 executor:
One solution will contain multiple swap groups if different protocols are used.
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:
Transaction struct
Encoding returns you a Transaction
struct. It has the following attributes:
to
Bytes
The contract address to which you send the transaction.
value
BigUint
Amount of ETH to send (for native transactions)
data
Vec<u8>
The encoded calldata containing the swap details.
Run as a Binary
Installation
First, 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 encoding strategy to be used. These correspond to the shortcut methods of the builder. The available strategies are:
tycho-router
: Encodes a transaction using the Tycho Router encoding strategy. Requires a private key for signing Permit2.tycho-router-permit2
: Encodes a transaction using the Tycho Router encoding strategy. Requires a private key for signing Permit2.direct-execution
: Encodes a transaction using the direct execution encoding strategy. Does not require a private key.
Encoding Transactions
The commands accept the following options:
--config_path
: Path to the executor addresses configuration file (defaults tosrc/encoding/config/executor_addresses.json
)--swapper-pk
: Private key for signing approvals (required when direct_execution is false)
Example
Here's a complete example that encodes a swap from WETH to DAI using Uniswap V2 and the Tycho Router strategy with Permit2:
Last updated