Migration Guide: V2 to V3

This guide covers the breaking changes between V2 and V3 from the perspective of users who consume the Rust encoding library or interact with the TychoRouter contracts.

Encoding Changes

Solution Struct

Renamed fields:

V2
V3
Notes

given_token

token_in

The token being sold

given_amount

amount_in

Amount of the input token

checked_token

token_out

The token being bought

checked_amount

min_amount_out

Minimum acceptable output amount

Removed fields:

Field
Replacement

native_action: Option<NativeAction>

No longer needed. The encoder automatically inserts WETH wrap/unwrap swaps (see Wrapping and Unwrapping).

exact_out: bool

Only exact-in was ever supported. Removed for simplicity.

New fields:

Field
Type
Description

user_transfer_type

UserTransferType

How user funds enter the router. Moved here from the encoder builder.

client_fee_bps

u16

Fee in basis points charged by the client (0–10000).

client_fee_receiver

Bytes

Address to receive the client fee.

max_client_contribution

BigUint

Maximum amount the client will subsidize from their vault if slippage reduces the output below min_amount_out.

Private fields with getters/setters:

In V2, Solution fields were pub. In V3, all fields are private. Use the constructor and builder methods:

UserTransferType Moved to Solution

In V2, UserTransferType was set on the encoder builder. In V3, it is a field on each Solution, allowing different solutions in the same batch to use different funding methods.

The UserTransferType::None variant has been renamed to UserTransferType::UseVaultsFunds, reflecting the new vault-based architecture.

Swap Struct

Builder methods renamed (added with_ prefix for consistency):

V2
V3

.split(0.5)

.with_split(0.5)

.user_data(data)

.with_user_data(data)

.protocol_state(state)

.with_protocol_state(state)

.estimated_amount_in(amount)

.with_estimated_amount_in(amount)

Getter methods renamed (dropped get_ prefix):

V2
V3

.get_split()

.split()

.get_user_data()

.user_data()

.get_protocol_state()

.protocol_state()

.get_estimated_amount_in()

.estimated_amount_in()

EncodedSolution Struct

Fields are now private with getter methods, matching the pattern used elsewhere:

The function_signature field now reflects both the swap strategy and the funding mode. For example, splitSwapUsingVault(...) for a split swap using vault funds.

Wrapping and Unwrapping

V2 used a NativeAction enum on the Solution with Wrap and Unwrap variants. The router had dedicated wrap/unwrap flags.

V3 removes this entirely. Instead, a WETH executor handles wrapping and unwrapping as regular swap steps. The encoder automatically inserts these swaps when it detects ETH↔WETH gaps in the swap path.

This also works for mid-path bridging (e.g., if one swap outputs ETH and the next expects WETH) and at the end of a path. See more in Wrapping & Unwrapping.

Encoder Builder

Removed options:

V2 option
Notes

.user_transfer_type(...)

Moved to Solution.

.swapper_pk(...)

Removed. Sign Permit2 externally.

.historical_trade()

Removed. No longer needed.

The V3 builder only requires chain and swap_encoder_registry:

Transaction and encode_full_calldata Removed

The Transaction struct and encode_full_calldata method have been removed entirely. In V2, encode_full_calldata was already deprecated. V3 only supports encode_solutions, which returns EncodedSolution objects.

You are responsible for constructing the full method call, including execution-critical parameters like min_amount_out, receiver, and fee configuration.

SwapEncoderRegistry

SwapEncoderRegistry::new now requires a Chain parameter:

Execution Changes

Router Function Signatures

The TychoRouter V3 methods now include a ClientFeeParams struct in their signatures:

When constructing calldata yourself (recommended), encode this struct as part of the function arguments. Even if you are not charging fees, you must pass this parameter with zero values.

Vault Integration

The TychoRouter now includes an ERC6909 vault. Key changes:

  • UseVaultsFunds replaces the old None transfer type. Tokens deposited in the vault are tracked per-user and can be used for swaps or withdrawn.

  • Deposit tokens via router.deposit(token, amount) before swapping with vault funds.

  • Fees (both client and router fees) are credited to the receiver's vault balance rather than transferred immediately.

For more see Vault.

No More Wrap/Unwrap Flags

The router no longer accepts wrap or unwrap boolean flags. If your calldata construction includes these parameters, remove them. The WETH executor handles wrapping and unwrapping as part of the swap path. See Native Token Handling (Wrapping & Unwrapping).

Method Variants

Each swap strategy (single, sequential, split) now has three variants instead of two, with a new UsingVault variant:

V2
V3

singleSwap(...)

singleSwap(...)

singleSwapPermit2(...)

singleSwapPermit2(...)

singleSwapUsingVault(...)

The same pattern applies for sequentialSwap and splitSwap. The EncodedSolution.function_signature tells you which variant to call.

Last updated

Was this helpful?