fix(Bebop): Fix encoding and tests

Misc: Fix revert condition in UniswapXFiller

Took 1 hour 20 minutes
This commit is contained in:
Diana Carvalho
2025-08-13 15:11:43 +01:00
parent 7024da395d
commit e79347842f
13 changed files with 96 additions and 791 deletions

View File

@@ -3,7 +3,10 @@ pub mod encoding;
use std::str::FromStr;
use alloy::{primitives::B256, signers::local::PrivateKeySigner};
use alloy::{
primitives::{B256, U256},
signers::local::PrivateKeySigner,
};
use tycho_common::{models::Chain, Bytes};
use tycho_execution::encoding::{
evm::encoder_builders::TychoRouterEncoderBuilder, models::UserTransferType,
@@ -70,9 +73,16 @@ pub fn get_tycho_router_encoder(user_transfer_type: UserTransferType) -> Box<dyn
}
/// Builds the complete Bebop calldata in the format expected by the encoder
/// Returns: partialFillOffset (1 byte) | bebop_calldata (selector + ABI encoded params)
pub fn build_bebop_calldata(calldata: &[u8], partial_fill_offset: u8) -> Bytes {
let mut user_data = vec![partial_fill_offset];
/// Returns: [ partial_fill_offset (u8) | original_taker_amount (U256) | calldata (bytes (selector +
/// ABI encoded params)) ]
pub fn build_bebop_calldata(
calldata: &[u8],
partial_fill_offset: u8,
original_taker_amount: U256,
) -> Bytes {
let mut user_data = Vec::with_capacity(1 + 32 + calldata.len());
user_data.push(partial_fill_offset);
user_data.extend_from_slice(&original_taker_amount.to_be_bytes::<32>());
user_data.extend_from_slice(calldata);
Bytes::from(user_data)

View File

@@ -593,143 +593,3 @@ fn test_uniswap_v3_balancer_v3() {
let hex_calldata = encode(&calldata);
write_calldata_to_file("test_uniswap_v3_balancer_v3", hex_calldata.as_str());
}
// #[test]
// fn test_uniswap_v3_bebop() {
// // Note: This test does not assert anything. It is only used to obtain
// // integration test data for our router solidity test.
// //
// // Performs a sequential swap from WETH to ONDO through USDC using USV3 and
// // Bebop RFQ
// //
// // WETH ───(USV3)──> USDC ───(Bebop RFQ)──> ONDO
//
// let weth = weth();
// let usdc = usdc();
// let ondo = ondo();
//
// // First swap: WETH -> USDC via UniswapV3
// let swap_weth_usdc = Swap {
// component: ProtocolComponent {
// id: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640".to_string(), /* WETH-USDC USV3 Pool
// * 0.05% */
// protocol_system: "uniswap_v3".to_string(),
// static_attributes: {
// let mut attrs = HashMap::new();
// attrs
// .insert("fee".to_string(),
// Bytes::from(BigInt::from(500).to_signed_bytes_be())); attrs
// },
// ..Default::default()
// },
// token_in: weth.clone(),
// token_out: usdc.clone(),
// split: 0f64,
// user_data: None,
// protocol_state: None,
// };
//
// // Second swap: USDC -> ONDO via Bebop RFQ using real order data
// // Using the same real order from the mainnet transaction at block 22667985
// let expiry = 1749483840u64; // Real expiry from the order
// let taker_address = Address::from_str("0xc5564C13A157E6240659fb81882A28091add8670").unwrap();
// // Real taker let maker_address =
// Address::from_str("0xCe79b081c0c924cb67848723ed3057234d10FC6b").unwrap(); // Real maker
// let maker_nonce = 1749483765992417u64; // Real nonce
// let taker_token = Address::from_str(&usdc.to_string()).unwrap();
// let maker_token = Address::from_str(&ondo.to_string()).unwrap();
// // Using the real order amounts
// let taker_amount = U256::from_str("200000000").unwrap(); // 200 USDC (6 decimals)
// let maker_amount = U256::from_str("237212396774431060000").unwrap(); // 237.21 ONDO (18
// decimals) let receiver =
// Address::from_str("0xc5564C13A157E6240659fb81882A28091add8670").unwrap(); // Real receiver
// let packed_commands = U256::ZERO;
// let flags = U256::from_str(
// "51915842898789398998206002334703507894664330885127600393944965515693155942400",
// )
// .unwrap(); // Real flags
//
// // Encode using standard ABI encoding (not packed)
// let quote_data = (
// expiry,
// taker_address,
// maker_address,
// maker_nonce,
// taker_token,
// maker_token,
// taker_amount,
// maker_amount,
// receiver,
// packed_commands,
// flags,
// )
// .abi_encode();
//
// // Real signature from the order
// let signature =
// hex::decode("
// eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c"
// ).unwrap();
//
// // Build user_data with the quote and signature
// let user_data = build_bebop_calldata(
// BebopOrderType::Single,
// U256::from(0), // 0 means fill entire order
// &quote_data,
// vec![(signature, 0)], // ETH_SIGN signature type (0)
// );
//
// let bebop_component = ProtocolComponent {
// id: String::from("bebop-rfq"),
// protocol_system: String::from("rfq:bebop"),
// static_attributes: HashMap::new(), // No static attributes needed
// ..Default::default()
// };
//
// let swap_usdc_ondo = Swap {
// component: bebop_component,
// token_in: usdc.clone(),
// token_out: ondo.clone(),
// split: 0f64,
// user_data: Some(user_data),
// protocol_state: None,
// };
//
// let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
//
// let solution = Solution {
// exact_out: false,
// given_token: weth,
// // Use ~0.099 WETH to get approximately 200 USDC from UniswapV3
// // This should leave only dust amount in the router after Bebop consumes 200
// // USDC
// given_amount: BigUint::from_str("99000000000000000").unwrap(), // 0.099 WETH
// checked_token: ondo,
// checked_amount: BigUint::from_str("237212396774431060000").unwrap(), /* Expected ONDO
// from Bebop order */ sender:
// Bytes::from_str("0xc5564C13A157E6240659fb81882A28091add8670").unwrap(), /* Must match order
// taker_address */ receiver:
// Bytes::from_str("0xc5564C13A157E6240659fb81882A28091add8670").unwrap(), /* Using the real order
// receiver */ swaps: vec![swap_weth_usdc, swap_usdc_ondo],
// ..Default::default()
// };
//
// let encoded_solution = encoder
// .encode_solutions(vec![solution.clone()])
// .unwrap()[0]
// .clone();
//
// let calldata = encode_tycho_router_call(
// eth_chain().id(),
// encoded_solution,
// &solution,
// &UserTransferType::TransferFrom,
// &eth(),
// None,
// )
// .unwrap()
// .data;
//
// let hex_calldata = encode(&calldata);
// write_calldata_to_file("test_uniswap_v3_bebop", hex_calldata.as_str());
// }

View File

@@ -5,7 +5,7 @@ use alloy::{hex, hex::encode};
use num_bigint::{BigInt, BigUint};
use tycho_common::{models::protocol::ProtocolComponent, Bytes};
use tycho_execution::encoding::{
evm::utils::write_calldata_to_file,
evm::utils::{biguint_to_u256, write_calldata_to_file},
models::{Solution, Swap, UserTransferType},
};
@@ -597,7 +597,8 @@ fn test_single_encoding_strategy_bebop() {
let partial_fill_offset = 12;
let calldata = Bytes::from_str("0x4dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000").unwrap();
let user_data = build_bebop_calldata(&calldata, partial_fill_offset);
let user_data =
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),
@@ -662,7 +663,8 @@ fn test_single_encoding_strategy_bebop_aggregate() {
let partial_fill_offset = 2;
let calldata = Bytes::from_str("0xa2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000").unwrap();
let user_data = build_bebop_calldata(&calldata, partial_fill_offset);
let user_data =
build_bebop_calldata(&calldata, partial_fill_offset, biguint_to_u256(&amount_in));
let bebop_component = ProtocolComponent {
id: String::from("bebop-rfq"),