chore: Improve tests:

In both encoding and contracts:
- Make sure that the tests names/encoder match what is happening (we had test_split_... that was only a single swap).
- Made modules inside the encodings tests
  - In swap_encoders: there is one module per protocol
  - In strategy_encoders: there is one module per strategy and an extra protocol_integration module. Inside the sequential module there is another module called chained_swaps
- In contracts, each strategy has its own file. Integration tests per strategy should also be here. Renamed TychoRouterIntegration to TychoRouterProtocolIntegration. Only protocol integration tests should be in this file

--- don't change below this line ---
ENG-4327 Took 1 hour 13 minutes
This commit is contained in:
Diana Carvalho
2025-04-21 13:05:04 +01:00
parent b4236dd879
commit a951dfb21a
7 changed files with 2110 additions and 2363 deletions

View File

@@ -577,419 +577,435 @@ mod tests {
use super::*;
use crate::encoding::models::TransferType;
#[test]
fn test_encode_uniswap_v2() {
let usv2_pool = ProtocolComponent {
id: String::from("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
..Default::default()
};
mod uniswap_v2 {
use super::*;
#[test]
fn test_encode_uniswap_v2() {
let usv2_pool = ProtocolComponent {
id: String::from("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
..Default::default()
};
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0x6b175474e89094c44da98b954eedeac495271d0f");
let swap = Swap {
component: usv2_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV2SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0x6b175474e89094c44da98b954eedeac495271d0f");
let swap = Swap {
component: usv2_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV2SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// in token
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// component id
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
// receiver
"0000000000000000000000000000000000000001",
// zero for one
"00",
// transfer type (transfer)
"00",
))
);
}
#[test]
fn test_encode_uniswap_v3() {
let fee = BigInt::from(500);
let encoded_pool_fee = Bytes::from(fee.to_signed_bytes_be());
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("fee".into(), Bytes::from(encoded_pool_fee.to_vec()));
let usv3_pool = ProtocolComponent {
id: String::from("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
static_attributes,
..Default::default()
};
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0x6b175474e89094c44da98b954eedeac495271d0f");
let swap = Swap {
component: usv3_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV3SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// in token
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// out token
"6b175474e89094c44da98b954eedeac495271d0f",
// fee
"0001f4",
// receiver
"0000000000000000000000000000000000000001",
// pool id
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
// zero for one
"00",
// transfer type (transfer)
"00",
))
);
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// in token
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// component id
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
// receiver
"0000000000000000000000000000000000000001",
// zero for one
"00",
// transfer type (transfer)
"00",
))
);
}
}
#[test]
fn test_encode_balancer_v2() {
let balancer_pool = ProtocolComponent {
id: String::from("0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014"),
protocol_system: String::from("vm:balancer_v2"),
..Default::default()
};
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0xba100000625a3754423978a60c9317c58a424e3D");
let swap = Swap {
component: balancer_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver was generated with `makeAddr("bob") using forge`
receiver: Bytes::from("0x1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::None,
};
let encoder = BalancerV2SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
Some(HashMap::from([(
"vault_address".to_string(),
"0xba12222222228d8ba445958a75a0704d566bf2c8".to_string(),
)])),
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
mod uniswap_v3 {
use super::*;
#[test]
fn test_encode_uniswap_v3() {
let fee = BigInt::from(500);
let encoded_pool_fee = Bytes::from(fee.to_signed_bytes_be());
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("fee".into(), Bytes::from(encoded_pool_fee.to_vec()));
assert_eq!(
hex_swap,
String::from(concat!(
// token in
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// token out
"ba100000625a3754423978a60c9317c58a424e3d",
// pool id
"5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// approval needed
"01",
// transfer type
"05"
))
);
let usv3_pool = ProtocolComponent {
id: String::from("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
static_attributes,
..Default::default()
};
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0x6b175474e89094c44da98b954eedeac495271d0f");
let swap = Swap {
component: usv3_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV3SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// in token
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// out token
"6b175474e89094c44da98b954eedeac495271d0f",
// fee
"0001f4",
// receiver
"0000000000000000000000000000000000000001",
// pool id
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
// zero for one
"00",
// transfer type (transfer)
"00",
))
);
}
}
#[test]
fn test_encode_uniswap_v4_simple_swap() {
let fee = BigInt::from(100);
let tick_spacing = BigInt::from(1);
let token_in = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"); // USDE
let token_out = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7"); // USDT
mod balancer_v2 {
use super::*;
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("key_lp_fee".into(), Bytes::from(fee.to_signed_bytes_be()));
static_attributes
.insert("tick_spacing".into(), Bytes::from(tick_spacing.to_signed_bytes_be()));
let usv4_pool = ProtocolComponent {
// Pool manager
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes,
..Default::default()
};
let swap = Swap {
component: usv4_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
// Same as the executor address
router_address: Some(Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f")),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0xF62849F9A0B5Bf2913b396098F7c7019b51A820a"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
#[test]
fn test_encode_balancer_v2() {
let balancer_pool = ProtocolComponent {
id: String::from(
"0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014",
),
protocol_system: String::from("vm:balancer_v2"),
..Default::default()
};
let token_in = Bytes::from("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let token_out = Bytes::from("0xba100000625a3754423978a60c9317c58a424e3D");
let swap = Swap {
component: balancer_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver was generated with `makeAddr("bob") using forge`
receiver: Bytes::from("0x1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::None,
};
let encoder = BalancerV2SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
Some(HashMap::from([(
"vault_address".to_string(),
"0xba12222222228d8ba445958a75a0704d566bf2c8".to_string(),
)])),
)
.unwrap();
let hex_swap = encode(&encoded_swap);
println!("test_encode_uniswap_v4_simple_swap: {}", hex_swap);
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// group token in
"4c9edd5852cd905f086c759e8383e09bff1e68b3",
// group token out
"dac17f958d2ee523a2206206994597c13d831ec7",
// zero for one
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token
"dac17f958d2ee523a2206206994597c13d831ec7",
// - fee
"000064",
// - tick spacing
"000001"
))
);
assert_eq!(
hex_swap,
String::from(concat!(
// token in
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// token out
"ba100000625a3754423978a60c9317c58a424e3d",
// pool id
"5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// approval needed
"01",
// transfer type
"05"
))
);
}
}
#[test]
fn test_encode_uniswap_v4_second_swap() {
let fee = BigInt::from(3000);
let tick_spacing = BigInt::from(60);
let group_token_in = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"); // USDE
let token_in = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7"); // USDT
let token_out = Bytes::from("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"); // WBTC
mod uniswap_v4 {
use super::*;
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("key_lp_fee".into(), Bytes::from(fee.to_signed_bytes_be()));
static_attributes
.insert("tick_spacing".into(), Bytes::from(tick_spacing.to_signed_bytes_be()));
#[test]
fn test_encode_uniswap_v4_simple_swap() {
let fee = BigInt::from(100);
let tick_spacing = BigInt::from(1);
let token_in = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"); // USDE
let token_out = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7"); // USDT
let usv4_pool = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes,
..Default::default()
};
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("key_lp_fee".into(), Bytes::from(fee.to_signed_bytes_be()));
static_attributes
.insert("tick_spacing".into(), Bytes::from(tick_spacing.to_signed_bytes_be()));
let swap = Swap {
component: usv4_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let usv4_pool = ProtocolComponent {
// Pool manager
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes,
..Default::default()
};
let swap = Swap {
component: usv4_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
// Same as the executor address
router_address: Some(Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f")),
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: group_token_in.clone(),
// Token out is the same as the group token out
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0xF62849F9A0B5Bf2913b396098F7c7019b51A820a"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let hex_swap = encode(&encoded_swap);
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
println!("test_encode_uniswap_v4_simple_swap: {}", hex_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// pool params:
// - intermediary token (20 bytes)
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// - fee (3 bytes)
"000bb8",
// - tick spacing (3 bytes)
"00003c"
))
);
assert_eq!(
hex_swap,
String::from(concat!(
// group token in
"4c9edd5852cd905f086c759e8383e09bff1e68b3",
// group token out
"dac17f958d2ee523a2206206994597c13d831ec7",
// zero for one
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token
"dac17f958d2ee523a2206206994597c13d831ec7",
// - fee
"000064",
// - tick spacing
"000001"
))
);
}
#[test]
fn test_encode_uniswap_v4_second_swap() {
let fee = BigInt::from(3000);
let tick_spacing = BigInt::from(60);
let group_token_in = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3"); // USDE
let token_in = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7"); // USDT
let token_out = Bytes::from("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"); // WBTC
let mut static_attributes: HashMap<String, Bytes> = HashMap::new();
static_attributes.insert("key_lp_fee".into(), Bytes::from(fee.to_signed_bytes_be()));
static_attributes
.insert("tick_spacing".into(), Bytes::from(tick_spacing.to_signed_bytes_be()));
let usv4_pool = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes,
..Default::default()
};
let swap = Swap {
component: usv4_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: group_token_in.clone(),
// Token out is the same as the group token out
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// pool params:
// - intermediary token (20 bytes)
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// - fee (3 bytes)
"000bb8",
// - tick spacing (3 bytes)
"00003c"
))
);
}
#[test]
fn test_encode_uniswap_v4_sequential_swap() {
let usde_address = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3");
let usdt_address = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7");
let wbtc_address = Bytes::from("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599");
let router_address = Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f");
// The context is the same for both swaps, since the group token in and out are the same
let context = EncodingContext {
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
router_address: Some(router_address.clone()),
group_token_in: usde_address.clone(),
group_token_out: wbtc_address.clone(),
transfer_type: TransferType::TransferToProtocol,
};
// Setup - First sequence: USDE -> USDT
let usde_usdt_fee = BigInt::from(100);
let usde_usdt_tick_spacing = BigInt::from(1);
let mut usde_usdt_static_attributes: HashMap<String, Bytes> = HashMap::new();
usde_usdt_static_attributes
.insert("key_lp_fee".into(), Bytes::from(usde_usdt_fee.to_signed_bytes_be()));
usde_usdt_static_attributes.insert(
"tick_spacing".into(),
Bytes::from(usde_usdt_tick_spacing.to_signed_bytes_be()),
);
let usde_usdt_component = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes: usde_usdt_static_attributes,
..Default::default()
};
// Setup - Second sequence: USDT -> WBTC
let usdt_wbtc_fee = BigInt::from(3000);
let usdt_wbtc_tick_spacing = BigInt::from(60);
let mut usdt_wbtc_static_attributes: HashMap<String, Bytes> = HashMap::new();
usdt_wbtc_static_attributes
.insert("key_lp_fee".into(), Bytes::from(usdt_wbtc_fee.to_signed_bytes_be()));
usdt_wbtc_static_attributes.insert(
"tick_spacing".into(),
Bytes::from(usdt_wbtc_tick_spacing.to_signed_bytes_be()),
);
let usdt_wbtc_component = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes: usdt_wbtc_static_attributes,
..Default::default()
};
let initial_swap = Swap {
component: usde_usdt_component,
token_in: usde_address.clone(),
token_out: usdt_address.clone(),
split: 0f64,
};
let second_swap = Swap {
component: usdt_wbtc_component,
token_in: usdt_address,
token_out: wbtc_address.clone(),
split: 0f64,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0xF62849F9A0B5Bf2913b396098F7c7019b51A820a"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let initial_encoded_swap = encoder
.encode_swap(initial_swap, context.clone())
.unwrap();
let second_encoded_swap = encoder
.encode_swap(second_swap, context)
.unwrap();
let combined_hex =
format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap));
println!("test_encode_uniswap_v4_sequential_swap: {}", combined_hex);
assert_eq!(
combined_hex,
String::from(concat!(
// group_token in
"4c9edd5852cd905f086c759e8383e09bff1e68b3",
// group_token out
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// zero for one
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token USDT
"dac17f958d2ee523a2206206994597c13d831ec7",
// - fee
"000064",
// - tick spacing
"000001",
// - intermediary token WBTC
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// - fee
"000bb8",
// - tick spacing
"00003c"
))
);
println!("{}", combined_hex)
}
}
#[test]
fn test_encode_uniswap_v4_sequential_swap() {
let usde_address = Bytes::from("0x4c9EDD5852cd905f086C759E8383e09bff1E68B3");
let usdt_address = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7");
let wbtc_address = Bytes::from("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599");
let router_address = Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f");
// The context is the same for both swaps, since the group token in and out are the same
let context = EncodingContext {
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
router_address: Some(router_address.clone()),
group_token_in: usde_address.clone(),
group_token_out: wbtc_address.clone(),
transfer_type: TransferType::TransferToProtocol,
};
// Setup - First sequence: USDE -> USDT
let usde_usdt_fee = BigInt::from(100);
let usde_usdt_tick_spacing = BigInt::from(1);
let mut usde_usdt_static_attributes: HashMap<String, Bytes> = HashMap::new();
usde_usdt_static_attributes
.insert("key_lp_fee".into(), Bytes::from(usde_usdt_fee.to_signed_bytes_be()));
usde_usdt_static_attributes.insert(
"tick_spacing".into(),
Bytes::from(usde_usdt_tick_spacing.to_signed_bytes_be()),
);
let usde_usdt_component = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes: usde_usdt_static_attributes,
..Default::default()
};
// Setup - Second sequence: USDT -> WBTC
let usdt_wbtc_fee = BigInt::from(3000);
let usdt_wbtc_tick_spacing = BigInt::from(60);
let mut usdt_wbtc_static_attributes: HashMap<String, Bytes> = HashMap::new();
usdt_wbtc_static_attributes
.insert("key_lp_fee".into(), Bytes::from(usdt_wbtc_fee.to_signed_bytes_be()));
usdt_wbtc_static_attributes.insert(
"tick_spacing".into(),
Bytes::from(usdt_wbtc_tick_spacing.to_signed_bytes_be()),
);
let usdt_wbtc_component = ProtocolComponent {
id: String::from("0x000000000004444c5dc75cB358380D2e3dE08A90"),
static_attributes: usdt_wbtc_static_attributes,
..Default::default()
};
let initial_swap = Swap {
component: usde_usdt_component,
token_in: usde_address.clone(),
token_out: usdt_address.clone(),
split: 0f64,
};
let second_swap = Swap {
component: usdt_wbtc_component,
token_in: usdt_address,
token_out: wbtc_address.clone(),
split: 0f64,
};
let encoder = UniswapV4SwapEncoder::new(
String::from("0xF62849F9A0B5Bf2913b396098F7c7019b51A820a"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let initial_encoded_swap = encoder
.encode_swap(initial_swap, context.clone())
.unwrap();
let second_encoded_swap = encoder
.encode_swap(second_swap, context)
.unwrap();
let combined_hex =
format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap));
println!("test_encode_uniswap_v4_sequential_swap: {}", combined_hex);
assert_eq!(
combined_hex,
String::from(concat!(
// group_token in
"4c9edd5852cd905f086c759e8383e09bff1e68b3",
// group_token out
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// zero for one
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token USDT
"dac17f958d2ee523a2206206994597c13d831ec7",
// - fee
"000064",
// - tick spacing
"000001",
// - intermediary token WBTC
"2260fac5e5542a773aa44fbcfedf7c193bc2c599",
// - fee
"000bb8",
// - tick spacing
"00003c"
))
);
println!("{}", combined_hex)
}
mod ekubo {
use super::*;