chore: merge main

This commit is contained in:
TAMARA LIPOWSKI
2025-08-27 23:27:58 -04:00
8 changed files with 132 additions and 240 deletions

View File

@@ -1,3 +1,10 @@
## [0.120.0](https://github.com/propeller-heads/tycho-execution/compare/0.119.0...0.120.0) (2025-08-27)
### Features
* Deploy new hashflow router ([eac45fa](https://github.com/propeller-heads/tycho-execution/commit/eac45faf5a56a50dacff374da7c3701e5a1d3f33))
## [0.119.0](https://github.com/propeller-heads/tycho-execution/compare/0.118.0...0.119.0) (2025-08-21)

2
Cargo.lock generated
View File

@@ -4659,7 +4659,7 @@ dependencies = [
[[package]]
name = "tycho-execution"
version = "0.119.0"
version = "0.120.0"
dependencies = [
"alloy",
"async-trait",

View File

@@ -1,6 +1,6 @@
[package]
name = "tycho-execution"
version = "0.119.0"
version = "0.120.0"
edition = "2021"
description = "Provides tools for encoding and executing swaps against Tycho router and protocol executors."
repository = "https://github.com/propeller-heads/tycho-execution"

View File

@@ -13,7 +13,7 @@
"vm:maverick_v2": "0xF35e3F5F205769B41508A18787b62A21bC80200B",
"vm:balancer_v3": "0xec5cE4bF6FbcB7bB0148652c92a4AEC8c1d474Ec",
"rfq:bebop": "0xFE42BFb115eD9671011cA52BDD23A52A2e077a7c",
"rfq:hashflow": "0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f"
"rfq:hashflow": "0x19e49Db786c87F4e46B10aFb21c0C06d34270f98"
},
"base": {
"uniswap_v2": "0xF744EBfaA580cF3fFc25aD046E92BD8B770a0700",

View File

@@ -86,6 +86,11 @@ const executors_to_deploy = {
exchange: "BebopExecutor",
args: ["0xbbbbbBB520d69a9775E85b458C58c648259FAD5F", "0x000000000022D473030F116dDEE9F6B43aC78BA3"]
},
// Args: Hashflow router, Permit2
{
exchange: "HashflowExecutor",
args: ["0x55084eE0fEf03f14a305cd24286359A35D735151", "0x000000000022D473030F116dDEE9F6B43aC78BA3"]
},
],
"base": [
// Args: Factory, Pool Init Code Hash, Permit2, Fee BPS

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
use std::{collections::HashMap, str::FromStr, sync::Arc};
use alloy::{
primitives::{Address, Bytes as AlloyBytes, U256, U8},
primitives::{Address, Bytes as AlloyBytes, U8},
sol_types::SolValue,
};
use serde_json::from_str;
@@ -751,90 +751,74 @@ impl SwapEncoder for BebopSwapEncoder {
)?
};
let (partial_fill_offset, original_filled_taker_amount, bebop_calldata) =
if let Some(state) = &swap.protocol_state {
let indicatively_priced_state = state
.as_indicatively_priced()
.map_err(|e| {
EncodingError::FatalError(format!("State is not indicatively priced {e}"))
})?;
let estimated_amount_in =
swap.estimated_amount_in
.clone()
.ok_or(EncodingError::FatalError(
"Estimated amount in is mandatory for a Bebop swap".to_string(),
))?;
// Bebop uses another address for the native token than the zero address
let mut token_in = swap.token_in.clone();
if swap.token_in == self.native_token_address {
token_in = self.native_token_bebop_address.clone()
}
let mut token_out = swap.token_out.clone();
if swap.token_out == self.native_token_address {
token_out = self.native_token_bebop_address.clone()
}
let params = GetAmountOutParams {
amount_in: estimated_amount_in,
token_in,
token_out,
sender: encoding_context
.router_address
.clone()
.ok_or(EncodingError::FatalError(
"The router address is needed to perform a Bebop swap".to_string(),
))?,
receiver: encoding_context.receiver.clone(),
};
let signed_quote = block_in_place(|| {
self.runtime_handle.block_on(async {
indicatively_priced_state
.request_signed_quote(params)
.await
})
let protocol_state = swap
.protocol_state
.as_ref()
.ok_or_else(|| {
EncodingError::FatalError("protocol_state is required for Bebop".to_string())
})?;
let (partial_fill_offset, original_filled_taker_amount, bebop_calldata) = {
let indicatively_priced_state = protocol_state
.as_indicatively_priced()
.map_err(|e| {
EncodingError::FatalError(format!("State is not indicatively priced {e}"))
})?;
let bebop_calldata = signed_quote
.quote_attributes
.get("calldata")
let estimated_amount_in =
swap.estimated_amount_in
.clone()
.ok_or(EncodingError::FatalError(
"Bebop quote must have a calldata attribute".to_string(),
"Estimated amount in is mandatory for a Bebop swap".to_string(),
))?;
let partial_fill_offset = signed_quote
.quote_attributes
.get("partial_fill_offset")
// Bebop uses another address for the native token than the zero address
let mut token_in = swap.token_in.clone();
if swap.token_in == self.native_token_address {
token_in = self.native_token_bebop_address.clone()
}
let mut token_out = swap.token_out.clone();
if swap.token_out == self.native_token_address {
token_out = self.native_token_bebop_address.clone()
}
let params = GetAmountOutParams {
amount_in: estimated_amount_in,
token_in,
token_out,
sender: encoding_context
.router_address
.clone()
.ok_or(EncodingError::FatalError(
"Bebop quote must have a partial_fill_offset attribute".to_string(),
))?;
let original_filled_taker_amount = biguint_to_u256(&signed_quote.amount_out);
(
// we are only interested in the last byte to get a u8
partial_fill_offset[partial_fill_offset.len() - 1],
original_filled_taker_amount,
bebop_calldata.to_vec(),
)
} else {
// The user data required for Bebop is
// partial_fill_offset (u8) | original_taker_amount (U256) | calldata (bytes
// (selector ABI encoded params))
let user_data = swap.user_data.clone().ok_or_else(|| {
EncodingError::InvalidInput(
"Bebop swaps require user_data with calldata".to_string(),
)
})?;
if user_data.len() < 37 {
return Err(EncodingError::InvalidInput(
"User data too short to contain offset and Bebop calldata".to_string(),
));
}
let partial_fill_offset = user_data[0];
let original_filled_taker_amount = U256::from_be_slice(&user_data[1..33]);
// The calldata should be for either swapSingle or swapAggregate
let bebop_calldata = user_data[33..].to_vec();
(partial_fill_offset, original_filled_taker_amount, bebop_calldata)
"The router address is needed to perform a Bebop swap".to_string(),
))?,
receiver: encoding_context.receiver.clone(),
};
let signed_quote = block_in_place(|| {
self.runtime_handle.block_on(async {
indicatively_priced_state
.request_signed_quote(params)
.await
})
})?;
let bebop_calldata = signed_quote
.quote_attributes
.get("calldata")
.ok_or(EncodingError::FatalError(
"Bebop quote must have a calldata attribute".to_string(),
))?;
let partial_fill_offset = signed_quote
.quote_attributes
.get("partial_fill_offset")
.ok_or(EncodingError::FatalError(
"Bebop quote must have a partial_fill_offset attribute".to_string(),
))?;
let original_filled_taker_amount = biguint_to_u256(&signed_quote.amount_out);
(
// we are only interested in the last byte to get a u8
partial_fill_offset[partial_fill_offset.len() - 1],
original_filled_taker_amount,
bebop_calldata.to_vec(),
)
};
let receiver = bytes_to_address(&encoding_context.receiver)?;
// Encode packed data for the executor
@@ -2007,136 +1991,6 @@ mod tests {
])
}
#[test]
fn test_encode_bebop_single_with_user_data() {
// 200 USDC -> ONDO
let bebop_calldata= Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
let original_taker_amount = U256::from_str("200000000").unwrap();
// partialFillOffset 12 for swapSingle
let mut user_data = vec![12u8];
user_data.extend_from_slice(&original_taker_amount.to_be_bytes::<32>());
user_data.extend_from_slice(&bebop_calldata);
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),
protocol_system: String::from("rfq:bebop"),
static_attributes: HashMap::new(),
..Default::default()
};
let token_in = Bytes::from("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"); // USDC
let token_out = Bytes::from("0xfAbA6f8e4a5E8Ab82F62fe7C39859FA577269BE3"); // ONDO
let swap = SwapBuilder::new(bebop_component, token_in.clone(), token_out.clone())
.user_data(Bytes::from(user_data))
.build();
let encoding_context = EncodingContext {
receiver: Bytes::from("0xc5564C13A157E6240659fb81882A28091add8670"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::Transfer,
};
let encoder = BebopSwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
Chain::Ethereum,
Some(bebop_config()),
)
.unwrap();
let encoded_swap = encoder
.encode_swap(&swap, &encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
let expected_swap = String::from(concat!(
// token in
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
// token out
"faba6f8e4a5e8ab82f62fe7c39859fa577269be3",
// transfer type
"01",
// partiall filled offset
"0c",
// original taker amount
"000000000000000000000000000000000000000000000000000000000bebc200",
// approval needed
"01",
//receiver,
"c5564c13a157e6240659fb81882a28091add8670",
));
assert_eq!(hex_swap, expected_swap + &bebop_calldata.to_string()[2..]);
}
#[test]
fn test_encode_bebop_aggregate_with_user_data() {
// 20k USDC -> ONDO
let bebop_calldata= Bytes::from_str("0xa2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000").unwrap();
let original_taker_amount = U256::from_str("20000000000").unwrap();
// partialFillOffset is 2 for swapAggregate
let mut user_data = vec![2u8];
user_data.extend_from_slice(&original_taker_amount.to_be_bytes::<32>());
user_data.extend_from_slice(&bebop_calldata);
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),
protocol_system: String::from("rfq:bebop"),
static_attributes: HashMap::new(),
..Default::default()
};
let token_in = Bytes::from("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"); // USDC
let token_out = Bytes::from("0xfAbA6f8e4a5E8Ab82F62fe7C39859FA577269BE3"); // ONDO
let swap = SwapBuilder::new(bebop_component, token_in.clone(), token_out.clone())
.user_data(Bytes::from(user_data))
.build();
let encoding_context = EncodingContext {
receiver: Bytes::from("0xc5564C13A157E6240659fb81882A28091add8670"),
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::Transfer,
};
let encoder = BebopSwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
Chain::Ethereum,
Some(bebop_config()),
)
.unwrap();
let encoded_swap = encoder
.encode_swap(&swap, &encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
let expected_swap = String::from(concat!(
// token in
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
// token out
"faba6f8e4a5e8ab82f62fe7c39859fa577269be3",
// transfer type
"01",
// partiall filled offset
"02",
// original taker amount
"00000000000000000000000000000000000000000000000000000004a817c800",
// approval needed
"01",
//receiver,
"c5564c13a157e6240659fb81882a28091add8670",
));
assert_eq!(hex_swap, expected_swap + &bebop_calldata.to_string()[2..]);
}
#[test]
fn test_encode_bebop_single_with_protocol_state() {
// 3000 USDC -> 1 WETH using a mocked RFQ state to get a quote

View File

@@ -13,8 +13,8 @@ use tycho_execution::encoding::{
};
use crate::common::{
alice_address, build_bebop_calldata, encoding::encode_tycho_router_call, eth, eth_chain,
get_signer, get_tycho_router_encoder, ondo, pepe, usdc, wbtc, weth,
alice_address, encoding::encode_tycho_router_call, eth, eth_chain, get_signer,
get_tycho_router_encoder, ondo, pepe, usdc, wbtc, weth,
};
#[test]
@@ -609,11 +609,23 @@ fn test_single_encoding_strategy_bebop() {
let token_out = ondo();
let amount_in = BigUint::from_str("200000000").unwrap(); // 200 USDC
let amount_out = BigUint::from_str("194477331556159832309").unwrap(); // 203.8 ONDO
let partial_fill_offset = 12;
let calldata = Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
let user_data =
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
let partial_fill_offset = 12u64;
let bebop_calldata = Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
let bebop_state = MockRFQState {
quote_amount_out: amount_out.clone(),
quote_data: HashMap::from([
("calldata".to_string(), bebop_calldata),
(
"partial_fill_offset".to_string(),
Bytes::from(
partial_fill_offset
.to_be_bytes()
.to_vec(),
),
),
]),
};
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),
@@ -623,7 +635,8 @@ fn test_single_encoding_strategy_bebop() {
};
let swap = SwapBuilder::new(bebop_component, token_in.clone(), token_out.clone())
.user_data(user_data)
.estimated_amount_in(BigUint::from_str("200000000").unwrap())
.protocol_state(Arc::new(bebop_state))
.build();
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
@@ -670,11 +683,23 @@ fn test_single_encoding_strategy_bebop_aggregate() {
let token_out = ondo();
let amount_in = BigUint::from_str("20000000000").unwrap(); // 20k USDC
let amount_out = BigUint::from_str("18699321819466078474202").unwrap(); // 203.8 ONDO
let partial_fill_offset = 2;
let partial_fill_offset = 2u64;
let calldata = Bytes::from_str("0xa2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000").unwrap();
let user_data =
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
let bebop_calldata = Bytes::from_str("0xa2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000").unwrap();
let bebop_state = MockRFQState {
quote_amount_out: amount_out.clone(),
quote_data: HashMap::from([
("calldata".to_string(), bebop_calldata),
(
"partial_fill_offset".to_string(),
Bytes::from(
partial_fill_offset
.to_be_bytes()
.to_vec(),
),
),
]),
};
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),
@@ -684,7 +709,8 @@ fn test_single_encoding_strategy_bebop_aggregate() {
};
let swap = SwapBuilder::new(bebop_component, token_in.clone(), token_out.clone())
.user_data(user_data)
.estimated_amount_in(BigUint::from_str("20000000000").unwrap())
.protocol_state(Arc::new(bebop_state))
.build();
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);