feat: Separate encoding swaps from encoding txs

This way the user is responsible for encoding the Tycho Router method inputs that are used as guardrails in execution.

Interface changes:
- Create EncodedSolution
- StrategyEncoder
  - don't need to know have permit2 or token_in_already_in_router as attributes anymore
  - encode_strategy returns EncodedSolution now (no method encoding done here now)
- TychoEncoder
  - add encode_solution() method. This is the recommended method for users
  - needs to have permit2, token_in_already_in_router and router_address as attributes
  - permit creation is made in the router now

Also:
- create encoding_utils.rs
- update all tests

Took 2 hours 42 minutes


Took 3 minutes

Took 13 minutes
This commit is contained in:
Diana Carvalho
2025-05-21 13:33:46 +01:00
parent 6a6955d31d
commit 4e8c6ddc8c
12 changed files with 869 additions and 420 deletions

View File

@@ -10,7 +10,7 @@ use alloy::{
providers::{ProviderBuilder, RootProvider},
transports::BoxTransport,
};
use alloy_primitives::{aliases::U24, keccak256, Address, FixedBytes, Keccak256, U256, U8};
use alloy_primitives::{aliases::U24, Address, U256, U8};
use alloy_sol_types::SolValue;
use num_bigint::BigUint;
use once_cell::sync::Lazy;
@@ -40,28 +40,6 @@ pub fn biguint_to_u256(value: &BigUint) -> U256 {
U256::from_be_slice(&bytes)
}
/// 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> {
let mut hasher = Keccak256::new();
hasher.update(selector.as_bytes());
let selector_bytes = &hasher.finalize()[..4];
let mut call_data = selector_bytes.to_vec();
// Remove extra prefix if present (32 bytes for dynamic data)
// Alloy encoding is including a prefix for dynamic data indicating the offset or length
// but at this point we don't want that
if encoded_args.len() > 32 &&
encoded_args[..32] ==
[0u8; 31]
.into_iter()
.chain([32].to_vec())
.collect::<Vec<u8>>()
{
encoded_args = encoded_args[32..].to_vec();
}
call_data.extend(encoded_args);
call_data
}
/// Converts a decimal to a `U24` value. The percentage is a `f64` value between 0 and 1.
/// MAX_UINT24 corresponds to 100%.
pub fn percentage_to_uint24(decimal: f64) -> U24 {
@@ -116,12 +94,6 @@ pub fn pad_to_fixed_size<const N: usize>(input: &[u8]) -> Result<[u8; N], Encodi
Ok(padded)
}
/// Encodes a function selector to a fixed size array of 4 bytes.
pub fn encode_function_selector(selector: &str) -> FixedBytes<4> {
let hash = keccak256(selector.as_bytes());
FixedBytes::<4>::from([hash[0], hash[1], hash[2], hash[3]])
}
/// Extracts a static attribute from a swap.
pub fn get_static_attribute(swap: &Swap, attribute_name: &str) -> Result<Vec<u8>, EncodingError> {
Ok(swap