feat: implement SwapEncoder for Hashflow
This commit is contained in:
@@ -128,6 +128,9 @@ contract Constants is Test, BaseConstants {
|
||||
// Bebop Settlement
|
||||
address BEBOP_SETTLEMENT = 0xbbbbbBB520d69a9775E85b458C58c648259FAD5F;
|
||||
|
||||
// Hashflow Router
|
||||
address HASHFLOW_ROUTER = 0x55084eE0fEf03f14a305cd24286359A35D735151;
|
||||
|
||||
// Pool Code Init Hashes
|
||||
bytes32 USV2_POOL_CODE_INIT_HASH =
|
||||
0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f;
|
||||
|
||||
@@ -547,3 +547,36 @@ contract TychoRouterSequentialSwapTestForBebop is TychoRouterTestSetup {
|
||||
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
|
||||
}
|
||||
}
|
||||
|
||||
contract TychoRouterSequentialSwapTestForHashflow is TychoRouterTestSetup {
|
||||
function getForkBlock() public pure override returns (uint256) {
|
||||
return 23167288;
|
||||
}
|
||||
|
||||
function testUSV3HashflowIntegration() public {
|
||||
// Performs a sequential swap from WETH to WBTC through USDC using USV3 and Hashflow RFQ
|
||||
//
|
||||
// WETH ──(USV3)──> USDC ───(Hashflow RFQ)──> WBTC
|
||||
|
||||
// The Hashflow order expects:
|
||||
// - 4308094737 USDC input -> 3738288 WBTC output
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 expectedAmountOut = 3738288;
|
||||
deal(WETH_ADDR, ALICE, amountIn);
|
||||
uint256 balanceBefore = IERC20(WBTC_ADDR).balanceOf(ALICE);
|
||||
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
|
||||
bytes memory callData = loadCallDataFromFile("test_uniswap_v3_hashflow");
|
||||
(bool success,) = tychoRouterAddr.call(callData);
|
||||
|
||||
vm.stopPrank();
|
||||
|
||||
uint256 balanceAfter = IERC20(WBTC_ADDR).balanceOf(ALICE);
|
||||
|
||||
assertTrue(success, "Call Failed");
|
||||
assertEq(balanceAfter - balanceBefore, expectedAmountOut);
|
||||
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,3 +426,36 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
assertEq(balanceAfter - balanceBefore, 2018817438608734439722);
|
||||
}
|
||||
}
|
||||
|
||||
contract TychoRouterSingleSwapTestForHashflow is TychoRouterTestSetup {
|
||||
function getForkBlock() public pure override returns (uint256) {
|
||||
return 23175437;
|
||||
}
|
||||
|
||||
function testUSV3HashflowIntegration() public {
|
||||
// Performs a swap from USDC to WBTC using Hashflow RFQ
|
||||
//
|
||||
// USDC ───(Hashflow RFQ)──> WBTC
|
||||
|
||||
// The Hashflow order expects:
|
||||
// - 4308094737 USDC input -> 3714751 WBTC output
|
||||
|
||||
uint256 amountIn = 4308094737;
|
||||
uint256 expectedAmountOut = 3714751;
|
||||
deal(USDC_ADDR, ALICE, amountIn);
|
||||
uint256 balanceBefore = IERC20(WBTC_ADDR).balanceOf(ALICE);
|
||||
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(USDC_ADDR).approve(tychoRouterAddr, type(uint256).max);
|
||||
bytes memory callData = loadCallDataFromFile("test_hashflow");
|
||||
(bool success,) = tychoRouterAddr.call(callData);
|
||||
|
||||
vm.stopPrank();
|
||||
|
||||
uint256 balanceAfter = IERC20(WBTC_ADDR).balanceOf(ALICE);
|
||||
|
||||
assertTrue(success, "Call Failed");
|
||||
assertEq(balanceAfter - balanceBefore, expectedAmountOut);
|
||||
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,27 +2,28 @@
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
// Executors
|
||||
import "../src/executors/HashflowExecutor.sol";
|
||||
import "./Constants.sol";
|
||||
import "./TestUtils.sol";
|
||||
import "@src/TychoRouter.sol";
|
||||
import {
|
||||
UniswapV3Executor,
|
||||
IUniswapV3Pool
|
||||
} from "../src/executors/UniswapV3Executor.sol";
|
||||
import {BalancerV2Executor} from "../src/executors/BalancerV2Executor.sol";
|
||||
import {BalancerV3Executor} from "../src/executors/BalancerV3Executor.sol";
|
||||
import {BebopExecutor} from "../src/executors/BebopExecutor.sol";
|
||||
import {CurveExecutor} from "../src/executors/CurveExecutor.sol";
|
||||
import {EkuboExecutor} from "../src/executors/EkuboExecutor.sol";
|
||||
import {MaverickV2Executor} from "../src/executors/MaverickV2Executor.sol";
|
||||
import {UniswapV2Executor} from "../src/executors/UniswapV2Executor.sol";
|
||||
import {
|
||||
UniswapV3Executor,
|
||||
IUniswapV3Pool
|
||||
} from "../src/executors/UniswapV3Executor.sol";
|
||||
import {UniswapV4Executor} from "../src/executors/UniswapV4Executor.sol";
|
||||
|
||||
// Test utilities and mocks
|
||||
import "./Constants.sol";
|
||||
import "./TestUtils.sol";
|
||||
import {Permit2TestHelper} from "./Permit2TestHelper.sol";
|
||||
import {EkuboExecutor} from "../src/executors/EkuboExecutor.sol";
|
||||
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
||||
import {MaverickV2Executor} from "../src/executors/MaverickV2Executor.sol";
|
||||
|
||||
// Core contracts and interfaces
|
||||
import "@src/TychoRouter.sol";
|
||||
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
||||
import {Permit2TestHelper} from "./Permit2TestHelper.sol";
|
||||
import {UniswapV2Executor} from "../src/executors/UniswapV2Executor.sol";
|
||||
import {UniswapV4Executor} from "../src/executors/UniswapV4Executor.sol";
|
||||
|
||||
contract TychoRouterExposed is TychoRouter {
|
||||
constructor(address _permit2, address weth) TychoRouter(_permit2, weth) {}
|
||||
@@ -75,6 +76,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
MaverickV2Executor public maverickv2Executor;
|
||||
BalancerV3Executor public balancerV3Executor;
|
||||
BebopExecutor public bebopExecutor;
|
||||
HashflowExecutor public hashflowExecutor;
|
||||
|
||||
function getForkBlock() public view virtual returns (uint256) {
|
||||
return 22082754;
|
||||
@@ -135,8 +137,9 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
new MaverickV2Executor(MAVERICK_V2_FACTORY, PERMIT2_ADDRESS);
|
||||
balancerV3Executor = new BalancerV3Executor(PERMIT2_ADDRESS);
|
||||
bebopExecutor = new BebopExecutor(BEBOP_SETTLEMENT, PERMIT2_ADDRESS);
|
||||
hashflowExecutor = new HashflowExecutor(HASHFLOW_ROUTER, PERMIT2_ADDRESS);
|
||||
|
||||
address[] memory executors = new address[](10);
|
||||
address[] memory executors = new address[](11);
|
||||
executors[0] = address(usv2Executor);
|
||||
executors[1] = address(usv3Executor);
|
||||
executors[2] = address(pancakev3Executor);
|
||||
@@ -147,6 +150,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
executors[7] = address(maverickv2Executor);
|
||||
executors[8] = address(balancerV3Executor);
|
||||
executors[9] = address(bebopExecutor);
|
||||
executors[10] = address(hashflowExecutor);
|
||||
|
||||
return executors;
|
||||
}
|
||||
|
||||
@@ -38,3 +38,5 @@ test_single_encoding_strategy_bebop_aggregate:5c4b639c00000000000000000000000000
|
||||
test_single_encoding_strategy_bebop:5c4b639c000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000a8aea46aa4ec5c0f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a10000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002d7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be3000c000000000000000000000000000000000000000000000000000000000bebc20001d2068e04cf586f76eece7ba5beb779d7bb1474a14dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
test_sequential_swap_strategy_encoder_unwrap:51bcc7b600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000068c5498700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000689dc38f00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041192fc75d79a3d76bcf3c3d193cf769446abc98ff76ce2a1de183e7e46d80073836cd6ceedc30f98085188eab1098ca2f0ef03c25ebaa69cd2758988263e563c41b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48004375dff511095cc5a197a54140a24efef3a416bb2b8038a1640196fbe3e38816f3e67cba72d940000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950102000000000000000000000000000000000000000000000000
|
||||
test_sequential_swap_usx:0101e21dd0d300000000000000000000000000000000000000000000006c6b935b8bbd4000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000769cfd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d9da78b6a5bedca287aa5d49613ba36b90c15c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470b6b175474e89094c44da98b954eedeac495271d0fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000643ede3eca2a72b3aecc820e955b36f38437d013955777d92f208679db4b9778590fa3cab3ac9e2168010000692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48dac17f958d2ee523a2206206994597c13d831ec70000646d9da78b6a5bedca287aa5d49613ba36b90c15c43416cf6c708da44db2624d63ea0aaef7113527c6010100000000000000000000
|
||||
test_uniswap_v3_hashflow:e21dd0d30000000000000000000000000000000000000000000000000000000077359400000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000007735940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000014400692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000000d75615deb798bb3e4dfa0139dfa1b3d433cc23b72f0201031903307c517c11b71f8313d19afde0a4f41cb55615deb798bb3e4dfa0139dfa1b3d433cc23b72f00000198bcad59fd125000064000640000001747937188ffffffffffffff00295e467232b36d0000fda99100ffd8adfc818a827e1698c1d1fa2f59f7723ff84bfeba0f80e5298b1077f590d8d99aec6f6801c611eb270b5d89fac02a680ab38f03f3c5d16039c6f11c0000000068a2fd62bb289bc97591f70d8216462df40ed713011b968acd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000
|
||||
test_hashflow:5c4b639c0000000000000000000000000000000000000000000000000000000100c84f11000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000000038aebf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016f15cf58144ef33af1e14b5208015d11f9143e27b90001478eca1b93865dca0b9f325935eb123c8a4af011bee3211ab312a8d065c4fef0247448e17a8da000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb482260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000100c84f11000000000000000000000000000000000000000000000000000000000038aebf0000000000000000000000000000000000000000000000000000000068a47cd800000000000000000000000000000000000000000000000000000198c286fecb125000064000640000001747eb8c38ffffffffffffff0029642016edb36d00006ddb3b21fe8509e274ddf46c55209cdbf30360944abbca6569ed6b26740d052f419964dcb5a3bdb98b4ed1fb3642a2760b8312118599a962251f7a8f73fe4fbe1c0000000000000000000000000000000000
|
||||
|
||||
@@ -14,8 +14,8 @@ contract HashflowUtils is Test {
|
||||
RestrictTransferFrom.TransferType transferType
|
||||
) internal pure returns (bytes memory) {
|
||||
return abi.encodePacked(
|
||||
approvalNeeded, // needsApproval (1 byte)
|
||||
uint8(transferType), // transferType (1 byte)
|
||||
approvalNeeded, // needsApproval (1 byte)
|
||||
quote.pool, // pool (20 bytes)
|
||||
quote.externalAccount, // externalAccount (20 bytes)
|
||||
quote.trader, // trader (20 bytes)
|
||||
@@ -53,7 +53,7 @@ contract HashflowExecutorECR20Test is Constants, HashflowUtils {
|
||||
function setUp() public {
|
||||
forkBlock = 23124977; // Using expiry date: 1755001853, ECR20
|
||||
vm.createSelectFork("mainnet", forkBlock);
|
||||
executor = new HashflowExecutorExposed(PERMIT2_ADDRESS);
|
||||
executor = new HashflowExecutorExposed(HASHFLOW_ROUTER, PERMIT2_ADDRESS);
|
||||
}
|
||||
|
||||
function testDecodeParams() public view {
|
||||
@@ -215,7 +215,7 @@ contract HashflowExecutorNativeTest is Constants, HashflowUtils {
|
||||
function setUp() public {
|
||||
forkBlock = 23125321; // Using expiry date: 1755006017, Native
|
||||
vm.createSelectFork("mainnet", forkBlock);
|
||||
executor = new HashflowExecutorExposed(PERMIT2_ADDRESS);
|
||||
executor = new HashflowExecutorExposed(HASHFLOW_ROUTER, PERMIT2_ADDRESS);
|
||||
}
|
||||
|
||||
function testSwapNoSlippage() public {
|
||||
@@ -264,7 +264,9 @@ contract HashflowExecutorNativeTest is Constants, HashflowUtils {
|
||||
}
|
||||
|
||||
contract HashflowExecutorExposed is HashflowExecutor {
|
||||
constructor(address _permit2) HashflowExecutor(_permit2) {}
|
||||
constructor(address _hashflowRouter, address _permit2)
|
||||
HashflowExecutor(_hashflowRouter, _permit2)
|
||||
{}
|
||||
|
||||
function decodeData(bytes calldata data)
|
||||
external
|
||||
|
||||
Reference in New Issue
Block a user