fix: Move Bebop tests according to new setup
Encoding: integration tests are now separate and inside their own test folder Execution: the final integration test should be inside of the protocol test file now and not in TychoRouterProtocolIntegration.t.sol. For this I had to move the BebopExecutionHarness.t.sol outside of the Bebop test file (because of imports) Took 24 minutes # Commit time for manual adjustment: # Took 2 minutes
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
mod common;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use alloy::hex::encode;
|
||||
use alloy::{
|
||||
hex,
|
||||
hex::encode,
|
||||
primitives::{Address, U256},
|
||||
sol_types::SolValue,
|
||||
};
|
||||
use num_bigint::{BigInt, BigUint};
|
||||
use tycho_common::{models::protocol::ProtocolComponent, Bytes};
|
||||
use tycho_execution::encoding::{
|
||||
evm::utils::write_calldata_to_file,
|
||||
models::{Solution, Swap, UserTransferType},
|
||||
models::{BebopOrderType, Solution, Swap, UserTransferType},
|
||||
};
|
||||
|
||||
use crate::common::{
|
||||
encoding::encode_tycho_router_call, eth, eth_chain, get_signer, get_tycho_router_encoder, pepe,
|
||||
usdc, weth,
|
||||
build_bebop_user_data, encoding::encode_tycho_router_call, eth, eth_chain, get_signer,
|
||||
get_tycho_router_encoder, ondo, pepe, usdc, weth,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_single_encoding_strategy_ekubo() {
|
||||
// ETH ──(EKUBO)──> USDC
|
||||
@@ -572,3 +578,233 @@ fn test_single_encoding_strategy_balancer_v3() {
|
||||
let hex_calldata = encode(&calldata);
|
||||
write_calldata_to_file("test_single_encoding_strategy_balancer_v3", hex_calldata.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_encoding_strategy_bebop() {
|
||||
// Use the same mainnet data from Solidity tests
|
||||
// Transaction: https://etherscan.io/tx/0x6279bc970273b6e526e86d9b69133c2ca1277e697ba25375f5e6fc4df50c0c94
|
||||
let token_in = usdc();
|
||||
let token_out = ondo();
|
||||
let amount_in = BigUint::from_str("200000000").unwrap(); // 200 USDC
|
||||
let amount_out = BigUint::from_str("237212396774431060000").unwrap(); // 237.21 ONDO
|
||||
|
||||
// Create the exact same order from mainnet
|
||||
let expiry = 1749483840u64;
|
||||
let taker_address = Address::from_str("0xc5564C13A157E6240659fb81882A28091add8670").unwrap(); // Order receiver from mainnet
|
||||
let maker_address = Address::from_str("0xCe79b081c0c924cb67848723ed3057234d10FC6b").unwrap();
|
||||
let maker_nonce = 1749483765992417u64;
|
||||
let taker_token = Address::from_str(&token_in.to_string()).unwrap();
|
||||
let maker_token = Address::from_str(&token_out.to_string()).unwrap();
|
||||
let taker_amount = U256::from_str(&amount_in.to_string()).unwrap();
|
||||
let maker_amount = U256::from_str(&amount_out.to_string()).unwrap();
|
||||
let receiver = taker_address; // Same as taker_address in this order
|
||||
let packed_commands = U256::ZERO;
|
||||
let flags = U256::from_str(
|
||||
"51915842898789398998206002334703507894664330885127600393944965515693155942400",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// 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 mainnet
|
||||
let signature = hex::decode("eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c").unwrap();
|
||||
|
||||
// Build user_data with the quote and signature
|
||||
let user_data = build_bebop_user_data(
|
||||
BebopOrderType::Single,
|
||||
U256::ZERO, // 0 means fill entire order
|
||||
"e_data,
|
||||
vec![(signature, 0)], // ETH_SIGN signature type
|
||||
);
|
||||
|
||||
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 = Swap {
|
||||
component: bebop_component,
|
||||
token_in: token_in.clone(),
|
||||
token_out: token_out.clone(),
|
||||
split: 0f64,
|
||||
user_data: Some(user_data),
|
||||
};
|
||||
|
||||
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
||||
|
||||
let taker_address_bytes = Bytes::from_str(&taker_address.to_string()).unwrap();
|
||||
|
||||
let solution = Solution {
|
||||
exact_out: false,
|
||||
given_token: token_in,
|
||||
given_amount: amount_in,
|
||||
checked_token: token_out,
|
||||
checked_amount: amount_out, // Expected output amount
|
||||
// Use the order's taker address as sender and receiver
|
||||
sender: taker_address_bytes.clone(),
|
||||
receiver: taker_address_bytes,
|
||||
swaps: vec![swap],
|
||||
..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,
|
||||
ð(),
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.data;
|
||||
let hex_calldata = hex::encode(&calldata);
|
||||
write_calldata_to_file("test_single_encoding_strategy_bebop", hex_calldata.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_encoding_strategy_bebop_aggregate() {
|
||||
// Use real mainnet aggregate order data from CLAUDE.md
|
||||
// Transaction: https://etherscan.io/tx/0xec88410136c287280da87d0a37c1cb745f320406ca3ae55c678dec11996c1b1c
|
||||
// For testing, use WETH directly to avoid delegatecall + native ETH complexities
|
||||
let token_in = eth();
|
||||
let token_out = usdc();
|
||||
let amount_in = BigUint::from_str("9850000000000000").unwrap(); // 0.00985 WETH
|
||||
let amount_out = BigUint::from_str("17969561").unwrap(); // 17.969561 USDC
|
||||
|
||||
// Create the exact aggregate order from mainnet
|
||||
let expiry = 1746367285u64;
|
||||
let taker_address = Address::from_str("0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6").unwrap();
|
||||
let receiver = Address::from_str("0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6").unwrap();
|
||||
|
||||
// Set up makers
|
||||
let maker_addresses = vec![
|
||||
Address::from_str("0x67336Cec42645F55059EfF241Cb02eA5cC52fF86").unwrap(),
|
||||
Address::from_str("0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE").unwrap(),
|
||||
];
|
||||
let maker_nonces = vec![U256::from(1746367197308u64), U256::from(15460096u64)];
|
||||
|
||||
// 2D arrays for tokens
|
||||
// We use WETH as a taker token even when handling native ETH
|
||||
let taker_tokens = vec![vec![Address::from_slice(&weth())], vec![Address::from_slice(&weth())]];
|
||||
let maker_tokens =
|
||||
vec![vec![Address::from_slice(&token_out)], vec![Address::from_slice(&token_out)]];
|
||||
|
||||
// 2D arrays for amounts
|
||||
let taker_amounts = vec![
|
||||
vec![U256::from_str("5812106401997138").unwrap()],
|
||||
vec![U256::from_str("4037893598002862").unwrap()],
|
||||
];
|
||||
let maker_amounts =
|
||||
vec![vec![U256::from_str("10607211").unwrap()], vec![U256::from_str("7362350").unwrap()]];
|
||||
|
||||
// Commands and flags from the real transaction
|
||||
let commands = hex!("00040004").to_vec();
|
||||
let flags = U256::from_str(
|
||||
"95769172144825922628485191511070792431742484643425438763224908097896054784000",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Encode Aggregate order - must match IBebopSettlement.Aggregate struct exactly
|
||||
let quote_data = (
|
||||
U256::from(expiry), // expiry as U256
|
||||
taker_address,
|
||||
maker_addresses,
|
||||
maker_nonces, // Array of maker nonces
|
||||
taker_tokens, // 2D array
|
||||
maker_tokens,
|
||||
taker_amounts, // 2D array
|
||||
maker_amounts,
|
||||
receiver,
|
||||
commands,
|
||||
flags,
|
||||
)
|
||||
.abi_encode();
|
||||
|
||||
// Use real signatures from the mainnet transaction
|
||||
let sig1 = hex::decode("d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c").unwrap();
|
||||
let sig2 = hex::decode("f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b").unwrap();
|
||||
|
||||
// Build user_data with ETH_SIGN flag (0) for both signatures
|
||||
let signatures = vec![
|
||||
(sig1, 0u8), // ETH_SIGN for maker 1
|
||||
(sig2, 0u8), // ETH_SIGN for maker 2
|
||||
];
|
||||
|
||||
let user_data = build_bebop_user_data(
|
||||
BebopOrderType::Aggregate,
|
||||
U256::from(0), // 0 means fill entire aggregate order
|
||||
"e_data,
|
||||
signatures,
|
||||
);
|
||||
|
||||
let bebop_component = ProtocolComponent {
|
||||
id: String::from("bebop-rfq"),
|
||||
protocol_system: String::from("rfq:bebop"),
|
||||
static_attributes: HashMap::new(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let swap = Swap {
|
||||
component: bebop_component,
|
||||
token_in: token_in.clone(),
|
||||
token_out: token_out.clone(),
|
||||
split: 0f64,
|
||||
user_data: Some(user_data),
|
||||
};
|
||||
|
||||
// Use TransferFrom for WETH token transfer
|
||||
let encoder = get_tycho_router_encoder(UserTransferType::TransferFrom);
|
||||
|
||||
let solution = Solution {
|
||||
exact_out: false,
|
||||
given_token: token_in.clone(),
|
||||
given_amount: amount_in,
|
||||
checked_token: token_out,
|
||||
checked_amount: amount_out,
|
||||
// Use ALICE as sender but order receiver as receiver
|
||||
sender: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(), /* ALICE */
|
||||
receiver: Bytes::from_str("0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6").unwrap(), /* Order receiver */
|
||||
swaps: vec![swap],
|
||||
..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::None,
|
||||
ð(),
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.data;
|
||||
let hex_calldata = hex::encode(&calldata);
|
||||
|
||||
write_calldata_to_file("test_single_encoding_strategy_bebop_aggregate", hex_calldata.as_str());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user