Merge branch 'refs/heads/main' into router/tnl/fix-deployment
This commit is contained in:
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,3 +1,30 @@
|
|||||||
|
## [0.95.1](https://github.com/propeller-heads/tycho-execution/compare/0.95.0...0.95.1) (2025-05-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Move encode_input back into encoding_utils.rs ([92d36b9](https://github.com/propeller-heads/tycho-execution/commit/92d36b9f48d30aad2d1227c21f490ac9f47daa7b))
|
||||||
|
|
||||||
|
## [0.95.0](https://github.com/propeller-heads/tycho-execution/compare/0.94.0...0.95.0) (2025-05-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Don't sign permit2 objects ([c62af2f](https://github.com/propeller-heads/tycho-execution/commit/c62af2f232063d3a3c5baa759d484b0d2cc2c185))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Bring back swapper_pk for backwards compatibility ([d12e3d3](https://github.com/propeller-heads/tycho-execution/commit/d12e3d3b5fc302b1c266424189f984884b2d9ed7))
|
||||||
|
* Make functions in encoding_utils.rs private ([5ddd2a9](https://github.com/propeller-heads/tycho-execution/commit/5ddd2a9cd7d41d8899ff3667ca2587dc89fdce6a))
|
||||||
|
|
||||||
|
## [0.94.0](https://github.com/propeller-heads/tycho-execution/compare/0.93.0...0.94.0) (2025-05-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Create non alloy specific Permit and PermitDetails structs ([75f2c3a](https://github.com/propeller-heads/tycho-execution/commit/75f2c3a1c52b6ee8823d449b70147cb023202e93))
|
||||||
|
|
||||||
## [0.93.0](https://github.com/propeller-heads/tycho-execution/compare/0.92.1...0.93.0) (2025-05-22)
|
## [0.93.0](https://github.com/propeller-heads/tycho-execution/compare/0.92.1...0.93.0) (2025-05-22)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4469,7 +4469,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.93.0"
|
version = "0.95.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy",
|
"alloy",
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.93.0"
|
version = "0.95.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Provides tools for encoding and executing swaps against Tycho router and protocol executors."
|
description = "Provides tools for encoding and executing swaps against Tycho router and protocol executors."
|
||||||
repository = "https://github.com/propeller-heads/tycho-execution"
|
repository = "https://github.com/propeller-heads/tycho-execution"
|
||||||
|
|||||||
@@ -7,20 +7,17 @@ use tycho_common::{
|
|||||||
};
|
};
|
||||||
use tycho_execution::encoding::{
|
use tycho_execution::encoding::{
|
||||||
evm::encoder_builders::TychoRouterEncoderBuilder,
|
evm::encoder_builders::TychoRouterEncoderBuilder,
|
||||||
models::{Solution, Swap},
|
models::{Solution, Swap, UserTransferType},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Setup variables
|
|
||||||
let swapper_pk =
|
|
||||||
"0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234".to_string();
|
|
||||||
let user_address = Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2")
|
let user_address = Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2")
|
||||||
.expect("Failed to create user address");
|
.expect("Failed to create user address");
|
||||||
|
|
||||||
// Initialize the encoder
|
// Initialize the encoder
|
||||||
let encoder = TychoRouterEncoderBuilder::new()
|
let encoder = TychoRouterEncoderBuilder::new()
|
||||||
.chain(Chain::Ethereum)
|
.chain(Chain::Ethereum)
|
||||||
.swapper_pk(swapper_pk)
|
.user_transfer_type(UserTransferType::TransferFrom)
|
||||||
.build()
|
.build()
|
||||||
.expect("Failed to build encoder");
|
.expect("Failed to build encoder");
|
||||||
|
|
||||||
@@ -67,10 +64,10 @@ fn main() {
|
|||||||
.clone();
|
.clone();
|
||||||
println!(" ====== Simple swap WETH -> USDC ======");
|
println!(" ====== Simple swap WETH -> USDC ======");
|
||||||
println!(
|
println!(
|
||||||
"The simple swap encoded solution should be sent to address {:?} and selector {:?} and the \
|
"The simple swap encoded solution should be sent to address {:?} with function signature {:?} and the \
|
||||||
following encoded data: {:?}",
|
following encoded swaps: {:?}",
|
||||||
encoded_solution.interacting_with,
|
encoded_solution.interacting_with,
|
||||||
encoded_solution.selector,
|
encoded_solution.function_signature,
|
||||||
hex::encode(encoded_solution.swaps)
|
hex::encode(encoded_solution.swaps)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -141,10 +138,10 @@ fn main() {
|
|||||||
|
|
||||||
println!(" ====== Complex split swap WETH -> USDC ======");
|
println!(" ====== Complex split swap WETH -> USDC ======");
|
||||||
println!(
|
println!(
|
||||||
"The complex swaps encoded solution should be sent to address {:?} and selector {:?} and the \
|
"The complex swaps encoded solution should be sent to address {:?} with function signature {:?} and the \
|
||||||
following encoded data: {:?}",
|
following encoded swaps: {:?}",
|
||||||
complex_encoded_solution.interacting_with,
|
complex_encoded_solution.interacting_with,
|
||||||
complex_encoded_solution.selector,
|
complex_encoded_solution.function_signature,
|
||||||
hex::encode(complex_encoded_solution.swaps)
|
hex::encode(complex_encoded_solution.swaps)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,23 +3,23 @@ test_single_encoding_strategy_ekubo:5c4b639c000000000000000000000000000000000000
|
|||||||
test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000
|
test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000
|
||||||
test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||||
test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||||
test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041972d1d0dd19889db47087a4653c517a455a19a1dc76a0a14a29fd12ae7d2d4f218ba986eada63bfdfacf78e3a7ffdce07c4064fcf11033f185819509f64b6b191b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000
|
test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000416a1ae07bda4ca6c8503f2233052eea5a5dfb8c7755dfb108797fef2bacdddaa266ffba24db3614fb8a933c0bcceda3aecffa6db0781ecb436e6bbda5eea459621b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000
|
||||||
test_single_encoding_strategy_usv4_eth_out:7c55384600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041c0bbb5f493c1d4b87c92085902e4488efba2b87740abdcc298a5adb435bfe3b23820a0677d325e34fa06e8c2a91f0d3851b00cf170885176b5f47d40983d64941b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300710001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c00000000000000000000000000
|
test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000416f3729ae9d9802c1e9c996adac1ecd83bba3bbd9526e9d6b78b700624a5143e23a23bdfb10ba1dda78f51a819a9cd9fa247484c288c5102a384a0c86ad389d431b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000
|
||||||
test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000419861aedfb04e8f7b9fe147a7d19c41f9b1cf37a06850b09f645fb351c003967d43d365af50b08ef741348898578b7fa1454a8e9cd0390eaf6c2939d7b817d0d31c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d86a1edea6862ef9c8df971417410c87f6cf21d40542760db70fdd800b82f7c9722702f735433a898b8cc208b131cd865589d11f5028da2b9866667e0d38bfd51b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000
|
||||||
test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||||
test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
||||||
test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041a8ad04262cc02545cc4934739e086f37b3ea04ba83195a151a736e55cf2cc68407f9dc20f19c68071ced3f6d5f20908ce9332526c955e66974aaf53c7e58ca581c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000
|
test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412b2ccc98803d3057de86d25f9dda53a5e41c5200ff6355b7627e6ce570adfe555a5fed532f95ca6c0a189594a7eef964398c5dbbddf2931b111c3888ec57301e1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000
|
||||||
test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d461cc5890a8a58d13249a485335b44671612c97b7a12004b5cfb163bdbf4c2f15dde7cb500c22f724f813b7d6fe5062076f63ee5b91c7e984f011a5d1ce6fca1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000
|
test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004133e8a83bf0ab458c292bf06e076844c9a2b2fbfbd2fbf1e9b13dd7c79a594597378fd61fe3b24def396d55636a50eb5c847367b1c1108e99c4f31172af84d6481c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000
|
||||||
test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
||||||
test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006b56051582a970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000419861aedfb04e8f7b9fe147a7d19c41f9b1cf37a06850b09f645fb351c003967d43d365af50b08ef741348898578b7fa1454a8e9cd0390eaf6c2939d7b817d0d31c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d86a1edea6862ef9c8df971417410c87f6cf21d40542760db70fdd800b82f7c9722702f735433a898b8cc208b131cd865589d11f5028da2b9866667e0d38bfd51b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
|
||||||
test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
|
||||||
test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004133c6e3010dfd7e69b717338de47a7129351aefa89191faa6c76250356c6adae041da1ef7cb664511e942ecd28f7b578b38dad510df3185241c8336259027ded11c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000
|
test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000410bc65c37597bc37547d90657196ff352b0d9d80df5435b74efb5fda78c203a047fdc53c8f77c800db59ddda08e3479e64cb706cc7296d4f68cb0ab46f03e8ff91b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000
|
||||||
test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041a8ad04262cc02545cc4934739e086f37b3ea04ba83195a151a736e55cf2cc68407f9dc20f19c68071ced3f6d5f20908ce9332526c955e66974aaf53c7e58ca581c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412b2ccc98803d3057de86d25f9dda53a5e41c5200ff6355b7627e6ce570adfe555a5fed532f95ca6c0a189594a7eef964398c5dbbddf2931b111c3888ec57301e1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
|
||||||
test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685552e700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccef000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041f208f39e98ca0821f644f4fd3be7ab23ce75c0e3d6e425b00327067b482dc3963e0c481141fe530d79cc8361ea628a0f53d69cbbd09b7c2416581f04392704681b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000
|
test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004133e8a83bf0ab458c292bf06e076844c9a2b2fbfbd2fbf1e9b13dd7c79a594597378fd61fe3b24def396d55636a50eb5c847367b1c1108e99c4f31172af84d6481c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000
|
||||||
test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685552e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccee000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041d461cc5890a8a58d13249a485335b44671612c97b7a12004b5cfb163bdbf4c2f15dde7cb500c22f724f813b7d6fe5062076f63ee5b91c7e984f011a5d1ce6fca1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000
|
test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f300000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004133e8a83bf0ab458c292bf06e076844c9a2b2fbfbd2fbf1e9b13dd7c79a594597378fd61fe3b24def396d55636a50eb5c847367b1c1108e99c4f31172af84d6481c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000
|
||||||
test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685552e700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccef000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041726b94d0c0b711c31e19e1b33bcdd87e4526b4fd804471bbafcb0fed1fdc5aea23922bb4d46f16add4f01136165643feb355d89bf31d1a25a8a1a126ee3af43e1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000
|
test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000685c1eeb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f3000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041d86a1edea6862ef9c8df971417410c87f6cf21d40542760db70fdd800b82f7c9722702f735433a898b8cc208b131cd865589d11f5028da2b9866667e0d38bfd51b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000
|
||||||
test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000
|
test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000
|
||||||
test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000685552e700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000682dccef00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000410488df0c2ac790f75505dbd2754518d70fb02c32fb3bb3e63e299259037765606ca8d38d05c9c6d2d82e3b39203f378ad489f715a2aeb7df674ee4b8e5c8d1151c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000
|
test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000685c1eec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000683498f400000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041aa54dffe78286acee8d7bc6c0adf055c63efb57333eaf9684f8d5dac70a81c342970954434cfaf8c5beeeccb4ab9ed1c2dd8ae2e3031fb689b42e938d5c7841a1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000
|
||||||
test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102
|
test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102
|
||||||
test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032
|
test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032
|
||||||
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ use alloy_sol_types::SolValue;
|
|||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use tycho_common::{hex_bytes::Bytes, models::Chain};
|
use tycho_common::{hex_bytes::Bytes, models::Chain};
|
||||||
use tycho_execution::encoding::{
|
use tycho_execution::encoding::{
|
||||||
evm::encoder_builders::{TychoExecutorEncoderBuilder, TychoRouterEncoderBuilder},
|
evm::{
|
||||||
models::Solution,
|
approvals::permit2::PermitSingle,
|
||||||
|
encoder_builders::{TychoExecutorEncoderBuilder, TychoRouterEncoderBuilder},
|
||||||
|
},
|
||||||
|
models::{Solution, UserTransferType},
|
||||||
tycho_encoder::TychoEncoder,
|
tycho_encoder::TychoEncoder,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,8 +24,6 @@ use tycho_execution::encoding::{
|
|||||||
/// "given_amount": "123...",
|
/// "given_amount": "123...",
|
||||||
/// "checked_token": "0x...",
|
/// "checked_token": "0x...",
|
||||||
/// "exact_out": false,
|
/// "exact_out": false,
|
||||||
/// "slippage": 0.01,
|
|
||||||
/// "expected_amount": "123...",
|
|
||||||
/// "checked_amount": "123...",
|
/// "checked_amount": "123...",
|
||||||
/// "swaps": [{
|
/// "swaps": [{
|
||||||
/// "component": {
|
/// "component": {
|
||||||
@@ -51,9 +52,9 @@ pub struct Cli {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
router_address: Option<Bytes>,
|
router_address: Option<Bytes>,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
swapper_pk: Option<String>,
|
user_transfer_type: Option<UserTransferType>,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
token_in_already_in_router: Option<bool>,
|
swapper_pk: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
@@ -87,12 +88,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
if let Some(router_address) = cli.router_address {
|
if let Some(router_address) = cli.router_address {
|
||||||
builder = builder.router_address(router_address);
|
builder = builder.router_address(router_address);
|
||||||
}
|
}
|
||||||
|
if let Some(user_transfer_type) = cli.user_transfer_type {
|
||||||
|
builder = builder.user_transfer_type(user_transfer_type);
|
||||||
|
}
|
||||||
|
#[allow(deprecated)]
|
||||||
if let Some(swapper_pk) = cli.swapper_pk {
|
if let Some(swapper_pk) = cli.swapper_pk {
|
||||||
builder = builder.swapper_pk(swapper_pk);
|
builder = builder.swapper_pk(swapper_pk);
|
||||||
}
|
}
|
||||||
if let Some(token_in_already_in_router) = cli.token_in_already_in_router {
|
|
||||||
builder = builder.token_in_already_in_router(token_in_already_in_router);
|
|
||||||
}
|
|
||||||
builder.build()?
|
builder.build()?
|
||||||
}
|
}
|
||||||
Commands::TychoExecutor => TychoExecutorEncoderBuilder::new()
|
Commands::TychoExecutor => TychoExecutorEncoderBuilder::new()
|
||||||
@@ -102,19 +104,20 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
let encoded_solutions = encoder.encode_solutions(vec![solution])?;
|
let encoded_solutions = encoder.encode_solutions(vec![solution])?;
|
||||||
let encoded = serde_json::json!({
|
let encoded = serde_json::json!({
|
||||||
"swaps": format!("0x{}", hex::encode(&encoded_solutions[0].swaps)),
|
"swaps": format!("0x{}", hex::encode(&encoded_solutions[0].swaps)),
|
||||||
"interacting_with": format!("0x{}", hex::encode(&encoded_solutions[0].interacting_with)),
|
"interacting_with": format!("0x{}", hex::encode(&encoded_solutions[0].interacting_with)),
|
||||||
"selector": format!("{}",&encoded_solutions[0].selector),
|
"function_signature": format!("{}",&encoded_solutions[0].function_signature),
|
||||||
"n_tokens": format!("{}", &encoded_solutions[0].n_tokens),
|
"n_tokens": format!("{}", &encoded_solutions[0].n_tokens),
|
||||||
"permit": encoded_solutions[0].permit
|
"permit": match encoded_solutions[0].permit.as_ref() {
|
||||||
.as_ref()
|
Some(permit) => {
|
||||||
.map(|permit| format!("0x{}", hex::encode(permit.abi_encode())))
|
match PermitSingle::try_from(permit) {
|
||||||
.unwrap_or_else(String::new),
|
Ok(sol_permit) => format!("0x{}", hex::encode(sol_permit.abi_encode())),
|
||||||
"signature": encoded_solutions[0].signature
|
Err(_) => String::new(),
|
||||||
.as_ref()
|
}
|
||||||
.map(|signature| format!("0x{}", hex::encode(signature.as_bytes())))
|
}
|
||||||
.unwrap_or_else(String::new),
|
None => String::new(),
|
||||||
});
|
},
|
||||||
|
});
|
||||||
// Output the encoded result as JSON to stdout
|
// Output the encoded result as JSON to stdout
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ use alloy::{
|
|||||||
primitives::{aliases::U48, Address, Bytes as AlloyBytes, TxKind, U160, U256},
|
primitives::{aliases::U48, Address, Bytes as AlloyBytes, TxKind, U160, U256},
|
||||||
providers::{Provider, RootProvider},
|
providers::{Provider, RootProvider},
|
||||||
rpc::types::{TransactionInput, TransactionRequest},
|
rpc::types::{TransactionInput, TransactionRequest},
|
||||||
signers::{local::PrivateKeySigner, SignerSync},
|
|
||||||
transports::BoxTransport,
|
transports::BoxTransport,
|
||||||
};
|
};
|
||||||
use alloy_primitives::{PrimitiveSignature as Signature, B256};
|
use alloy_sol_types::{sol, SolValue};
|
||||||
use alloy_sol_types::{eip712_domain, sol, SolStruct, SolValue};
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
@@ -23,7 +21,7 @@ use crate::encoding::{
|
|||||||
encoding_utils::encode_input,
|
encoding_utils::encode_input,
|
||||||
utils::{biguint_to_u256, bytes_to_address, get_client, get_runtime},
|
utils::{biguint_to_u256, bytes_to_address, get_client, get_runtime},
|
||||||
},
|
},
|
||||||
models::Chain,
|
models,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Struct for managing Permit2 operations, including encoding approvals and fetching allowance
|
/// Struct for managing Permit2 operations, including encoding approvals and fetching allowance
|
||||||
@@ -32,8 +30,6 @@ use crate::encoding::{
|
|||||||
pub struct Permit2 {
|
pub struct Permit2 {
|
||||||
address: Address,
|
address: Address,
|
||||||
client: Arc<RootProvider<BoxTransport>>,
|
client: Arc<RootProvider<BoxTransport>>,
|
||||||
signer: PrivateKeySigner,
|
|
||||||
chain_id: u64,
|
|
||||||
runtime_handle: Handle,
|
runtime_handle: Handle,
|
||||||
// Store the runtime to prevent it from being dropped before use.
|
// Store the runtime to prevent it from being dropped before use.
|
||||||
// This is required since tycho-execution does not have a pre-existing runtime.
|
// This is required since tycho-execution does not have a pre-existing runtime.
|
||||||
@@ -68,23 +64,53 @@ sol! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&PermitSingle> for models::PermitSingle {
|
||||||
|
type Error = EncodingError;
|
||||||
|
|
||||||
|
fn try_from(sol: &PermitSingle) -> Result<Self, EncodingError> {
|
||||||
|
Ok(models::PermitSingle {
|
||||||
|
details: models::PermitDetails {
|
||||||
|
token: Bytes::from(sol.details.token.to_vec()),
|
||||||
|
amount: BigUint::from_bytes_be(&sol.details.amount.to_be_bytes::<20>()),
|
||||||
|
expiration: BigUint::from_bytes_be(
|
||||||
|
&sol.details
|
||||||
|
.expiration
|
||||||
|
.to_be_bytes::<6>(),
|
||||||
|
),
|
||||||
|
nonce: BigUint::from_bytes_be(&sol.details.nonce.to_be_bytes::<6>()),
|
||||||
|
},
|
||||||
|
spender: Bytes::from(sol.spender.to_vec()),
|
||||||
|
sig_deadline: BigUint::from_bytes_be(&sol.sigDeadline.to_be_bytes::<32>()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&models::PermitSingle> for PermitSingle {
|
||||||
|
type Error = EncodingError;
|
||||||
|
|
||||||
|
fn try_from(p: &models::PermitSingle) -> Result<Self, EncodingError> {
|
||||||
|
Ok(PermitSingle {
|
||||||
|
details: PermitDetails {
|
||||||
|
token: bytes_to_address(&p.details.token)?,
|
||||||
|
amount: U160::from(biguint_to_u256(&p.details.amount)),
|
||||||
|
expiration: U48::from(biguint_to_u256(&p.details.expiration)),
|
||||||
|
nonce: U48::from(biguint_to_u256(&p.details.nonce)),
|
||||||
|
},
|
||||||
|
spender: bytes_to_address(&p.spender)?,
|
||||||
|
sigDeadline: biguint_to_u256(&p.sig_deadline),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Permit2 {
|
impl Permit2 {
|
||||||
pub fn new(swapper_pk: String, chain: Chain) -> Result<Self, EncodingError> {
|
pub fn new() -> Result<Self, EncodingError> {
|
||||||
let (handle, runtime) = get_runtime()?;
|
let (handle, runtime) = get_runtime()?;
|
||||||
let client = block_in_place(|| handle.block_on(get_client()))?;
|
let client = block_in_place(|| handle.block_on(get_client()))?;
|
||||||
let pk = B256::from_str(&swapper_pk).map_err(|_| {
|
|
||||||
EncodingError::FatalError("Failed to convert swapper private key to B256".to_string())
|
|
||||||
})?;
|
|
||||||
let signer = PrivateKeySigner::from_bytes(&pk).map_err(|_| {
|
|
||||||
EncodingError::FatalError("Failed to create signer from private key".to_string())
|
|
||||||
})?;
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
address: Address::from_str("0x000000000022D473030F116dDEE9F6B43aC78BA3")
|
address: Address::from_str("0x000000000022D473030F116dDEE9F6B43aC78BA3")
|
||||||
.map_err(|_| EncodingError::FatalError("Permit2 address not valid".to_string()))?,
|
.map_err(|_| EncodingError::FatalError("Permit2 address not valid".to_string()))?,
|
||||||
client,
|
client,
|
||||||
runtime_handle: handle,
|
runtime_handle: handle,
|
||||||
signer,
|
|
||||||
chain_id: chain.id,
|
|
||||||
runtime,
|
runtime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -123,14 +149,14 @@ impl Permit2 {
|
|||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates permit single and signature
|
/// Creates permit single
|
||||||
pub fn get_permit(
|
pub fn get_permit(
|
||||||
&self,
|
&self,
|
||||||
spender: &Bytes,
|
spender: &Bytes,
|
||||||
owner: &Bytes,
|
owner: &Bytes,
|
||||||
token: &Bytes,
|
token: &Bytes,
|
||||||
amount: &BigUint,
|
amount: &BigUint,
|
||||||
) -> Result<(PermitSingle, Signature), EncodingError> {
|
) -> Result<models::PermitSingle, EncodingError> {
|
||||||
let current_time = Utc::now()
|
let current_time = Utc::now()
|
||||||
.naive_utc()
|
.naive_utc()
|
||||||
.and_utc()
|
.and_utc()
|
||||||
@@ -149,21 +175,7 @@ impl Permit2 {
|
|||||||
sigDeadline: sig_deadline,
|
sigDeadline: sig_deadline,
|
||||||
};
|
};
|
||||||
|
|
||||||
let domain = eip712_domain! {
|
models::PermitSingle::try_from(&permit_single)
|
||||||
name: "Permit2",
|
|
||||||
chain_id: self.chain_id,
|
|
||||||
verifying_contract: self.address,
|
|
||||||
};
|
|
||||||
let hash = permit_single.eip712_signing_hash(&domain);
|
|
||||||
let signature = self
|
|
||||||
.signer
|
|
||||||
.sign_hash_sync(&hash)
|
|
||||||
.map_err(|e| {
|
|
||||||
EncodingError::FatalError(format!(
|
|
||||||
"Failed to sign permit2 approval with error: {e}"
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok((permit_single, signature))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,11 +183,13 @@ impl Permit2 {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use alloy_primitives::Uint;
|
use alloy::signers::local::PrivateKeySigner;
|
||||||
|
use alloy_primitives::{Uint, B256};
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use tycho_common::models::Chain as TychoCommonChain;
|
use tycho_common::models::Chain as TychoCommonChain;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::encoding::{evm::encoding_utils::sign_permit, models::Chain};
|
||||||
|
|
||||||
// These two implementations are to avoid comparing the expiration and sig_deadline fields
|
// These two implementations are to avoid comparing the expiration and sig_deadline fields
|
||||||
// because they are timestamps
|
// because they are timestamps
|
||||||
@@ -214,9 +228,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_existing_allowance() {
|
fn test_get_existing_allowance() {
|
||||||
let swapper_pk =
|
let manager = Permit2::new().unwrap();
|
||||||
"4c0883a69102937d6231471b5dbb6204fe512961708279feb1be6ae5538da033".to_string();
|
|
||||||
let manager = Permit2::new(swapper_pk, eth_chain()).unwrap();
|
|
||||||
|
|
||||||
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
||||||
let owner = Bytes::from_str("0x2c6a3cd97c6283b95ac8c5a4459ebb0d5fd404f4").unwrap();
|
let owner = Bytes::from_str("0x2c6a3cd97c6283b95ac8c5a4459ebb0d5fd404f4").unwrap();
|
||||||
@@ -233,30 +245,27 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_permit() {
|
fn test_get_permit() {
|
||||||
// Set up a mock private key for signing
|
let permit2 = Permit2::new().expect("Failed to create Permit2");
|
||||||
let private_key =
|
|
||||||
"4c0883a69102937d6231471b5dbb6204fe512961708279feb1be6ae5538da033".to_string();
|
|
||||||
let permit2 = Permit2::new(private_key, eth_chain()).expect("Failed to create Permit2");
|
|
||||||
|
|
||||||
let owner = Bytes::from_str("0x2c6a3cd97c6283b95ac8c5a4459ebb0d5fd404f4").unwrap();
|
let owner = Bytes::from_str("0x2c6a3cd97c6283b95ac8c5a4459ebb0d5fd404f4").unwrap();
|
||||||
let spender = Bytes::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap();
|
let spender = Bytes::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap();
|
||||||
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
||||||
let amount = BigUint::from(1000u64);
|
let amount = BigUint::from(1000u64);
|
||||||
|
|
||||||
let (permit, _) = permit2
|
let permit = permit2
|
||||||
.get_permit(&spender, &owner, &token, &amount)
|
.get_permit(&spender, &owner, &token, &amount)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let expected_details = PermitDetails {
|
let expected_details = models::PermitDetails {
|
||||||
token: bytes_to_address(&token).unwrap(),
|
token,
|
||||||
amount: U160::from(biguint_to_u256(&amount)),
|
amount,
|
||||||
expiration: U48::from(Utc::now().timestamp() as u64 + PERMIT_EXPIRATION),
|
expiration: BigUint::from(Utc::now().timestamp() as u64 + PERMIT_EXPIRATION),
|
||||||
nonce: U48::from(0),
|
nonce: BigUint::from(0u64),
|
||||||
};
|
};
|
||||||
let expected_permit_single = PermitSingle {
|
let expected_permit_single = models::PermitSingle {
|
||||||
details: expected_details,
|
details: expected_details,
|
||||||
spender: Address::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap(),
|
spender: Bytes::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap(),
|
||||||
sigDeadline: U256::from(Utc::now().timestamp() as u64 + PERMIT_SIG_EXPIRATION),
|
sig_deadline: BigUint::from(Utc::now().timestamp() as u64 + PERMIT_SIG_EXPIRATION),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -276,8 +285,19 @@ mod tests {
|
|||||||
let anvil_private_key =
|
let anvil_private_key =
|
||||||
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".to_string();
|
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".to_string();
|
||||||
|
|
||||||
let permit2 =
|
let pk = B256::from_str(&anvil_private_key)
|
||||||
Permit2::new(anvil_private_key, eth_chain()).expect("Failed to create Permit2");
|
.map_err(|_| {
|
||||||
|
EncodingError::FatalError(
|
||||||
|
"Failed to convert swapper private key to B256".to_string(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let signer = PrivateKeySigner::from_bytes(&pk)
|
||||||
|
.map_err(|_| {
|
||||||
|
EncodingError::FatalError("Failed to create signer from private key".to_string())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let permit2 = Permit2::new().expect("Failed to create Permit2");
|
||||||
|
|
||||||
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
let token = Bytes::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap();
|
||||||
let amount = BigUint::from(1000u64);
|
let amount = BigUint::from(1000u64);
|
||||||
@@ -307,11 +327,15 @@ mod tests {
|
|||||||
|
|
||||||
let spender = Bytes::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap();
|
let spender = Bytes::from_str("0xba12222222228d8ba445958a75a0704d566bf2c8").unwrap();
|
||||||
|
|
||||||
let (permit, signature) = permit2
|
let permit = permit2
|
||||||
.get_permit(&spender, &anvil_account, &token, &amount)
|
.get_permit(&spender, &anvil_account, &token, &amount)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let sol_permit: PermitSingle =
|
||||||
|
PermitSingle::try_from(&permit).expect("Failed to convert to PermitSingle");
|
||||||
|
|
||||||
|
let signature = sign_permit(eth_chain().id, &permit, signer).unwrap();
|
||||||
let encoded =
|
let encoded =
|
||||||
(bytes_to_address(&anvil_account).unwrap(), permit, signature.as_bytes().to_vec())
|
(bytes_to_address(&anvil_account).unwrap(), sol_permit, signature.as_bytes().to_vec())
|
||||||
.abi_encode();
|
.abi_encode();
|
||||||
|
|
||||||
let function_signature =
|
let function_signature =
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
|
use alloy::signers::local::PrivateKeySigner;
|
||||||
|
use alloy_primitives::B256;
|
||||||
use tycho_common::{models::Chain as TychoCommonChain, Bytes};
|
use tycho_common::{models::Chain as TychoCommonChain, Bytes};
|
||||||
|
|
||||||
use crate::encoding::{
|
use crate::encoding::{
|
||||||
@@ -9,7 +11,7 @@ use crate::encoding::{
|
|||||||
swap_encoder::swap_encoder_registry::SwapEncoderRegistry,
|
swap_encoder::swap_encoder_registry::SwapEncoderRegistry,
|
||||||
tycho_encoders::{TychoExecutorEncoder, TychoRouterEncoder},
|
tycho_encoders::{TychoExecutorEncoder, TychoRouterEncoder},
|
||||||
},
|
},
|
||||||
models::Chain,
|
models::{Chain, UserTransferType},
|
||||||
tycho_encoder::TychoEncoder,
|
tycho_encoder::TychoEncoder,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,11 +19,11 @@ use crate::encoding::{
|
|||||||
///
|
///
|
||||||
/// This struct allows setting a chain and strategy encoder before building the final encoder.
|
/// This struct allows setting a chain and strategy encoder before building the final encoder.
|
||||||
pub struct TychoRouterEncoderBuilder {
|
pub struct TychoRouterEncoderBuilder {
|
||||||
swapper_pk: Option<String>,
|
|
||||||
chain: Option<Chain>,
|
chain: Option<Chain>,
|
||||||
|
user_transfer_type: Option<UserTransferType>,
|
||||||
executors_file_path: Option<String>,
|
executors_file_path: Option<String>,
|
||||||
router_address: Option<Bytes>,
|
router_address: Option<Bytes>,
|
||||||
token_in_already_in_router: Option<bool>,
|
swapper_pk: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TychoRouterEncoderBuilder {
|
impl Default for TychoRouterEncoderBuilder {
|
||||||
@@ -33,11 +35,11 @@ impl Default for TychoRouterEncoderBuilder {
|
|||||||
impl TychoRouterEncoderBuilder {
|
impl TychoRouterEncoderBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
TychoRouterEncoderBuilder {
|
TychoRouterEncoderBuilder {
|
||||||
swapper_pk: None,
|
|
||||||
chain: None,
|
chain: None,
|
||||||
executors_file_path: None,
|
executors_file_path: None,
|
||||||
router_address: None,
|
router_address: None,
|
||||||
token_in_already_in_router: None,
|
swapper_pk: None,
|
||||||
|
user_transfer_type: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn chain(mut self, chain: TychoCommonChain) -> Self {
|
pub fn chain(mut self, chain: TychoCommonChain) -> Self {
|
||||||
@@ -45,6 +47,11 @@ impl TychoRouterEncoderBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn user_transfer_type(mut self, user_transfer_type: UserTransferType) -> Self {
|
||||||
|
self.user_transfer_type = Some(user_transfer_type);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the `executors_file_path` manually.
|
/// Sets the `executors_file_path` manually.
|
||||||
/// If it's not set, the default path will be used (config/executor_addresses.json)
|
/// If it's not set, the default path will be used (config/executor_addresses.json)
|
||||||
pub fn executors_file_path(mut self, executors_file_path: String) -> Self {
|
pub fn executors_file_path(mut self, executors_file_path: String) -> Self {
|
||||||
@@ -59,25 +66,22 @@ impl TychoRouterEncoderBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `swapper_pk` for the encoder. This is used to sign permit2 objects. This is only
|
||||||
|
/// needed if you intend to get the full calldata for the transfer. We do not recommend
|
||||||
|
/// using this option, you should sign and create the function calldata entirely on your
|
||||||
|
/// own.
|
||||||
|
#[deprecated(
|
||||||
|
note = "This is deprecated and will be removed in the future. You should sign and create the function calldata on your own."
|
||||||
|
)]
|
||||||
pub fn swapper_pk(mut self, swapper_pk: String) -> Self {
|
pub fn swapper_pk(mut self, swapper_pk: String) -> Self {
|
||||||
self.swapper_pk = Some(swapper_pk);
|
self.swapper_pk = Some(swapper_pk);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the `token_in_already_in_router` flag.
|
|
||||||
// If set to true, the encoder will assume that the token in is already in the router.
|
|
||||||
// WARNING: this is an advanced feature and should be used with caution. Make sure you have
|
|
||||||
// checks to make sure that your tokens won't be lost. The Router is not considered safe to hold
|
|
||||||
// tokens, so if this is not done within the same transaction you will lose your tokens.
|
|
||||||
pub fn token_in_already_in_router(mut self, token_in_already_in_router: bool) -> Self {
|
|
||||||
self.token_in_already_in_router = Some(token_in_already_in_router);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the `TychoRouterEncoder` instance using the configured chain.
|
/// Builds the `TychoRouterEncoder` instance using the configured chain.
|
||||||
/// Returns an error if either the chain has not been set.
|
/// Returns an error if either the chain has not been set.
|
||||||
pub fn build(self) -> Result<Box<dyn TychoEncoder>, EncodingError> {
|
pub fn build(self) -> Result<Box<dyn TychoEncoder>, EncodingError> {
|
||||||
if let Some(chain) = self.chain {
|
if let (Some(chain), Some(user_transfer_type)) = (self.chain, self.user_transfer_type) {
|
||||||
let tycho_router_address;
|
let tycho_router_address;
|
||||||
if let Some(address) = self.router_address {
|
if let Some(address) = self.router_address {
|
||||||
tycho_router_address = address;
|
tycho_router_address = address;
|
||||||
@@ -95,17 +99,28 @@ impl TychoRouterEncoderBuilder {
|
|||||||
let swap_encoder_registry =
|
let swap_encoder_registry =
|
||||||
SwapEncoderRegistry::new(self.executors_file_path.clone(), chain.clone())?;
|
SwapEncoderRegistry::new(self.executors_file_path.clone(), chain.clone())?;
|
||||||
|
|
||||||
|
let signer = if let Some(pk) = self.swapper_pk {
|
||||||
|
let pk = B256::from_str(&pk).map_err(|_| {
|
||||||
|
EncodingError::FatalError("Invalid swapper private key provided".to_string())
|
||||||
|
})?;
|
||||||
|
Some(PrivateKeySigner::from_bytes(&pk).map_err(|_| {
|
||||||
|
EncodingError::FatalError("Failed to create signer".to_string())
|
||||||
|
})?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Box::new(TychoRouterEncoder::new(
|
Ok(Box::new(TychoRouterEncoder::new(
|
||||||
chain,
|
chain,
|
||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
self.swapper_pk,
|
|
||||||
tycho_router_address,
|
tycho_router_address,
|
||||||
self.token_in_already_in_router
|
user_transfer_type,
|
||||||
.unwrap_or(false),
|
signer,
|
||||||
)?))
|
)?))
|
||||||
} else {
|
} else {
|
||||||
Err(EncodingError::FatalError(
|
Err(EncodingError::FatalError(
|
||||||
"Please set the chain and router address before building the encoder".to_string(),
|
"Please set the chain and user transfer type before building the encoder"
|
||||||
|
.to_string(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,262 @@
|
|||||||
use alloy_primitives::{Keccak256, U256};
|
use std::str::FromStr;
|
||||||
use alloy_sol_types::SolValue;
|
|
||||||
|
use alloy::{
|
||||||
|
primitives::U256,
|
||||||
|
signers::{local::PrivateKeySigner, Signature, SignerSync},
|
||||||
|
};
|
||||||
|
use alloy_primitives::{Address, Keccak256};
|
||||||
|
use alloy_sol_types::{eip712_domain, SolStruct, SolValue};
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use tycho_common::Bytes;
|
use tycho_common::Bytes;
|
||||||
|
|
||||||
use crate::encoding::{
|
use crate::encoding::{
|
||||||
errors::EncodingError,
|
errors::EncodingError,
|
||||||
evm::utils::{biguint_to_u256, bytes_to_address},
|
evm::{
|
||||||
models::{EncodedSolution, NativeAction, Solution, Transaction},
|
approvals::permit2::PermitSingle,
|
||||||
|
utils::{biguint_to_u256, bytes_to_address},
|
||||||
|
},
|
||||||
|
models,
|
||||||
|
models::{EncodedSolution, NativeAction, Solution, Transaction, UserTransferType},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Encodes a transaction for the Tycho Router using one of its supported swap methods.
|
||||||
|
///
|
||||||
|
/// # Overview
|
||||||
|
///
|
||||||
|
/// This function provides an **example implementation** of how to encode a call to the Tycho
|
||||||
|
/// Router. It handles all currently supported swap selectors such as:
|
||||||
|
/// - `singleSwap`
|
||||||
|
/// - `singleSwapPermit2`
|
||||||
|
/// - `sequentialSwap`
|
||||||
|
/// - `sequentialSwapPermit2`
|
||||||
|
/// - `splitSwap`
|
||||||
|
/// - `splitSwapPermit2`
|
||||||
|
///
|
||||||
|
/// The encoding includes handling of native asset wrapping/unwrapping, permit2 support,
|
||||||
|
/// and proper input argument formatting based on the function signature string.
|
||||||
|
///
|
||||||
|
/// # ⚠️ Important Responsibility Note
|
||||||
|
///
|
||||||
|
/// This function is intended as **an illustrative example only**. **Users must implement
|
||||||
|
/// their own encoding logic** to ensure:
|
||||||
|
/// - Full control of parameters passed to the router.
|
||||||
|
/// - Proper validation and setting of critical inputs such as `minAmountOut`.
|
||||||
|
/// - Signing of permit2 objects.
|
||||||
|
///
|
||||||
|
/// While Tycho is responsible for encoding the swap paths themselves, the input arguments
|
||||||
|
/// to the router's methods act as **guardrails** for on-chain execution safety.
|
||||||
|
/// Thus, the user must **take responsibility** for ensuring correctness of all input parameters,
|
||||||
|
/// including `minAmountOut`, `receiver`, and permit2 logic.
|
||||||
|
///
|
||||||
|
/// # Min Amount Out
|
||||||
|
///
|
||||||
|
/// The `minAmountOut` calculation used here is just an example.
|
||||||
|
/// You should ideally:
|
||||||
|
/// - Query an external service (e.g., DEX aggregators, oracle, off-chain price feed).
|
||||||
|
/// - Use your own strategy to determine an accurate and safe minimum acceptable output amount.
|
||||||
|
///
|
||||||
|
/// ⚠️ If `minAmountOut` is too low, your swap may be front-run or sandwiched, resulting in loss of
|
||||||
|
/// funds.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
/// - `encoded_solution`: The solution already encoded by Tycho.
|
||||||
|
/// - `solution`: The high-level solution including tokens, amounts, and receiver info.
|
||||||
|
/// - `token_in_already_in_router`: Whether the input token is already present in the router.
|
||||||
|
/// - `router_address`: The address of the Tycho Router contract.
|
||||||
|
/// - `native_address`: The address used to represent the native token
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// A `Result<Transaction, EncodingError>` that either contains the full transaction data (to,
|
||||||
|
/// value, data), or an error if the inputs are invalid.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - Returns `EncodingError::FatalError` if the function signature is unsupported or required
|
||||||
|
/// fields (e.g., permit or signature) are missing.
|
||||||
|
pub fn encode_tycho_router_call(
|
||||||
|
chain_id: u64,
|
||||||
|
encoded_solution: EncodedSolution,
|
||||||
|
solution: &Solution,
|
||||||
|
user_transfer_type: UserTransferType,
|
||||||
|
native_address: Bytes,
|
||||||
|
signer: Option<PrivateKeySigner>,
|
||||||
|
) -> Result<Transaction, EncodingError> {
|
||||||
|
let (mut unwrap, mut wrap) = (false, false);
|
||||||
|
if let Some(action) = solution.native_action.clone() {
|
||||||
|
match action {
|
||||||
|
NativeAction::Wrap => wrap = true,
|
||||||
|
NativeAction::Unwrap => unwrap = true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let given_amount = biguint_to_u256(&solution.given_amount);
|
||||||
|
let min_amount_out = biguint_to_u256(&solution.checked_amount);
|
||||||
|
let given_token = bytes_to_address(&solution.given_token)?;
|
||||||
|
let checked_token = bytes_to_address(&solution.checked_token)?;
|
||||||
|
let receiver = bytes_to_address(&solution.receiver)?;
|
||||||
|
let n_tokens = U256::from(encoded_solution.n_tokens);
|
||||||
|
let (permit, signature) = if let Some(p) = encoded_solution.permit {
|
||||||
|
let permit = Some(
|
||||||
|
PermitSingle::try_from(&p)
|
||||||
|
.map_err(|_| EncodingError::InvalidInput("Invalid permit".to_string()))?,
|
||||||
|
);
|
||||||
|
let signer = signer
|
||||||
|
.ok_or(EncodingError::FatalError("Signer must be set to use permit2".to_string()))?;
|
||||||
|
let signature = sign_permit(chain_id, &p, signer)?;
|
||||||
|
(permit, signature.as_bytes().to_vec())
|
||||||
|
} else {
|
||||||
|
(None, vec![])
|
||||||
|
};
|
||||||
|
|
||||||
|
let method_calldata = if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("singleSwapPermit2")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
receiver,
|
||||||
|
permit.ok_or(EncodingError::FatalError(
|
||||||
|
"permit2 object must be set to use permit2".to_string(),
|
||||||
|
))?,
|
||||||
|
signature,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("singleSwap")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
receiver,
|
||||||
|
user_transfer_type == UserTransferType::TransferFrom,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("sequentialSwapPermit2")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
receiver,
|
||||||
|
permit.ok_or(EncodingError::FatalError(
|
||||||
|
"permit2 object must be set to use permit2".to_string(),
|
||||||
|
))?,
|
||||||
|
signature,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("sequentialSwap")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
receiver,
|
||||||
|
user_transfer_type == UserTransferType::TransferFrom,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("splitSwapPermit2")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
n_tokens,
|
||||||
|
receiver,
|
||||||
|
permit.ok_or(EncodingError::FatalError(
|
||||||
|
"permit2 object must be set to use permit2".to_string(),
|
||||||
|
))?,
|
||||||
|
signature,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else if encoded_solution
|
||||||
|
.function_signature
|
||||||
|
.contains("splitSwap")
|
||||||
|
{
|
||||||
|
(
|
||||||
|
given_amount,
|
||||||
|
given_token,
|
||||||
|
checked_token,
|
||||||
|
min_amount_out,
|
||||||
|
wrap,
|
||||||
|
unwrap,
|
||||||
|
n_tokens,
|
||||||
|
receiver,
|
||||||
|
user_transfer_type == UserTransferType::TransferFrom,
|
||||||
|
encoded_solution.swaps,
|
||||||
|
)
|
||||||
|
.abi_encode()
|
||||||
|
} else {
|
||||||
|
Err(EncodingError::FatalError("Invalid function signature for Tycho router".to_string()))?
|
||||||
|
};
|
||||||
|
|
||||||
|
let contract_interaction = encode_input(&encoded_solution.function_signature, method_calldata);
|
||||||
|
let value = if solution.given_token == native_address {
|
||||||
|
solution.given_amount.clone()
|
||||||
|
} else {
|
||||||
|
BigUint::ZERO
|
||||||
|
};
|
||||||
|
Ok(Transaction { to: encoded_solution.interacting_with, value, data: contract_interaction })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Signs a Permit2 `PermitSingle` struct using the EIP-712 signing scheme.
|
||||||
|
///
|
||||||
|
/// This function constructs an EIP-712 domain specific to the Permit2 contract and computes the
|
||||||
|
/// hash of the provided `PermitSingle`. It then uses the given `PrivateKeySigner` to produce
|
||||||
|
/// a cryptographic signature of the permit.
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
/// This is only an **example implementation** provided for reference purposes.
|
||||||
|
/// **Do not rely on this in production.** You should implement your own version.
|
||||||
|
pub fn sign_permit(
|
||||||
|
chain_id: u64,
|
||||||
|
permit_single: &models::PermitSingle,
|
||||||
|
signer: PrivateKeySigner,
|
||||||
|
) -> Result<Signature, EncodingError> {
|
||||||
|
let permit2_address = Address::from_str("0x000000000022D473030F116dDEE9F6B43aC78BA3")
|
||||||
|
.map_err(|_| EncodingError::FatalError("Permit2 address not valid".to_string()))?;
|
||||||
|
let domain = eip712_domain! {
|
||||||
|
name: "Permit2",
|
||||||
|
chain_id: chain_id,
|
||||||
|
verifying_contract: permit2_address,
|
||||||
|
};
|
||||||
|
let permit_single: PermitSingle = PermitSingle::try_from(permit_single)?;
|
||||||
|
let hash = permit_single.eip712_signing_hash(&domain);
|
||||||
|
signer
|
||||||
|
.sign_hash_sync(&hash)
|
||||||
|
.map_err(|e| {
|
||||||
|
EncodingError::FatalError(format!("Failed to sign permit2 approval with error: {e}"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Encodes the input data for a function call to the given function selector.
|
/// Encodes the input data for a function call to the given function selector.
|
||||||
pub fn encode_input(selector: &str, mut encoded_args: Vec<u8>) -> Vec<u8> {
|
pub fn encode_input(selector: &str, mut encoded_args: Vec<u8>) -> Vec<u8> {
|
||||||
let mut hasher = Keccak256::new();
|
let mut hasher = Keccak256::new();
|
||||||
@@ -30,220 +278,3 @@ pub fn encode_input(selector: &str, mut encoded_args: Vec<u8>) -> Vec<u8> {
|
|||||||
call_data.extend(encoded_args);
|
call_data.extend(encoded_args);
|
||||||
call_data
|
call_data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes a transaction for the Tycho Router using one of its supported swap methods.
|
|
||||||
///
|
|
||||||
/// # Overview
|
|
||||||
///
|
|
||||||
/// This function provides an **example implementation** of how to encode a call to the Tycho
|
|
||||||
/// Router. It handles all currently supported swap selectors such as:
|
|
||||||
/// - `singleSwap`
|
|
||||||
/// - `singleSwapPermit2`
|
|
||||||
/// - `sequentialSwap`
|
|
||||||
/// - `sequentialSwapPermit2`
|
|
||||||
/// - `splitSwap`
|
|
||||||
/// - `splitSwapPermit2`
|
|
||||||
///
|
|
||||||
/// The encoding includes handling of native asset wrapping/unwrapping, permit2 support,
|
|
||||||
/// and proper input argument formatting based on the selector string.
|
|
||||||
///
|
|
||||||
/// # ⚠️ Important Responsibility Note
|
|
||||||
///
|
|
||||||
/// This function is intended as **an illustrative example only**. **Users must implement
|
|
||||||
/// their own encoding logic** to ensure:
|
|
||||||
/// - Full control of parameters passed to the router.
|
|
||||||
/// - Proper validation and setting of critical inputs such as `minAmountOut`.
|
|
||||||
///
|
|
||||||
/// While Tycho is responsible for encoding the swap paths themselves, the input arguments
|
|
||||||
/// to the router's methods act as **guardrails** for on-chain execution safety.
|
|
||||||
/// Thus, the user must **take responsibility** for ensuring correctness of all input parameters,
|
|
||||||
/// including `minAmountOut`, `receiver`, and permit2 logic.
|
|
||||||
///
|
|
||||||
/// # Min Amount Out
|
|
||||||
///
|
|
||||||
/// The `minAmountOut` calculation used here is just an example.
|
|
||||||
/// You should ideally:
|
|
||||||
/// - Query an external service (e.g., DEX aggregators, oracle, off-chain price feed).
|
|
||||||
/// - Use your own strategy to determine an accurate and safe minimum acceptable output amount.
|
|
||||||
///
|
|
||||||
/// ⚠️ If `minAmountOut` is too low, your swap may be front-run or sandwiched, resulting in loss of
|
|
||||||
/// funds.
|
|
||||||
///
|
|
||||||
/// # Parameters
|
|
||||||
/// - `encoded_solution`: The solution already encoded by Tycho, including selector and swap path.
|
|
||||||
/// - `solution`: The high-level solution including tokens, amounts, and receiver info.
|
|
||||||
/// - `token_in_already_in_router`: Whether the input token is already present in the router.
|
|
||||||
/// - `router_address`: The address of the Tycho Router contract.
|
|
||||||
/// - `native_address`: The address used to represent the native token
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
/// A `Result<Transaction, EncodingError>` that either contains the full transaction data (to,
|
|
||||||
/// value, data), or an error if the inputs are invalid.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
/// - Returns `EncodingError::FatalError` if the selector is unsupported or required fields (e.g.,
|
|
||||||
/// permit or signature) are missing.
|
|
||||||
pub fn encode_tycho_router_call(
|
|
||||||
encoded_solution: EncodedSolution,
|
|
||||||
solution: &Solution,
|
|
||||||
token_in_already_in_router: bool,
|
|
||||||
native_address: Bytes,
|
|
||||||
) -> Result<Transaction, EncodingError> {
|
|
||||||
let (mut unwrap, mut wrap) = (false, false);
|
|
||||||
if let Some(action) = solution.native_action.clone() {
|
|
||||||
match action {
|
|
||||||
NativeAction::Wrap => wrap = true,
|
|
||||||
NativeAction::Unwrap => unwrap = true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let given_amount = biguint_to_u256(&solution.given_amount);
|
|
||||||
let min_amount_out = biguint_to_u256(&solution.checked_amount);
|
|
||||||
let given_token = bytes_to_address(&solution.given_token)?;
|
|
||||||
let checked_token = bytes_to_address(&solution.checked_token)?;
|
|
||||||
let receiver = bytes_to_address(&solution.receiver)?;
|
|
||||||
let n_tokens = U256::from(encoded_solution.n_tokens);
|
|
||||||
|
|
||||||
let method_calldata = if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("singleSwapPermit2")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
receiver,
|
|
||||||
encoded_solution
|
|
||||||
.permit
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"permit2 object must be set to use permit2".to_string(),
|
|
||||||
))?,
|
|
||||||
encoded_solution
|
|
||||||
.signature
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"Signature must be set to use permit2".to_string(),
|
|
||||||
))?
|
|
||||||
.as_bytes()
|
|
||||||
.to_vec(),
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("singleSwap")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
receiver,
|
|
||||||
!token_in_already_in_router,
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("sequentialSwapPermit2")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
receiver,
|
|
||||||
encoded_solution
|
|
||||||
.permit
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"permit2 object must be set to use permit2".to_string(),
|
|
||||||
))?,
|
|
||||||
encoded_solution
|
|
||||||
.signature
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"Signature must be set to use permit2".to_string(),
|
|
||||||
))?
|
|
||||||
.as_bytes()
|
|
||||||
.to_vec(),
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("sequentialSwap")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
receiver,
|
|
||||||
!token_in_already_in_router,
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("splitSwapPermit2")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
n_tokens,
|
|
||||||
receiver,
|
|
||||||
encoded_solution
|
|
||||||
.permit
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"permit2 object must be set to use permit2".to_string(),
|
|
||||||
))?,
|
|
||||||
encoded_solution
|
|
||||||
.signature
|
|
||||||
.ok_or(EncodingError::FatalError(
|
|
||||||
"Signature must be set to use permit2".to_string(),
|
|
||||||
))?
|
|
||||||
.as_bytes()
|
|
||||||
.to_vec(),
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else if encoded_solution
|
|
||||||
.selector
|
|
||||||
.contains("splitSwap")
|
|
||||||
{
|
|
||||||
(
|
|
||||||
given_amount,
|
|
||||||
given_token,
|
|
||||||
checked_token,
|
|
||||||
min_amount_out,
|
|
||||||
wrap,
|
|
||||||
unwrap,
|
|
||||||
n_tokens,
|
|
||||||
receiver,
|
|
||||||
!token_in_already_in_router,
|
|
||||||
encoded_solution.swaps,
|
|
||||||
)
|
|
||||||
.abi_encode()
|
|
||||||
} else {
|
|
||||||
Err(EncodingError::FatalError("Invalid selector for Tycho router".to_string()))?
|
|
||||||
};
|
|
||||||
|
|
||||||
let contract_interaction = encode_input(&encoded_solution.selector, method_calldata);
|
|
||||||
let value = if solution.given_token == native_address {
|
|
||||||
solution.given_amount.clone()
|
|
||||||
} else {
|
|
||||||
BigUint::ZERO
|
|
||||||
};
|
|
||||||
Ok(Transaction { to: encoded_solution.interacting_with, value, data: contract_interaction })
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
pub mod approvals;
|
pub mod approvals;
|
||||||
mod constants;
|
mod constants;
|
||||||
pub mod encoder_builders;
|
pub mod encoder_builders;
|
||||||
pub mod encoding_utils;
|
mod encoding_utils;
|
||||||
mod group_swaps;
|
mod group_swaps;
|
||||||
pub mod strategy_encoder;
|
pub mod strategy_encoder;
|
||||||
mod swap_encoder;
|
mod swap_encoder;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ use crate::encoding::{
|
|||||||
constants::{CALLBACK_CONSTRAINED_PROTOCOLS, IN_TRANSFER_REQUIRED_PROTOCOLS},
|
constants::{CALLBACK_CONSTRAINED_PROTOCOLS, IN_TRANSFER_REQUIRED_PROTOCOLS},
|
||||||
group_swaps::SwapGroup,
|
group_swaps::SwapGroup,
|
||||||
},
|
},
|
||||||
models::TransferType,
|
models::{TransferType, UserTransferType},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A struct that defines how the tokens will be transferred into the given pool given the solution.
|
/// A struct that defines how the tokens will be transferred into the given pool given the solution.
|
||||||
@@ -16,7 +16,7 @@ use crate::encoding::{
|
|||||||
pub struct TransferOptimization {
|
pub struct TransferOptimization {
|
||||||
native_token: Bytes,
|
native_token: Bytes,
|
||||||
wrapped_token: Bytes,
|
wrapped_token: Bytes,
|
||||||
token_in_already_in_router: bool,
|
user_transfer_type: UserTransferType,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,15 +24,10 @@ impl TransferOptimization {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
native_token: Bytes,
|
native_token: Bytes,
|
||||||
wrapped_token: Bytes,
|
wrapped_token: Bytes,
|
||||||
token_in_already_in_router: bool,
|
user_transfer_type: UserTransferType,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
TransferOptimization {
|
TransferOptimization { native_token, wrapped_token, user_transfer_type, router_address }
|
||||||
native_token,
|
|
||||||
wrapped_token,
|
|
||||||
token_in_already_in_router,
|
|
||||||
router_address,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the transfer type that should be used for the current transfer.
|
/// Returns the transfer type that should be used for the current transfer.
|
||||||
@@ -55,7 +50,7 @@ impl TransferOptimization {
|
|||||||
TransferType::Transfer
|
TransferType::Transfer
|
||||||
} else if is_first_swap {
|
} else if is_first_swap {
|
||||||
if in_transfer_required {
|
if in_transfer_required {
|
||||||
if self.token_in_already_in_router {
|
if self.user_transfer_type == UserTransferType::None {
|
||||||
// Transfer from router to pool.
|
// Transfer from router to pool.
|
||||||
TransferType::Transfer
|
TransferType::Transfer
|
||||||
} else {
|
} else {
|
||||||
@@ -64,7 +59,7 @@ impl TransferOptimization {
|
|||||||
}
|
}
|
||||||
// in transfer is not necessary for these protocols. Only make a transfer from the
|
// in transfer is not necessary for these protocols. Only make a transfer from the
|
||||||
// swapper to the router if the tokens are not already in the router
|
// swapper to the router if the tokens are not already in the router
|
||||||
} else if !self.token_in_already_in_router {
|
} else if self.user_transfer_type != UserTransferType::None {
|
||||||
// Transfer from swapper to router using.
|
// Transfer from swapper to router using.
|
||||||
TransferType::TransferFrom
|
TransferType::TransferFrom
|
||||||
} else {
|
} else {
|
||||||
@@ -146,30 +141,30 @@ mod tests {
|
|||||||
#[rstest]
|
#[rstest]
|
||||||
// First swap tests
|
// First swap tests
|
||||||
// WETH -(univ2)-> DAI we expect a transfer from the user to the protocol
|
// WETH -(univ2)-> DAI we expect a transfer from the user to the protocol
|
||||||
#[case(weth(), weth(), "uniswap_v2".to_string(), false, false,false, TransferType::TransferFrom)]
|
#[case(weth(), weth(), "uniswap_v2".to_string(), false, UserTransferType::TransferFrom,false, TransferType::TransferFrom)]
|
||||||
// Native token swap. No transfer is needed
|
// Native token swap. No transfer is needed
|
||||||
#[case(eth(), eth(), "uniswap_v2".to_string(),false, false,false, TransferType::None)]
|
#[case(eth(), eth(), "uniswap_v2".to_string(),false, UserTransferType::TransferFrom,false, TransferType::None)]
|
||||||
// ETH -(wrap)-> WETH -(univ2)-> DAI. Only a transfer from the router into the protocol is
|
// ETH -(wrap)-> WETH -(univ2)-> DAI. Only a transfer from the router into the protocol is
|
||||||
// needed
|
// needed
|
||||||
#[case(eth(), weth(), "uniswap_v2".to_string(),true, false,false,TransferType::Transfer)]
|
#[case(eth(), weth(), "uniswap_v2".to_string(),true, UserTransferType::TransferFrom,false,TransferType::Transfer)]
|
||||||
// USDC -(univ2)-> DAI and the tokens are already in the router. Only a transfer from the router
|
// USDC -(univ2)-> DAI and the tokens are already in the router. Only a transfer from the router
|
||||||
// to the protocol is needed
|
// to the protocol is needed
|
||||||
#[case(usdc(), usdc(), "uniswap_v2".to_string(),false, true,false, TransferType::Transfer)]
|
#[case(usdc(), usdc(), "uniswap_v2".to_string(),false, UserTransferType::None,false, TransferType::Transfer)]
|
||||||
// USDC -(curve)-> DAI and the tokens are already in the router. No transfer is needed
|
// USDC -(curve)-> DAI and the tokens are already in the router. No transfer is needed
|
||||||
#[case(usdc(), usdc(), "vm:curve".to_string(),false, true, false,TransferType::None)]
|
#[case(usdc(), usdc(), "vm:curve".to_string(),false, UserTransferType::None, false,TransferType::None)]
|
||||||
// other swaps tests
|
// other swaps tests
|
||||||
// tokens need to be transferred into the pool
|
// tokens need to be transferred into the pool
|
||||||
#[case(weth(), usdc(), "uniswap_v2".to_string(), false, false,false, TransferType::Transfer)]
|
#[case(weth(), usdc(), "uniswap_v2".to_string(), false, UserTransferType::TransferFrom,false, TransferType::Transfer)]
|
||||||
// tokens are already in the pool (optimization)
|
// tokens are already in the pool (optimization)
|
||||||
#[case(weth(), usdc(), "uniswap_v2".to_string(), false, false, true, TransferType::None)]
|
#[case(weth(), usdc(), "uniswap_v2".to_string(), false, UserTransferType::TransferFrom, true, TransferType::None)]
|
||||||
// tokens are already in the router and don't need a transfer
|
// tokens are already in the router and don't need a transfer
|
||||||
#[case(weth(), usdc(), "vm:curve".to_string(), false, false, false, TransferType::None)]
|
#[case(weth(), usdc(), "vm:curve".to_string(), false, UserTransferType::TransferFrom, false, TransferType::None)]
|
||||||
fn test_get_transfers(
|
fn test_get_transfers(
|
||||||
#[case] given_token: Bytes,
|
#[case] given_token: Bytes,
|
||||||
#[case] swap_token_in: Bytes,
|
#[case] swap_token_in: Bytes,
|
||||||
#[case] protocol: String,
|
#[case] protocol: String,
|
||||||
#[case] wrap: bool,
|
#[case] wrap: bool,
|
||||||
#[case] token_in_already_in_router: bool,
|
#[case] user_transfer_type: UserTransferType,
|
||||||
#[case] in_between_swap_optimization: bool,
|
#[case] in_between_swap_optimization: bool,
|
||||||
#[case] expected_transfer: TransferType,
|
#[case] expected_transfer: TransferType,
|
||||||
) {
|
) {
|
||||||
@@ -192,7 +187,7 @@ mod tests {
|
|||||||
swaps,
|
swaps,
|
||||||
};
|
};
|
||||||
let optimization =
|
let optimization =
|
||||||
TransferOptimization::new(eth(), weth(), token_in_already_in_router, router_address());
|
TransferOptimization::new(eth(), weth(), user_transfer_type, router_address());
|
||||||
let transfer = optimization.get_transfers(
|
let transfer = optimization.get_transfers(
|
||||||
swap.clone(),
|
swap.clone(),
|
||||||
given_token,
|
given_token,
|
||||||
@@ -224,7 +219,12 @@ mod tests {
|
|||||||
#[case] expected_receiver: Bytes,
|
#[case] expected_receiver: Bytes,
|
||||||
#[case] expected_optimization: bool,
|
#[case] expected_optimization: bool,
|
||||||
) {
|
) {
|
||||||
let optimization = TransferOptimization::new(eth(), weth(), false, router_address());
|
let optimization = TransferOptimization::new(
|
||||||
|
eth(),
|
||||||
|
weth(),
|
||||||
|
UserTransferType::TransferFrom,
|
||||||
|
router_address(),
|
||||||
|
);
|
||||||
|
|
||||||
let next_swap = if protocol.is_none() {
|
let next_swap = if protocol.is_none() {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ use crate::encoding::{
|
|||||||
///
|
///
|
||||||
/// # Fields
|
/// # Fields
|
||||||
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
/// * `swap_selector` - The selector of the swap function in the executor contract.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UniswapV2SwapEncoder {
|
pub struct UniswapV2SwapEncoder {
|
||||||
executor_address: String,
|
executor_address: String,
|
||||||
@@ -78,7 +77,6 @@ impl SwapEncoder for UniswapV2SwapEncoder {
|
|||||||
///
|
///
|
||||||
/// # Fields
|
/// # Fields
|
||||||
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
/// * `swap_selector` - The selector of the swap function in the executor contract.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UniswapV3SwapEncoder {
|
pub struct UniswapV3SwapEncoder {
|
||||||
executor_address: String,
|
executor_address: String,
|
||||||
@@ -140,8 +138,6 @@ impl SwapEncoder for UniswapV3SwapEncoder {
|
|||||||
///
|
///
|
||||||
/// # Fields
|
/// # Fields
|
||||||
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
/// * `swap_selector` - The selector of the swap function in the executor contract.
|
|
||||||
/// * `callback_selector` - The selector of the callback function in the executor contract.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UniswapV4SwapEncoder {
|
pub struct UniswapV4SwapEncoder {
|
||||||
executor_address: String,
|
executor_address: String,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
use alloy_primitives::PrimitiveSignature as Signature;
|
use clap::ValueEnum;
|
||||||
use hex;
|
use hex;
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -7,9 +7,32 @@ use tycho_common::{
|
|||||||
Bytes,
|
Bytes,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::encoding::{
|
use crate::encoding::{errors::EncodingError, serde_primitives::biguint_string};
|
||||||
errors::EncodingError, evm::approvals::permit2::PermitSingle, serde_primitives::biguint_string,
|
|
||||||
};
|
/// Specifies the method for transferring user funds into Tycho execution.
|
||||||
|
///
|
||||||
|
/// Options:
|
||||||
|
///
|
||||||
|
/// - `TransferFromPermit2`: Use Permit2 for token transfer.
|
||||||
|
/// - You must manually approve the Permit2 contract and sign the permit object externally
|
||||||
|
/// (outside `tycho-execution`).
|
||||||
|
///
|
||||||
|
/// - `TransferFrom`: Use standard ERC-20 approval and `transferFrom`.
|
||||||
|
/// - You must approve the Tycho Router contract to spend your tokens via standard `approve()`
|
||||||
|
/// calls.
|
||||||
|
///
|
||||||
|
/// - `None`: No transfer will be performed.
|
||||||
|
/// - Assumes the tokens are already present in the Tycho Router.
|
||||||
|
/// - **Warning**: This is an advanced mode. Ensure your logic guarantees that the tokens are
|
||||||
|
/// already in the router at the time of execution.
|
||||||
|
/// - The Tycho router is **not** designed to safely hold tokens. If tokens are not transferred
|
||||||
|
/// and used in the **same transaction**, they will be permanently lost.
|
||||||
|
#[derive(Clone, Debug, PartialEq, ValueEnum)]
|
||||||
|
pub enum UserTransferType {
|
||||||
|
TransferFromPermit2,
|
||||||
|
TransferFrom,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents a solution containing details describing an order, and instructions for filling
|
/// Represents a solution containing details describing an order, and instructions for filling
|
||||||
/// the order.
|
/// the order.
|
||||||
@@ -82,7 +105,6 @@ impl Swap {
|
|||||||
/// * `to`: Address of the contract to call with the calldata
|
/// * `to`: Address of the contract to call with the calldata
|
||||||
/// * `value`: Native token value to be sent with the transaction.
|
/// * `value`: Native token value to be sent with the transaction.
|
||||||
/// * `data`: Encoded calldata for the transaction.
|
/// * `data`: Encoded calldata for the transaction.
|
||||||
/// * `selector`: Only relevant for direct executions. The selector of the function to be called.
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
pub to: Bytes,
|
pub to: Bytes,
|
||||||
@@ -95,18 +117,58 @@ pub struct Transaction {
|
|||||||
/// # Fields
|
/// # Fields
|
||||||
/// * `swaps`: Encoded swaps to be executed.
|
/// * `swaps`: Encoded swaps to be executed.
|
||||||
/// * `interacting_with`: Address of the contract to be called.
|
/// * `interacting_with`: Address of the contract to be called.
|
||||||
/// * `selector`: The selector of the function to be called.
|
/// * `function_signature`: The signature of the function to be called.
|
||||||
/// * `n_tokens`: Number of tokens in the swap.
|
/// * `n_tokens`: Number of tokens in the swap.
|
||||||
/// * `permit`: Optional permit for the swap (if permit2 is enabled).
|
/// * `permit`: Optional permit for the swap (if permit2 is enabled).
|
||||||
/// * `signature`: Optional signature for the swap (if permit2 is enabled).
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct EncodedSolution {
|
pub struct EncodedSolution {
|
||||||
pub swaps: Vec<u8>,
|
pub swaps: Vec<u8>,
|
||||||
pub interacting_with: Bytes,
|
pub interacting_with: Bytes,
|
||||||
pub selector: String,
|
pub function_signature: String,
|
||||||
pub n_tokens: usize,
|
pub n_tokens: usize,
|
||||||
pub permit: Option<PermitSingle>,
|
pub permit: Option<PermitSingle>,
|
||||||
pub signature: Option<Signature>,
|
}
|
||||||
|
|
||||||
|
/// Represents a single permit for permit2.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `details`: The details of the permit, such as token, amount, expiration, and nonce.
|
||||||
|
/// * `spender`: The address authorized to spend the tokens.
|
||||||
|
/// * `sig_deadline`: The deadline (as a timestamp) for the permit signature
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct PermitSingle {
|
||||||
|
pub details: PermitDetails,
|
||||||
|
pub spender: Bytes,
|
||||||
|
pub sig_deadline: BigUint,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Details of a permit.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `token`: The token address for which the permit is granted.
|
||||||
|
/// * `amount`: The amount of tokens approved for spending.
|
||||||
|
/// * `expiration`: The expiration time (as a timestamp) for the permit.
|
||||||
|
/// * `nonce`: The unique nonce to prevent replay attacks.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct PermitDetails {
|
||||||
|
pub token: Bytes,
|
||||||
|
pub amount: BigUint,
|
||||||
|
pub expiration: BigUint,
|
||||||
|
pub nonce: BigUint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for PermitSingle {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.details == other.details && self.spender == other.spender
|
||||||
|
// sig_deadline is intentionally ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for PermitDetails {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.token == other.token && self.amount == other.amount && self.nonce == other.nonce
|
||||||
|
// expiration is intentionally ignored
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents necessary attributes for encoding an order.
|
/// Represents necessary attributes for encoding an order.
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ use crate::encoding::{
|
|||||||
/// outer function call arguments themselves** and verify that they enforce correct and secure
|
/// outer function call arguments themselves** and verify that they enforce correct and secure
|
||||||
/// behavior.
|
/// behavior.
|
||||||
pub trait TychoEncoder {
|
pub trait TychoEncoder {
|
||||||
/// Encodes a list of [`Solution`]s into [`EncodedSolution`]s, which include the selector and
|
/// Encodes a list of [`Solution`]s into [`EncodedSolution`]s, which include the function
|
||||||
/// internal swap call data.
|
/// signature and internal swap call data.
|
||||||
///
|
///
|
||||||
/// This method gives users maximum flexibility and control. It **does not** produce full
|
/// This method gives users maximum flexibility and control. It **does not** produce full
|
||||||
/// transaction objects. Users are responsible for:
|
/// transaction objects. Users are responsible for:
|
||||||
@@ -36,7 +36,7 @@ pub trait TychoEncoder {
|
|||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// A vector of encoded solutions, each containing:
|
/// A vector of encoded solutions, each containing:
|
||||||
/// - The Tycho method selector
|
/// - The Tycho method function signature
|
||||||
/// - The encoded swap path
|
/// - The encoded swap path
|
||||||
/// - Additional metadata (e.g., permit2 information)
|
/// - Additional metadata (e.g., permit2 information)
|
||||||
///
|
///
|
||||||
@@ -61,6 +61,7 @@ pub trait TychoEncoder {
|
|||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// A vector of fully constructed [`Transaction`]s that can be submitted to a node or bundler.
|
/// A vector of fully constructed [`Transaction`]s that can be submitted to a node or bundler.
|
||||||
|
#[deprecated(note = "Please use `encode_solutions` instead")]
|
||||||
fn encode_full_calldata(
|
fn encode_full_calldata(
|
||||||
&self,
|
&self,
|
||||||
solutions: Vec<Solution>,
|
solutions: Vec<Solution>,
|
||||||
|
|||||||
Reference in New Issue
Block a user