chore: merge main
This commit is contained in:
@@ -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)
|
## [0.119.0](https://github.com/propeller-heads/tycho-execution/compare/0.118.0...0.119.0) (2025-08-21)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4659,7 +4659,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.119.0"
|
version = "0.120.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy",
|
"alloy",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tycho-execution"
|
name = "tycho-execution"
|
||||||
version = "0.119.0"
|
version = "0.120.0"
|
||||||
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"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"vm:maverick_v2": "0xF35e3F5F205769B41508A18787b62A21bC80200B",
|
"vm:maverick_v2": "0xF35e3F5F205769B41508A18787b62A21bC80200B",
|
||||||
"vm:balancer_v3": "0xec5cE4bF6FbcB7bB0148652c92a4AEC8c1d474Ec",
|
"vm:balancer_v3": "0xec5cE4bF6FbcB7bB0148652c92a4AEC8c1d474Ec",
|
||||||
"rfq:bebop": "0xFE42BFb115eD9671011cA52BDD23A52A2e077a7c",
|
"rfq:bebop": "0xFE42BFb115eD9671011cA52BDD23A52A2e077a7c",
|
||||||
"rfq:hashflow": "0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f"
|
"rfq:hashflow": "0x19e49Db786c87F4e46B10aFb21c0C06d34270f98"
|
||||||
},
|
},
|
||||||
"base": {
|
"base": {
|
||||||
"uniswap_v2": "0xF744EBfaA580cF3fFc25aD046E92BD8B770a0700",
|
"uniswap_v2": "0xF744EBfaA580cF3fFc25aD046E92BD8B770a0700",
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ const executors_to_deploy = {
|
|||||||
exchange: "BebopExecutor",
|
exchange: "BebopExecutor",
|
||||||
args: ["0xbbbbbBB520d69a9775E85b458C58c648259FAD5F", "0x000000000022D473030F116dDEE9F6B43aC78BA3"]
|
args: ["0xbbbbbBB520d69a9775E85b458C58c648259FAD5F", "0x000000000022D473030F116dDEE9F6B43aC78BA3"]
|
||||||
},
|
},
|
||||||
|
// Args: Hashflow router, Permit2
|
||||||
|
{
|
||||||
|
exchange: "HashflowExecutor",
|
||||||
|
args: ["0x55084eE0fEf03f14a305cd24286359A35D735151", "0x000000000022D473030F116dDEE9F6B43aC78BA3"]
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"base": [
|
"base": [
|
||||||
// Args: Factory, Pool Init Code Hash, Permit2, Fee BPS
|
// Args: Factory, Pool Init Code Hash, Permit2, Fee BPS
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
use std::{collections::HashMap, str::FromStr, sync::Arc};
|
use std::{collections::HashMap, str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use alloy::{
|
use alloy::{
|
||||||
primitives::{Address, Bytes as AlloyBytes, U256, U8},
|
primitives::{Address, Bytes as AlloyBytes, U8},
|
||||||
sol_types::SolValue,
|
sol_types::SolValue,
|
||||||
};
|
};
|
||||||
use serde_json::from_str;
|
use serde_json::from_str;
|
||||||
@@ -751,90 +751,74 @@ impl SwapEncoder for BebopSwapEncoder {
|
|||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let (partial_fill_offset, original_filled_taker_amount, bebop_calldata) =
|
let protocol_state = swap
|
||||||
if let Some(state) = &swap.protocol_state {
|
.protocol_state
|
||||||
let indicatively_priced_state = state
|
.as_ref()
|
||||||
.as_indicatively_priced()
|
.ok_or_else(|| {
|
||||||
.map_err(|e| {
|
EncodingError::FatalError("protocol_state is required for Bebop".to_string())
|
||||||
EncodingError::FatalError(format!("State is not indicatively priced {e}"))
|
})?;
|
||||||
})?;
|
let (partial_fill_offset, original_filled_taker_amount, bebop_calldata) = {
|
||||||
let estimated_amount_in =
|
let indicatively_priced_state = protocol_state
|
||||||
swap.estimated_amount_in
|
.as_indicatively_priced()
|
||||||
.clone()
|
.map_err(|e| {
|
||||||
.ok_or(EncodingError::FatalError(
|
EncodingError::FatalError(format!("State is not indicatively priced {e}"))
|
||||||
"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 bebop_calldata = signed_quote
|
let estimated_amount_in =
|
||||||
.quote_attributes
|
swap.estimated_amount_in
|
||||||
.get("calldata")
|
.clone()
|
||||||
.ok_or(EncodingError::FatalError(
|
.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
|
// Bebop uses another address for the native token than the zero address
|
||||||
.quote_attributes
|
let mut token_in = swap.token_in.clone();
|
||||||
.get("partial_fill_offset")
|
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(
|
.ok_or(EncodingError::FatalError(
|
||||||
"Bebop quote must have a partial_fill_offset attribute".to_string(),
|
"The router address is needed to perform a Bebop swap".to_string(),
|
||||||
))?;
|
))?,
|
||||||
let original_filled_taker_amount = biguint_to_u256(&signed_quote.amount_out);
|
receiver: encoding_context.receiver.clone(),
|
||||||
(
|
|
||||||
// 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)
|
|
||||||
};
|
};
|
||||||
|
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)?;
|
let receiver = bytes_to_address(&encoding_context.receiver)?;
|
||||||
|
|
||||||
// Encode packed data for the executor
|
// 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]
|
#[test]
|
||||||
fn test_encode_bebop_single_with_protocol_state() {
|
fn test_encode_bebop_single_with_protocol_state() {
|
||||||
// 3000 USDC -> 1 WETH using a mocked RFQ state to get a quote
|
// 3000 USDC -> 1 WETH using a mocked RFQ state to get a quote
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ use tycho_execution::encoding::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
alice_address, build_bebop_calldata, encoding::encode_tycho_router_call, eth, eth_chain,
|
alice_address, encoding::encode_tycho_router_call, eth, eth_chain, get_signer,
|
||||||
get_signer, get_tycho_router_encoder, ondo, pepe, usdc, wbtc, weth,
|
get_tycho_router_encoder, ondo, pepe, usdc, wbtc, weth,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -609,11 +609,23 @@ fn test_single_encoding_strategy_bebop() {
|
|||||||
let token_out = ondo();
|
let token_out = ondo();
|
||||||
let amount_in = BigUint::from_str("200000000").unwrap(); // 200 USDC
|
let amount_in = BigUint::from_str("200000000").unwrap(); // 200 USDC
|
||||||
let amount_out = BigUint::from_str("194477331556159832309").unwrap(); // 203.8 ONDO
|
let amount_out = BigUint::from_str("194477331556159832309").unwrap(); // 203.8 ONDO
|
||||||
let partial_fill_offset = 12;
|
|
||||||
|
|
||||||
let calldata = Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
|
let partial_fill_offset = 12u64;
|
||||||
let user_data =
|
let bebop_calldata = Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
|
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 {
|
let bebop_component = ProtocolComponent {
|
||||||
id: String::from("bebop-rfq"),
|
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())
|
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();
|
.build();
|
||||||
|
|
||||||
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
||||||
@@ -670,11 +683,23 @@ fn test_single_encoding_strategy_bebop_aggregate() {
|
|||||||
let token_out = ondo();
|
let token_out = ondo();
|
||||||
let amount_in = BigUint::from_str("20000000000").unwrap(); // 20k USDC
|
let amount_in = BigUint::from_str("20000000000").unwrap(); // 20k USDC
|
||||||
let amount_out = BigUint::from_str("18699321819466078474202").unwrap(); // 203.8 ONDO
|
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 bebop_calldata = Bytes::from_str("0xa2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
let user_data =
|
let bebop_state = MockRFQState {
|
||||||
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
|
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 {
|
let bebop_component = ProtocolComponent {
|
||||||
id: String::from("bebop-rfq"),
|
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())
|
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();
|
.build();
|
||||||
|
|
||||||
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
||||||
|
|||||||
Reference in New Issue
Block a user