Merge branch 'refs/heads/main' into feat/bebop-rfq-encoder-and-executor

# Conflicts:
#	config/executor_addresses.json
#	foundry/scripts/deploy-executors.js
#	foundry/test/TychoRouterSequentialSwap.t.sol
#	foundry/test/assets/calldata.txt
#	src/encoding/models.rs
#	tests/common/mod.rs

Took 21 minutes
This commit is contained in:
Diana Carvalho
2025-08-08 14:40:03 +01:00
54 changed files with 5428 additions and 659 deletions

View File

@@ -7,10 +7,9 @@ use alloy::{
primitives::{B256, U256},
signers::local::PrivateKeySigner,
};
use tycho_common::{models::Chain as TychoCommonChain, Bytes};
use tycho_common::{models::Chain, Bytes};
use tycho_execution::encoding::{
evm::encoder_builders::TychoRouterEncoderBuilder,
models::{BebopOrderType, Chain, UserTransferType},
evm::encoder_builders::TychoRouterEncoderBuilder, models::UserTransferType,
tycho_encoder::TychoEncoder,
};
@@ -19,7 +18,7 @@ pub fn router_address() -> Bytes {
}
pub fn eth_chain() -> Chain {
TychoCommonChain::Ethereum.into()
Chain::Ethereum
}
pub fn eth() -> Bytes {
@@ -46,6 +45,10 @@ pub fn pepe() -> Bytes {
Bytes::from_str("0x6982508145454Ce325dDbE47a25d4ec3d2311933").unwrap()
}
pub fn usdt() -> Bytes {
Bytes::from_str("0xdAC17F958D2ee523a2206206994597C13D831ec7").unwrap()
}
pub fn ondo() -> Bytes {
Bytes::from_str("0xfAbA6f8e4a5E8Ab82F62fe7C39859FA577269BE3").unwrap()
}

View File

@@ -53,6 +53,7 @@ fn test_uniswap_v3_uniswap_v2() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
component: ProtocolComponent {
@@ -64,6 +65,7 @@ fn test_uniswap_v3_uniswap_v2() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -85,7 +87,7 @@ fn test_uniswap_v3_uniswap_v2() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -132,6 +134,7 @@ fn test_uniswap_v3_uniswap_v3() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
component: ProtocolComponent {
@@ -151,6 +154,7 @@ fn test_uniswap_v3_uniswap_v3() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -172,7 +176,7 @@ fn test_uniswap_v3_uniswap_v3() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -218,6 +222,7 @@ fn test_uniswap_v3_curve() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdt = Swap {
@@ -247,6 +252,7 @@ fn test_uniswap_v3_curve() {
token_out: usdt.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -268,7 +274,7 @@ fn test_uniswap_v3_curve() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -306,6 +312,7 @@ fn test_balancer_v2_uniswap_v2() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
@@ -318,6 +325,7 @@ fn test_balancer_v2_uniswap_v2() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -339,7 +347,7 @@ fn test_balancer_v2_uniswap_v2() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -380,6 +388,7 @@ fn test_multi_protocol() {
token_out: weth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let balancer_swap_weth_wbtc = Swap {
@@ -392,6 +401,7 @@ fn test_multi_protocol() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let curve_swap_wbtc_usdt = Swap {
@@ -421,6 +431,7 @@ fn test_multi_protocol() {
token_out: usdt.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
// Ekubo
@@ -443,6 +454,7 @@ fn test_multi_protocol() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
// USV4
@@ -466,6 +478,7 @@ fn test_multi_protocol() {
token_out: eth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -495,7 +508,7 @@ fn test_multi_protocol() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -538,6 +551,7 @@ fn test_uniswap_v3_balancer_v3() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_qnt = Swap {
component: ProtocolComponent {
@@ -549,6 +563,7 @@ fn test_uniswap_v3_balancer_v3() {
token_out: qnt.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -570,7 +585,7 @@ fn test_uniswap_v3_balancer_v3() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,

View File

@@ -46,6 +46,7 @@ fn test_single_encoding_strategy_ekubo() {
token_out: token_out.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -69,7 +70,7 @@ fn test_single_encoding_strategy_ekubo() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -98,6 +99,7 @@ fn test_single_encoding_strategy_maverick() {
token_out: token_out.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -121,7 +123,7 @@ fn test_single_encoding_strategy_maverick() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -162,6 +164,7 @@ fn test_single_encoding_strategy_usv4_eth_in() {
token_out: pepe.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -183,7 +186,7 @@ fn test_single_encoding_strategy_usv4_eth_in() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -228,6 +231,7 @@ fn test_single_encoding_strategy_usv4_eth_out() {
token_out: eth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -250,7 +254,7 @@ fn test_single_encoding_strategy_usv4_eth_out() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -302,6 +306,7 @@ fn test_single_encoding_strategy_usv4_grouped_swap() {
token_out: eth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_eth_pepe = Swap {
@@ -315,6 +320,7 @@ fn test_single_encoding_strategy_usv4_grouped_swap() {
token_out: pepe.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -336,7 +342,7 @@ fn test_single_encoding_strategy_usv4_grouped_swap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -423,6 +429,7 @@ fn test_single_encoding_strategy_curve() {
token_out: token_out.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -446,7 +453,7 @@ fn test_single_encoding_strategy_curve() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -490,6 +497,7 @@ fn test_single_encoding_strategy_curve_st_eth() {
token_out: token_out.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -513,7 +521,7 @@ fn test_single_encoding_strategy_curve_st_eth() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -543,6 +551,7 @@ fn test_single_encoding_strategy_balancer_v3() {
token_out: token_out.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -566,7 +575,7 @@ fn test_single_encoding_strategy_balancer_v3() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,

View File

@@ -6,7 +6,7 @@ use num_bigint::{BigInt, BigUint};
use tycho_common::{models::protocol::ProtocolComponent, Bytes};
use tycho_execution::encoding::{
evm::utils::write_calldata_to_file,
models::{Solution, Swap, UserTransferType},
models::{NativeAction, Solution, Swap, UserTransferType},
};
use crate::common::{
@@ -19,7 +19,7 @@ fn test_sequential_swap_strategy_encoder() {
// Note: This test does not assert anything. It is only used to obtain integration
// test data for our router solidity test.
//
// Performs a sequential swap from WETH to USDC though WBTC using USV2 pools
// Performs a sequential swap from WETH to USDC through WBTC using USV2 pools
//
// WETH ───(USV2)──> WBTC ───(USV2)──> USDC
@@ -37,6 +37,7 @@ fn test_sequential_swap_strategy_encoder() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
component: ProtocolComponent {
@@ -48,6 +49,7 @@ fn test_sequential_swap_strategy_encoder() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -69,7 +71,7 @@ fn test_sequential_swap_strategy_encoder() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -103,6 +105,7 @@ fn test_sequential_swap_strategy_encoder_no_permit2() {
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
component: ProtocolComponent {
@@ -114,6 +117,7 @@ fn test_sequential_swap_strategy_encoder_no_permit2() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -135,7 +139,7 @@ fn test_sequential_swap_strategy_encoder_no_permit2() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -215,6 +219,7 @@ fn test_sequential_strategy_cyclic_swap() {
token_out: weth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
// WETH -> USDC (Pool 2)
@@ -237,6 +242,7 @@ fn test_sequential_strategy_cyclic_swap() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -260,7 +266,7 @@ fn test_sequential_strategy_cyclic_swap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -310,3 +316,75 @@ fn test_sequential_strategy_cyclic_swap() {
assert_eq!(hex_calldata[1224..], expected_swaps);
write_calldata_to_file("test_sequential_strategy_cyclic_swap", hex_calldata.as_str());
}
#[test]
fn test_sequential_swap_strategy_encoder_unwrap() {
// Note: This test does not assert anything. It is only used to obtain integration
// test data for our router solidity test.
//
// Performs a sequential swap from USDC to ETH through WBTC using USV2 pools and unwrapping in
// the end
//
// USDC ───(USV2)──> WBTC ───(USV2)──> WETH -> ETH
let weth = weth();
let wbtc = wbtc();
let usdc = usdc();
let swap_usdc_wbtc = Swap {
component: ProtocolComponent {
id: "0x004375Dff511095CC5A197A54140a24eFEF3A416".to_string(),
protocol_system: "uniswap_v2".to_string(),
..Default::default()
},
token_in: usdc.clone(),
token_out: wbtc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_weth = Swap {
component: ProtocolComponent {
id: "0xBb2b8038a1640196FbE3e38816F3e67Cba72D940".to_string(),
protocol_system: "uniswap_v2".to_string(),
..Default::default()
},
token_in: wbtc.clone(),
token_out: weth.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
let solution = Solution {
exact_out: false,
given_token: usdc,
given_amount: BigUint::from_str("3_000_000_000").unwrap(),
checked_token: eth(),
checked_amount: BigUint::from_str("26173932").unwrap(),
sender: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
receiver: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
swaps: vec![swap_usdc_wbtc, swap_wbtc_weth],
native_action: Some(NativeAction::Unwrap),
};
let encoded_solution = encoder
.encode_solutions(vec![solution.clone()])
.unwrap()[0]
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
&eth(),
Some(get_signer()),
)
.unwrap()
.data;
let hex_calldata = encode(&calldata);
write_calldata_to_file("test_sequential_swap_strategy_encoder_unwrap", hex_calldata.as_str());
}

View File

@@ -33,6 +33,7 @@ fn test_single_swap_strategy_encoder() {
token_out: dai.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -54,7 +55,7 @@ fn test_single_swap_strategy_encoder() {
.unwrap();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solutions[0].clone(),
&solution,
&UserTransferType::TransferFromPermit2,
@@ -119,6 +120,7 @@ fn test_single_swap_strategy_encoder_no_permit2() {
token_out: dai.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -139,7 +141,7 @@ fn test_single_swap_strategy_encoder_no_permit2() {
.unwrap()[0]
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
@@ -201,6 +203,7 @@ fn test_single_swap_strategy_encoder_no_transfer_in() {
token_out: dai.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::None);
@@ -221,7 +224,7 @@ fn test_single_swap_strategy_encoder_no_transfer_in() {
.unwrap()[0]
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::None,
@@ -284,6 +287,7 @@ fn test_single_swap_strategy_encoder_wrap() {
token_out: dai.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -305,7 +309,7 @@ fn test_single_swap_strategy_encoder_wrap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -336,6 +340,7 @@ fn test_single_swap_strategy_encoder_unwrap() {
token_out: weth(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -357,7 +362,7 @@ fn test_single_swap_strategy_encoder_unwrap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,

View File

@@ -42,6 +42,7 @@ fn test_split_swap_strategy_encoder() {
token_out: dai.clone(),
split: 0.5f64,
user_data: None,
protocol_state: None,
};
let swap_weth_wbtc = Swap {
component: ProtocolComponent {
@@ -56,6 +57,7 @@ fn test_split_swap_strategy_encoder() {
// It should still be very close to 50%
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_dai_usdc = Swap {
component: ProtocolComponent {
@@ -67,6 +69,7 @@ fn test_split_swap_strategy_encoder() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_wbtc_usdc = Swap {
component: ProtocolComponent {
@@ -78,6 +81,7 @@ fn test_split_swap_strategy_encoder() {
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -99,7 +103,7 @@ fn test_split_swap_strategy_encoder() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -144,6 +148,7 @@ fn test_split_input_cyclic_swap() {
token_out: weth.clone(),
split: 0.6f64, // 60% of input
user_data: None,
protocol_state: None,
};
// USDC -> WETH (Pool 2) - 40% of input (remaining)
@@ -166,6 +171,7 @@ fn test_split_input_cyclic_swap() {
token_out: weth.clone(),
split: 0f64,
user_data: None, // Remaining 40%
protocol_state: None,
};
// WETH -> USDC (Pool 2)
@@ -188,6 +194,7 @@ fn test_split_input_cyclic_swap() {
token_out: usdc.clone(),
split: 0.0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -212,7 +219,7 @@ fn test_split_input_cyclic_swap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,
@@ -308,6 +315,7 @@ fn test_split_output_cyclic_swap() {
token_out: weth.clone(),
split: 0.0f64,
user_data: None,
protocol_state: None,
};
let swap_weth_usdc_v3_pool1 = Swap {
@@ -327,6 +335,7 @@ fn test_split_output_cyclic_swap() {
token_out: usdc.clone(),
split: 0.6f64,
user_data: None,
protocol_state: None,
};
let swap_weth_usdc_v3_pool2 = Swap {
@@ -348,6 +357,7 @@ fn test_split_output_cyclic_swap() {
token_out: usdc.clone(),
split: 0.0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFromPermit2);
@@ -372,7 +382,7 @@ fn test_split_output_cyclic_swap() {
.clone();
let calldata = encode_tycho_router_call(
eth_chain().id,
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFromPermit2,

View File

@@ -0,0 +1,125 @@
use std::{collections::HashMap, str::FromStr};
use alloy::{hex::encode, primitives::Address, sol_types::SolValue};
use num_bigint::{BigInt, BigUint};
use tycho_common::{models::protocol::ProtocolComponent, Bytes};
use tycho_execution::encoding::{
evm::{
approvals::protocol_approvals_manager::ProtocolApprovalsManager,
utils::{bytes_to_address, write_calldata_to_file},
},
models::{Solution, Swap, UserTransferType},
};
use crate::common::{
dai, encoding::encode_tycho_router_call, eth, eth_chain, get_tycho_router_encoder,
router_address, usdc, usdt,
};
mod common;
#[test]
fn test_sequential_swap_usx() {
// Replicates real uniswap X order settled in tx:
// 0x005d7b150017ba1b59d2f99395ccae7bda9b739938ade4e509817e32760aaf9d
// Performs a sequential
// swap from DAI to USDT though USDC using USV3 pools
//
// DAI ───(USV3)──> USDC ───(USV2)──> USDT
// Creates all the calldata needed for the uniswap X callbackData
let filler = Bytes::from_str("0x6D9da78B6A5BEdcA287AA5d49613bA36b90c15C4").unwrap();
let usx_reactor = Address::from_str("0x00000011F84B9aa48e5f8aA8B9897600006289Be").unwrap();
let dai = dai();
let usdc = usdc();
let usdt = usdt();
let swap_dai_usdc = Swap {
component: ProtocolComponent {
id: "0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168".to_string(),
protocol_system: "uniswap_v3".to_string(),
static_attributes: {
let mut attrs = HashMap::new();
attrs
.insert("fee".to_string(), Bytes::from(BigInt::from(100).to_signed_bytes_be()));
attrs
},
..Default::default()
},
token_in: dai.clone(),
token_out: usdc.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let swap_usdc_usdt = Swap {
component: ProtocolComponent {
id: "0x3416cF6C708Da44DB2624D63ea0AAef7113527C6".to_string(),
protocol_system: "uniswap_v3".to_string(),
static_attributes: {
let mut attrs = HashMap::new();
attrs
.insert("fee".to_string(), Bytes::from(BigInt::from(100).to_signed_bytes_be()));
attrs
},
..Default::default()
},
token_in: usdc.clone(),
token_out: usdt.clone(),
split: 0f64,
user_data: None,
protocol_state: None,
};
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
let solution = Solution {
exact_out: false,
given_token: dai.clone(),
given_amount: BigUint::from_str("2_000_000000000000000000").unwrap(),
checked_token: usdt.clone(),
checked_amount: BigUint::from_str("1_990_000000").unwrap(),
sender: filler.clone(),
receiver: filler.clone(),
swaps: vec![swap_dai_usdc, swap_usdc_usdt],
..Default::default()
};
let encoded_solution = encoder
.encode_solutions(vec![solution.clone()])
.unwrap()[0]
.clone();
let tycho_calldata = encode_tycho_router_call(
eth_chain().id(),
encoded_solution,
&solution,
&UserTransferType::TransferFrom,
&eth(),
None,
)
.unwrap()
.data;
// Uniswap X specific part
let filler_address = bytes_to_address(&filler).unwrap();
let token_approvals_manager = ProtocolApprovalsManager::new().unwrap();
let token_in_approval_needed = token_approvals_manager
.approval_needed(
bytes_to_address(&dai).unwrap(),
filler_address,
bytes_to_address(&router_address()).unwrap(),
)
.unwrap();
let token_out_approval_needed = token_approvals_manager
.approval_needed(bytes_to_address(&usdc).unwrap(), filler_address, usx_reactor)
.unwrap();
let full_calldata =
(token_in_approval_needed, token_out_approval_needed, tycho_calldata).abi_encode_packed();
let hex_calldata = encode(&full_calldata);
write_calldata_to_file("test_sequential_swap_usx", hex_calldata.as_str());
}