Add integration test

This commit is contained in:
die-herdplatte
2025-03-26 16:50:03 +01:00
parent 3e2e9308d4
commit 47d96c2347
2 changed files with 59 additions and 40 deletions

View File

@@ -9,6 +9,7 @@ import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
import {ICore} from "@ekubo/interfaces/ICore.sol"; import {ICore} from "@ekubo/interfaces/ICore.sol";
contract EkuboExecutorTest is Test, Constants { contract EkuboExecutorTest is Test, Constants {
address constant EXECUTOR_ADDRESS = 0xcA4F73Fe97D0B987a0D12B39BBD562c779BAb6f6; // Same address as in swap_encoder.rs tests
EkuboExecutor executor; EkuboExecutor executor;
IERC20 USDC = IERC20(USDC_ADDR); IERC20 USDC = IERC20(USDC_ADDR);
@@ -19,9 +20,14 @@ contract EkuboExecutorTest is Test, Constants {
bytes32 constant ORACLE_CONFIG = 0x51d02a5948496a67827242eabc5725531342527c000000000000000000000000; bytes32 constant ORACLE_CONFIG = 0x51d02a5948496a67827242eabc5725531342527c000000000000000000000000;
function setUp() public { function setUp() public {
uint256 forkBlock = 22082754; vm.createSelectFork(vm.rpcUrl("mainnet"), 22082754);
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
executor = new EkuboExecutor(ICore(payable(CORE_ADDRESS))); deployCodeTo(
"executors/EkuboExecutor.sol",
abi.encode(CORE_ADDRESS),
EXECUTOR_ADDRESS
);
executor = EkuboExecutor(payable(EXECUTOR_ADDRESS));
} }
function testSingleSwapEth() public { function testSingleSwapEth() public {
@@ -86,7 +92,8 @@ contract EkuboExecutorTest is Test, Constants {
assertEq(address(executor).balance, ethBalanceBeforeExecutor + amountOut); assertEq(address(executor).balance, ethBalanceBeforeExecutor + amountOut);
} }
function testMultiHopSwap() public { // Expects input that encodes the same test case as swap_encoder::tests::ekubo::test_encode_swap_multi
function multiHopSwap(bytes memory data) internal {
uint256 amountIn = 1 ether; uint256 amountIn = 1 ether;
deal(address(executor), amountIn); deal(address(executor), amountIn);
@@ -97,15 +104,6 @@ contract EkuboExecutorTest is Test, Constants {
uint256 usdtBalanceBeforeCore = USDT.balanceOf(CORE_ADDRESS); uint256 usdtBalanceBeforeCore = USDT.balanceOf(CORE_ADDRESS);
uint256 usdtBalanceBeforeExecutor = USDT.balanceOf(address(executor)); uint256 usdtBalanceBeforeExecutor = USDT.balanceOf(address(executor));
bytes memory data = abi.encodePacked(
address(executor), // receiver
NATIVE_TOKEN_ADDRESS, // tokenIn
USDC_ADDR, // tokenOut of 1st swap
ORACLE_CONFIG, // config of 1st swap
USDT_ADDR, // tokenOut of 2nd swap
bytes32(0x00000000000000000000000000000000000000000001a36e2eb1c43200000032) // config of 2nd swap (0.0025% fee & 0.005% base pool)
);
uint256 gasBefore = gasleft(); uint256 gasBefore = gasleft();
uint256 amountOut = executor.swap(amountIn, data); uint256 amountOut = executor.swap(amountIn, data);
console.log(gasBefore - gasleft()); console.log(gasBefore - gasleft());
@@ -118,4 +116,24 @@ contract EkuboExecutorTest is Test, Constants {
assertEq(USDT.balanceOf(CORE_ADDRESS), usdtBalanceBeforeCore - amountOut); assertEq(USDT.balanceOf(CORE_ADDRESS), usdtBalanceBeforeCore - amountOut);
assertEq(USDT.balanceOf(address(executor)), usdtBalanceBeforeExecutor + amountOut); assertEq(USDT.balanceOf(address(executor)), usdtBalanceBeforeExecutor + amountOut);
} }
// Same test case as in swap_encoder::tests::ekubo::test_encode_swap_multi
function testMultiHopSwap() public {
bytes memory data = abi.encodePacked(
address(executor), // receiver
NATIVE_TOKEN_ADDRESS, // tokenIn
USDC_ADDR, // tokenOut of 1st swap
ORACLE_CONFIG, // config of 1st swap
USDT_ADDR, // tokenOut of 2nd swap
bytes32(0x00000000000000000000000000000000000000000001a36e2eb1c43200000032) // config of 2nd swap (0.0025% fee & 0.005% base pool)
);
multiHopSwap(data);
}
// Data is generated by test case in swap_encoder::tests::ekubo::test_encode_swap_multi
function testMultiHopSwapIntegration() public {
multiHopSwap(
hex"ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032"
);
}
} }

View File

@@ -2,7 +2,6 @@ use std::str::FromStr;
use alloy_primitives::{Address, Bytes as AlloyBytes}; use alloy_primitives::{Address, Bytes as AlloyBytes};
use alloy_sol_types::SolValue; use alloy_sol_types::SolValue;
use num_traits::Zero;
use tycho_core::Bytes; use tycho_core::Bytes;
use crate::encoding::{ use crate::encoding::{
@@ -705,6 +704,8 @@ mod tests {
mod ekubo { mod ekubo {
use super::*; use super::*;
const RECEIVER: &str = "ca4f73fe97d0b987a0d12b39bbd562c779bab6f6"; // Random address
#[test] #[test]
fn test_encode_swap_simple() { fn test_encode_swap_simple() {
let token_in = Bytes::from(Address::ZERO.as_slice()); let token_in = Bytes::from(Address::ZERO.as_slice());
@@ -729,7 +730,7 @@ mod tests {
}; };
let encoding_context = EncodingContext { let encoding_context = EncodingContext {
receiver: "0xcA4F73Fe97D0B987a0D12B39BBD562c779BAb6f6".into(), // Random address receiver: RECEIVER.into(),
group_token_in: token_in.clone(), group_token_in: token_in.clone(),
group_token_out: token_out.clone(), group_token_out: token_out.clone(),
exact_out: false, exact_out: false,
@@ -746,16 +747,15 @@ mod tests {
assert_eq!( assert_eq!(
hex_swap, hex_swap,
String::from(concat!( RECEIVER.to_string() +
// receiver concat!(
"ca4f73fe97d0b987a0d12b39bbd562c779bab6f6", // group token in
// group token in "0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000", // token out 1st swap
// token out 1st swap "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // pool config 1st swap
// pool config 1st swap "51d02a5948496a67827242eabc5725531342527c000000000000000000000000",
"51d02a5948496a67827242eabc5725531342527c000000000000000000000000", ),
))
); );
} }
@@ -768,7 +768,7 @@ mod tests {
let encoder = EkuboSwapEncoder::new(String::default()); let encoder = EkuboSwapEncoder::new(String::default());
let encoding_context = EncodingContext { let encoding_context = EncodingContext {
receiver: "0xcA4F73Fe97D0B987a0D12B39BBD562c779BAb6f6".into(), // Random address receiver: RECEIVER.into(),
group_token_in: group_token_in.clone(), group_token_in: group_token_in.clone(),
group_token_out: group_token_out.clone(), group_token_out: group_token_out.clone(),
exact_out: false, exact_out: false,
@@ -818,22 +818,23 @@ mod tests {
let combined_hex = let combined_hex =
format!("{}{}", encode(first_encoded_swap), encode(second_encoded_swap)); format!("{}{}", encode(first_encoded_swap), encode(second_encoded_swap));
println!("{}", combined_hex);
assert_eq!( assert_eq!(
combined_hex, combined_hex,
String::from(concat!( RECEIVER.to_string() +
// receiver concat!(
"ca4f73fe97d0b987a0d12b39bbd562c779bab6f6", // group token in
// group token in "0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000", // token out 1st swap
// token out 1st swap "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // pool config 1st swap
// pool config 1st swap "51d02a5948496a67827242eabc5725531342527c000000000000000000000000",
"51d02a5948496a67827242eabc5725531342527c000000000000000000000000", // token out 2nd swap
// token out 2nd swap "dac17f958d2ee523a2206206994597c13d831ec7",
"dac17f958d2ee523a2206206994597c13d831ec7", // pool config 2nd swap
// pool config 2nd swap "00000000000000000000000000000000000000000001a36e2eb1c43200000032",
"00000000000000000000000000000000000000000001a36e2eb1c43200000032", ),
))
); );
} }
} }