Merge branch 'main' into router/tnl/deploy-pancake-v2

This commit is contained in:
dianacarvalho1
2025-05-05 10:11:28 +01:00
committed by GitHub
28 changed files with 753 additions and 165 deletions

View File

@@ -1,3 +1,34 @@
## [0.86.0](https://github.com/propeller-heads/tycho-execution/compare/0.85.1...0.86.0) (2025-05-02)
### Features
* Change revert condition in _wrapETH ([0400005](https://github.com/propeller-heads/tycho-execution/commit/04000059e5e7940f209639c900557b437a766913))
* Propagate the entire result of the callback ([8a7c390](https://github.com/propeller-heads/tycho-execution/commit/8a7c39052d45ee75e81cbb267748a1fc635a8c34))
## [0.85.1](https://github.com/propeller-heads/tycho-execution/compare/0.85.0...0.85.1) (2025-05-01)
### Bug Fixes
* Derive Clone in TychoEncoders ([f99bd29](https://github.com/propeller-heads/tycho-execution/commit/f99bd296a1b74900adc24ea9db7b75367612e0f9))
## [0.85.0](https://github.com/propeller-heads/tycho-execution/compare/0.84.0...0.85.0) (2025-05-01)
### Features
* add mav executor ([0ac722d](https://github.com/propeller-heads/tycho-execution/commit/0ac722d91f6c2f7c09531f5f56f057d1fe014c6f))
* add swap encode ([72a651d](https://github.com/propeller-heads/tycho-execution/commit/72a651d453943d554722d0fa4818255fbec01ce5))
* Transfer Optimizations in MaverickV2 ([bcef8f6](https://github.com/propeller-heads/tycho-execution/commit/bcef8f69f628c3a37a7cb5462e26200ad5aab1ee))
### Bug Fixes
* add maverick for build ([bab30e3](https://github.com/propeller-heads/tycho-execution/commit/bab30e3958ee62091b322ac0bc540939c050ee9e))
* maverick test fork block ([4c93830](https://github.com/propeller-heads/tycho-execution/commit/4c938306bda62d37b8932697f98d0d667a96532b))
* swap test ([d103ca9](https://github.com/propeller-heads/tycho-execution/commit/d103ca9e33f931f18c8af79efa5d77d801bab2e9))
## [0.84.0](https://github.com/propeller-heads/tycho-execution/compare/0.83.0...0.84.0) (2025-04-28) ## [0.84.0](https://github.com/propeller-heads/tycho-execution/compare/0.83.0...0.84.0) (2025-04-28)

39
Cargo.lock generated
View File

@@ -4,13 +4,19 @@ version = 4
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.24.2" version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
dependencies = [ dependencies = [
"gimli", "gimli",
] ]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "adler2" name = "adler2"
version = "2.0.0" version = "2.0.0"
@@ -1164,17 +1170,17 @@ dependencies = [
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.74" version = "0.3.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc",
"cfg-if", "cfg-if",
"libc", "libc",
"miniz_oxide", "miniz_oxide 0.7.4",
"object", "object",
"rustc-demangle", "rustc-demangle",
"windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -1792,7 +1798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide 0.8.8",
] ]
[[package]] [[package]]
@@ -2006,9 +2012,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.31.1" version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]] [[package]]
name = "glob" name = "glob"
@@ -2710,6 +2716,15 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "miniz_oxide"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.8" version = "0.8.8"
@@ -2841,9 +2856,9 @@ dependencies = [
[[package]] [[package]]
name = "object" name = "object"
version = "0.36.7" version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -4454,7 +4469,7 @@ dependencies = [
[[package]] [[package]]
name = "tycho-execution" name = "tycho-execution"
version = "0.84.0" version = "0.86.0"
dependencies = [ dependencies = [
"alloy", "alloy",
"alloy-primitives", "alloy-primitives",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tycho-execution" name = "tycho-execution"
version = "0.84.0" version = "0.86.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"

View File

@@ -12,3 +12,12 @@ For complete documentation, see Tycho docs [here](https://docs.propellerheads.xy
To get started on encoding, have a look at our [Encoding example](examples/encoding-example/README.md). To get started on encoding, have a look at our [Encoding example](examples/encoding-example/README.md).
For a complete example please refer to the [Tycho Quickstart guide](https://docs.propellerheads.xyz/tycho). For a complete example please refer to the [Tycho Quickstart guide](https://docs.propellerheads.xyz/tycho).
## Security
All audits of the Tycho Router and Executor contracts can be found [here](docs/audits).
The vulnerabilities discovered during the audits have been acknowledged and addressed or accepted.
### Report a Vulnerability
Contact [security@propellerheads.xyz](mailto:security@propellerheads.xyz)

View File

@@ -8,6 +8,7 @@
"uniswap_v4": "0xF62849F9A0B5Bf2913b396098F7c7019b51A820a", "uniswap_v4": "0xF62849F9A0B5Bf2913b396098F7c7019b51A820a",
"vm:balancer_v2": "0xc7183455a4C133Ae270771860664b6B7ec320bB1", "vm:balancer_v2": "0xc7183455a4C133Ae270771860664b6B7ec320bB1",
"ekubo_v2": "0xa0Cb889707d426A7A386870A03bc70d1b0697598", "ekubo_v2": "0xa0Cb889707d426A7A386870A03bc70d1b0697598",
"vm:curve": "0x1d1499e622D69689cdf9004d05Ec547d650Ff211" "vm:curve": "0x1d1499e622D69689cdf9004d05Ec547d650Ff211",
"vm:maverick_v2": "0xA4AD4f68d0b91CFD19687c881e50f3A00242828c"
} }
} }

View File

@@ -7,6 +7,7 @@ evm_version = 'cancun'
optimizer = true optimizer = true
optimizer_runs = 200 optimizer_runs = 200
via_ir = true via_ir = true
fs_permissions = [{ access = "read", path = "./test/assets" }]
[profile.production] [profile.production]
src = 'src' src = 'src'
@@ -21,6 +22,5 @@ via_ir = true
[rpc_endpoints] [rpc_endpoints]
mainnet = "${RPC_URL}" mainnet = "${RPC_URL}"
[fmt] [fmt]
line_length = 80 line_length = 80

View File

@@ -661,8 +661,8 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
bytes memory result = _callHandleCallbackOnExecutor(msg.data); bytes memory result = _callHandleCallbackOnExecutor(msg.data);
// slither-disable-next-line assembly // slither-disable-next-line assembly
assembly ("memory-safe") { assembly ("memory-safe") {
// Propagate the calculatedAmount // Propagate the result
return(add(result, 32), 16) return(add(result, 32), mload(result))
} }
} }
@@ -757,7 +757,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
* @param amount of native ETH to wrap. * @param amount of native ETH to wrap.
*/ */
function _wrapETH(uint256 amount) internal { function _wrapETH(uint256 amount) internal {
if (msg.value > 0 && msg.value != amount) { if (msg.value != amount) {
revert TychoRouter__MessageValueMismatch(msg.value, amount); revert TychoRouter__MessageValueMismatch(msg.value, amount);
} }
_weth.deposit{value: amount}(); _weth.deposit{value: amount}();

View File

@@ -0,0 +1,106 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26;
import "@interfaces/IExecutor.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./TokenTransfer.sol";
error MaverickV2Executor__InvalidDataLength();
error MaverickV2Executor__InvalidTarget();
error MaverickV2Executor__InvalidFactory();
contract MaverickV2Executor is IExecutor, TokenTransfer {
using SafeERC20 for IERC20;
address public immutable factory;
address private immutable self;
constructor(address _factory, address _permit2) TokenTransfer(_permit2) {
if (_factory == address(0)) {
revert MaverickV2Executor__InvalidFactory();
}
factory = _factory;
self = address(this);
}
// slither-disable-next-line locked-ether
function swap(uint256 givenAmount, bytes calldata data)
external
payable
returns (uint256 calculatedAmount)
{
address target;
address receiver;
IERC20 tokenIn;
TransferType transferType;
(tokenIn, target, receiver, transferType) = _decodeData(data);
_verifyPairAddress(target);
IMaverickV2Pool pool = IMaverickV2Pool(target);
bool isTokenAIn = pool.tokenA() == tokenIn;
int32 tickLimit = isTokenAIn ? type(int32).max : type(int32).min;
IMaverickV2Pool.SwapParams memory swapParams = IMaverickV2Pool
.SwapParams({
amount: givenAmount,
tokenAIn: isTokenAIn,
exactOutput: false,
tickLimit: tickLimit
});
_transfer(
address(tokenIn), msg.sender, target, givenAmount, transferType
);
// slither-disable-next-line unused-return
(, calculatedAmount) = pool.swap(receiver, swapParams, "");
}
function _decodeData(bytes calldata data)
internal
pure
returns (
IERC20 inToken,
address target,
address receiver,
TransferType transferType
)
{
if (data.length != 61) {
revert MaverickV2Executor__InvalidDataLength();
}
inToken = IERC20(address(bytes20(data[0:20])));
target = address(bytes20(data[20:40]));
receiver = address(bytes20(data[40:60]));
transferType = TransferType(uint8(data[60]));
}
function _verifyPairAddress(address target) internal view {
if (!IMaverickV2Factory(factory).isFactoryPool(IMaverickV2Pool(target)))
{
revert MaverickV2Executor__InvalidTarget();
}
}
}
interface IMaverickV2Factory {
function isFactoryPool(IMaverickV2Pool pool) external view returns (bool);
}
interface IMaverickV2Pool {
struct SwapParams {
uint256 amount;
bool tokenAIn;
bool exactOutput;
int32 tickLimit;
}
function swap(
address recipient,
SwapParams memory params,
bytes calldata data
) external returns (uint256 amountIn, uint256 amountOut);
function tokenA() external view returns (IERC20);
function tokenB() external view returns (IERC20);
}

View File

@@ -54,6 +54,12 @@ contract Constants is Test, BaseConstants {
address WSTTAO_ADDR = address(0xe9633C52f4c8B7BDeb08c4A7fE8a5c1B84AFCf67); address WSTTAO_ADDR = address(0xe9633C52f4c8B7BDeb08c4A7fE8a5c1B84AFCf67);
address WTAO_ADDR = address(0x77E06c9eCCf2E797fd462A92B6D7642EF85b0A44); address WTAO_ADDR = address(0x77E06c9eCCf2E797fd462A92B6D7642EF85b0A44);
address BSGG_ADDR = address(0xdA16Cf041E2780618c49Dbae5d734B89a6Bac9b3); address BSGG_ADDR = address(0xdA16Cf041E2780618c49Dbae5d734B89a6Bac9b3);
address GHO_ADDR = address(0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f);
// Maverick v2
address MAVERICK_V2_FACTORY = 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e;
address GHO_USDC_POOL = 0x14Cf6D2Fe3E1B326114b07d22A6F6bb59e346c67;
// Uniswap v2 // Uniswap v2
address WETH_DAI_POOL = 0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11; address WETH_DAI_POOL = 0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11;
address DAI_USDC_POOL = 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5; address DAI_USDC_POOL = 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5;

View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import "forge-std/Test.sol";
contract TestUtils is Test {
constructor() {}
function loadCallDataFromFile(string memory testName)
internal
view
returns (bytes memory)
{
string memory fileContent = vm.readFile("./test/assets/calldata.txt");
string[] memory lines = vm.split(fileContent, "\n");
for (uint256 i = 0; i < lines.length; i++) {
string[] memory parts = vm.split(lines[i], ":");
if (
parts.length >= 2
&& keccak256(bytes(parts[0])) == keccak256(bytes(testName))
) {
return vm.parseBytes(parts[1]);
}
}
revert("Test calldata not found");
}
}

View File

@@ -103,10 +103,9 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_sequential_encoding_strategy_usv4` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_sequential_encoding_strategy_usv4");
hex"7c553846000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006828a8d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000680122e10000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000412fb2c4e85c1b2236aef343641c10f81e4abfd675f520d86778cb9db16c9f500d11fe28b99285dd1bef082b9ccde3360a8077c57ece0775677fddfd5ff11b6e081c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d008b0001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -127,10 +126,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(DAI_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(DAI_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_multi_protocol` bytes memory callData = loadCallDataFromFile("test_multi_protocol");
(bool success,) = tychoRouterAddr.call( (bool success,) = tychoRouterAddr.call(callData);
hex"51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000682f990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006808130800000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000414e46e936cfd0f718a485f27c233cb85a64ab162edca753cbc7c9d1bc393a688275dc15bd930e210af2e5dd8e8d8f90ec8438b821297c469d80712aadcff73b071c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501020072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010500691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001053ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598003ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000"
);
vm.stopPrank(); vm.stopPrank();
@@ -150,10 +147,9 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
deal(ALICE, 1 ether); deal(ALICE, 1 ether);
uint256 balanceBefore = IERC20(PEPE_ADDR).balanceOf(ALICE); uint256 balanceBefore = IERC20(PEPE_ADDR).balanceOf(ALICE);
// Encoded solution generated using `test_single_encoding_strategy_usv4_eth_in` bytes memory callData =
(bool success,) = tychoRouterAddr.call{value: 1 ether}( loadCallDataFromFile("test_single_encoding_strategy_usv4_eth_in");
hex"30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000682f92ce00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068080cd600000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041006930677d9715fb8c55f73546d3aaff4176ee1342b9b7ae34431a4356fc98a915f3103639d8e34cbaa591a3493e887dad6e816228200dee0a693408b4fa6fdc1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330105cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call{value: 1 ether}(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -177,10 +173,9 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_single_encoding_strategy_usv4_eth_out` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_single_encoding_strategy_usv4_eth_out");
hex"7c55384600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006828a8d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000680122e1000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041bf1373f3d3943e0865f8081b1569b4deb66b56b8690500c4c9f1c1f7e1299510720e3d4c92abf6ec75f0b14a87b92957fd43408562f26b8616857469f94012e21b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300710001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c00000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -191,6 +186,26 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
assertEq(balanceAfter - balanceBefore, 1474406268748155809); assertEq(balanceAfter - balanceBefore, 1474406268748155809);
} }
function testSingleMaverickIntegration() public {
vm.stopPrank();
deal(GHO_ADDR, ALICE, 1 ether);
uint256 balanceBefore = IERC20(USDC_ADDR).balanceOf(ALICE);
vm.startPrank(ALICE);
IERC20(GHO_ADDR).approve(tychoRouterAddr, type(uint256).max);
bytes memory callData =
loadCallDataFromFile("test_single_encoding_strategy_maverick");
(bool success,) = tychoRouterAddr.call(callData);
uint256 balanceAfter = IERC20(USDC_ADDR).balanceOf(ALICE);
assertTrue(success, "Call Failed");
assertGe(balanceAfter - balanceBefore, 999725);
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
}
function testSingleEkuboIntegration() public { function testSingleEkuboIntegration() public {
vm.stopPrank(); vm.stopPrank();
@@ -199,10 +214,9 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
// Encoded solution generated using `test_single_encoding_strategy_ekubo` bytes memory callData =
(bool success,) = address(tychoRouter).call{value: 1 ether}( loadCallDataFromFile("test_single_encoding_strategy_ekubo");
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000071a0cb889707d426a7a386870a03bc70d1b069759805cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call{value: 1 ether}(callData);
);
uint256 balanceAfter = IERC20(USDC_ADDR).balanceOf(ALICE); uint256 balanceAfter = IERC20(USDC_ADDR).balanceOf(ALICE);
@@ -216,10 +230,9 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(UWU_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(UWU_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_single_encoding_strategy_curve` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_single_encoding_strategy_curve");
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000103cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
assertTrue(success, "Call Failed"); assertTrue(success, "Call Failed");
assertEq(IERC20(WETH_ADDR).balanceOf(ALICE), 2877855391767); assertEq(IERC20(WETH_ADDR).balanceOf(ALICE), 2877855391767);

View File

@@ -351,10 +351,9 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_sequential_swap_strategy_encoder` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_sequential_swap_strategy_encoder");
hex"51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000682714ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067ff8eb300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412fe66c22814eb271e37bb03303bae445eb96aa50fae9680a0ae685ee5795aebf1f5bb7718154c69680bcfc00cc9be525b2b021f57a1bddb4db622139acd425d41b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000200525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -375,10 +374,10 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_sequential_swap_strategy_encoder_no_permit2` bytes memory callData = loadCallDataFromFile(
(bool success,) = tychoRouterAddr.call( "test_sequential_swap_strategy_encoder_no_permit2"
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000"
); );
(bool success,) = tychoRouterAddr.call(callData);
vm.stopPrank(); vm.stopPrank();
@@ -396,10 +395,9 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_sequential_strategy_cyclic_swap` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_sequential_strategy_cyclic_swap");
hex"51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000682f96a300000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000680810ab00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000415de1a1f5644d780aa3e22af583e87639ff7d519518576da5b10c15748d75d7f64b9d4fc2439869fc226ca4a8b69c6cc4b284427b0d5d73c72e54f115cdf2bbca1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
assertTrue(success, "Call Failed"); assertTrue(success, "Call Failed");
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99792554); assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99792554);
@@ -417,10 +415,9 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_uniswap_v3_uniswap_v2` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_uniswap_v3_uniswap_v2");
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000bf00692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb8004375dff511095cc5a197a54140a24efef3a416cbcdf9626bc03e24f779434178a73a0b4bad62ed000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010500" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -441,10 +438,9 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_uniswap_v3_uniswap_v3` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_uniswap_v3_uniswap_v3");
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000100692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -465,10 +461,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_uniswap_v3_curve` bytes memory callData = loadCallDataFromFile("test_uniswap_v3_curve");
(bool success,) = tychoRouterAddr.call( (bool success,) = tychoRouterAddr.call(callData);
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000100691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000105cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000"
);
vm.stopPrank(); vm.stopPrank();
@@ -489,10 +483,9 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_uniswap_v3_curve` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_balancer_v2_uniswap_v2");
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010300525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();

View File

@@ -294,10 +294,9 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_single_swap_strategy_encoder_no_permit2` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_single_swap_strategy_encoder_no_permit2");
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -313,10 +312,9 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_single_swap_strategy_encoder` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_single_swap_strategy_encoder");
hex"30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006b56051582a970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000682f946a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068080e7200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041c0ace69971589bd5136c309c83a06d60a7a54a49a2f1cecdf51cc5aecd4f7cce07a1b4a152d758fb6c3e4a73f8cf96ca3b3e8ab82b402733b7979a67021e99a51c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200020000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -333,10 +331,9 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
// Encoded solution generated using `test_single_swap_strategy_encoder_wrap` bytes memory callData =
(bool success,) = tychoRouterAddr.call{value: 1 ether}( loadCallDataFromFile("test_single_swap_strategy_encoder_wrap");
hex"30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000682f965f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006808106700000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041cdef1c27d45a13adde80b5d93c8786741b69ddbe7684c4356f3dc7d4aa8029cb3cba0aac801787a7993ba0be72a6b459fa2a5c18a8e4938a0ccd3503d1be81841c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000" (bool success,) = tychoRouterAddr.call{value: 1 ether}(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -355,10 +352,9 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(DAI_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(DAI_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_single_swap_strategy_encoder_unwrap` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_single_swap_strategy_encoder_unwrap");
hex"30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000682db45d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068062e6500000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041de45f1a73e8a22fc958af300f93cff06b49e74667bb29b810aed4254fef0dae6340ceb95265d81f5b158bcade2b5a2e3efa8bfa521a6466c0b1ce0bcfddc19d21c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501020000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
@@ -374,10 +370,10 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
uint256 balanceBefore = IERC20(DAI_ADDR).balanceOf(ALICE); uint256 balanceBefore = IERC20(DAI_ADDR).balanceOf(ALICE);
vm.startPrank(ALICE); vm.startPrank(ALICE);
// Encoded solution generated using `test_single_swap_strategy_encoder_no_transfer_in` bytes memory callData = loadCallDataFromFile(
(bool success,) = tychoRouterAddr.call( "test_single_swap_strategy_encoder_no_transfer_in"
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000"
); );
(bool success,) = tychoRouterAddr.call(callData);
vm.stopPrank(); vm.stopPrank();

View File

@@ -529,11 +529,9 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_swap_strategy_encoder` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_split_swap_strategy_encoder");
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe9342000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041d137d0776bc16ff9c49bfd3e96103ceb6926654f314489cafcf5a64ab7a9c4f2061ed5ffdef67c33c3c5b78036d28d9eb73da156a0e68d8740235be50e88a3481b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950002005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950002005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20100005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010000000000000000000000000000000000000000000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
vm.stopPrank(); vm.stopPrank();
uint256 balanceAfter = IERC20(USDC_ADDR).balanceOf(ALICE); uint256 balanceAfter = IERC20(USDC_ADDR).balanceOf(ALICE);
@@ -552,10 +550,9 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_input_cyclic_swap` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_split_input_cyclic_swap");
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004194fc497ac440b520981d23b4713425da21dc1c801e657d218a917b5c51339a660b9a5fe0a346cb0aacc0d67ebf03f8fa3ec9fade437ef1b08ea837b2442931b61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80102005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
assertTrue(success, "Call Failed"); assertTrue(success, "Call Failed");
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99654537); assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99654537);
@@ -569,10 +566,9 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
// Approve permit2 // Approve permit2
vm.startPrank(ALICE); vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max); IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_output_cyclic_swap` bytes memory callData =
(bool success,) = tychoRouterAddr.call( loadCallDataFromFile("test_split_output_cyclic_swap");
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000682f963200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006808103a0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000413c46b497d6f01110f05257114b978d2fd2d493ac8dae2c7892bbfa593fc5d062384590828248348fe87b234c3417e463f12d4732e287a56882841a92bc41e9121b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950102006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400000006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000" (bool success,) = tychoRouterAddr.call(callData);
);
assertTrue(success, "Call Failed"); assertTrue(success, "Call Failed");
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99444510); assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), 99444510);

View File

@@ -14,6 +14,8 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol";
import {WETH} from "../lib/permit2/lib/solmate/src/tokens/WETH.sol"; import {WETH} from "../lib/permit2/lib/solmate/src/tokens/WETH.sol";
import {Permit2TestHelper} from "./Permit2TestHelper.sol"; import {Permit2TestHelper} from "./Permit2TestHelper.sol";
import "./TestUtils.sol";
import {MaverickV2Executor} from "../src/executors/MaverickV2Executor.sol";
contract TychoRouterExposed is TychoRouter { contract TychoRouterExposed is TychoRouter {
constructor(address _permit2, address weth) TychoRouter(_permit2, weth) {} constructor(address _permit2, address weth) TychoRouter(_permit2, weth) {}
@@ -42,7 +44,7 @@ contract TychoRouterExposed is TychoRouter {
} }
} }
contract TychoRouterTestSetup is Constants, Permit2TestHelper { contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
TychoRouterExposed tychoRouter; TychoRouterExposed tychoRouter;
address tychoRouterAddr; address tychoRouterAddr;
UniswapV2Executor public usv2Executor; UniswapV2Executor public usv2Executor;
@@ -52,6 +54,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper {
BalancerV2Executor public balancerv2Executor; BalancerV2Executor public balancerv2Executor;
EkuboExecutor public ekuboExecutor; EkuboExecutor public ekuboExecutor;
CurveExecutor public curveExecutor; CurveExecutor public curveExecutor;
MaverickV2Executor public maverickv2Executor;
MockERC20[] tokens; MockERC20[] tokens;
function setUp() public { function setUp() public {
@@ -109,8 +112,10 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper {
balancerv2Executor = new BalancerV2Executor(PERMIT2_ADDRESS); balancerv2Executor = new BalancerV2Executor(PERMIT2_ADDRESS);
ekuboExecutor = new EkuboExecutor(ekuboCore, PERMIT2_ADDRESS); ekuboExecutor = new EkuboExecutor(ekuboCore, PERMIT2_ADDRESS);
curveExecutor = new CurveExecutor(ETH_ADDR_FOR_CURVE, PERMIT2_ADDRESS); curveExecutor = new CurveExecutor(ETH_ADDR_FOR_CURVE, PERMIT2_ADDRESS);
maverickv2Executor =
new MaverickV2Executor(MAVERICK_V2_FACTORY, PERMIT2_ADDRESS);
address[] memory executors = new address[](7); address[] memory executors = new address[](8);
executors[0] = address(usv2Executor); executors[0] = address(usv2Executor);
executors[1] = address(usv3Executor); executors[1] = address(usv3Executor);
executors[2] = address(pancakev3Executor); executors[2] = address(pancakev3Executor);
@@ -118,6 +123,7 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper {
executors[4] = address(balancerv2Executor); executors[4] = address(balancerv2Executor);
executors[5] = address(ekuboExecutor); executors[5] = address(ekuboExecutor);
executors[6] = address(curveExecutor); executors[6] = address(curveExecutor);
executors[7] = address(maverickv2Executor);
return executors; return executors;
} }

View File

@@ -0,0 +1,28 @@
test_uniswap_v3_uniswap_v2:e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000bf00692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb8004375dff511095cc5a197a54140a24efef3a416cbcdf9626bc03e24f779434178a73a0b4bad62ed000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010500
test_single_encoding_strategy_ekubo:20144a070000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000071a0cb889707d426a7a386870a03bc70d1b069759805cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000000000000000000000000000000000
test_uniswap_v3_uniswap_v3:e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000100692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010000000000000000000000
test_balancer_v2_uniswap_v2:e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010300525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000
test_sequential_swap_strategy_encoder_no_permit2:e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000
test_sequential_encoding_strategy_usv4:51bcc7b6000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006838268800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004182b5da1843c415fd1304215c3049ced9c5e9b1f66463d5b035d67eb6fe8903de2564f5cb6740cdd838d7e497c61a75ccc572273a67e8c4b9e63f5f1ffc31e3bb1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000880086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f4000000000000000000000000000000000000000000000000
test_single_encoding_strategy_usv4_eth_out:7c55384600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006838268800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a0900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000418b43338a724ecb56c3c2ba7b10f26445ef901fa89fb585ad97771b24b87b2d71627d7dcd178bce3594dff4e4c024bd34c64ca33eda7ed6419c627e9a9b089e591c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300710001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c00000000000000000000000000
test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006838268800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411ddba9e27afa444896a84afcbd773cd492da98731f40e28243bf0aae4f345b7d44b7a6d220f7e5345055b7fe382114f0bf9f1ddb9e97987515880311f25f001b1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000200525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20105000000000000000000000000000000000000000000000000
test_single_swap_strategy_encoder_no_permit2:20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000
test_single_swap_strategy_encoder_no_transfer_in:20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006838268800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041657dbf542ed8b39f717c204413c77002d0d75fb3f81300bfef8eedf5889b55523868c42c0e2ef53fe7b82229ceceabe1b662201898043519d042e333c7492dad1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330105cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000
test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006838268800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041de5b09c674e85fef9de204fd3a03e190b1d06ebb6847543298183db02b46c0123c1433aec9951dfa391bc489c756816c4e87851882c8b4adbd21931490a820781b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000000000
test_single_encoding_strategy_curve_st_eth:20144a070000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010005cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006b56051582a970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041df0cad7d6d1228221ff55af2259877bbc38b6ef4af79f90757eab0576601a2f522e27881b929a5053eccb0d2fddc18db0bf3e905e407b5f17461e1bf64cbe70e1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200020000000000000000000000000000
test_single_encoding_strategy_curve:20144a070000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000103cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000
test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09100000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004148c4a9386769cda15972ca351ee585b996d184bcf3539441f103ca8477ddc35b4f34e91f490a181166440ceabe512ecc71bd00615ef5ba0ac5a7c58f2e0653511c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501020000000000000000000000000000
test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041ca7017e254f4fc333dbe49435283ee7d7bbf0ab261f79a3606848abbc7387dc2563fcdb32e670f1f80e729326d8d9973aef060a7f7e28d9c8ec2420cad05aa6f1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000
test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004177fcc3f010414cde9910d59346b7cac5341063addb7f041740fd0851cff3cd914b8b63c61edabe968f912b2ed17f273221a995d049e5d198384b5dbd00edb2011c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950102006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400000006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000
test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004177fcc3f010414cde9910d59346b7cac5341063addb7f041740fd0851cff3cd914b8b63c61edabe968f912b2ed17f273221a995d049e5d198384b5dbd00edb2011c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80102005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000
test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006838268900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a091000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041df0cad7d6d1228221ff55af2259877bbc38b6ef4af79f90757eab0576601a2f522e27881b929a5053eccb0d2fddc18db0bf3e905e407b5f17461e1bf64cbe70e1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950002005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950002005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20100005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010000000000000000000000000000000000000000000000000000000000
test_uniswap_v3_curve:e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000100691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000105cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000
test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf00000000000000000000000000000000000000000000000000000000000006838268a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006810a09200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041cf9d1ecdf2b9df43bdac811677440db893f99f04f5addb24c82b15d766c87e5c0091919a2c43ed9dc6fbd1237ce2bed73a3ea27cd638af11c1bb5673468e1d051b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501020072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010500691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001053ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598003ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000
test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0105
test_ekubo_encode_swap_multi:00ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032
test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c
test_encode_uniswap_v4_simple_swap:4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec7000064000001
test_single_encoding_strategy_maverick:20144a070000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000051a4ad4f68d0b91cfd19687c881e50f3a00242828c40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c67cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc201000000000000000000000000000000
test_encode_maverick_v2:40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c671d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e00

View File

@@ -1,8 +1,8 @@
// SPDX-License-Identifier: BUSL-1.1 // SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26; pragma solidity ^0.8.26;
import "../TestUtils.sol";
import "@src/executors/BalancerV2Executor.sol"; import "@src/executors/BalancerV2Executor.sol";
import {Test} from "../../lib/forge-std/src/Test.sol";
import {Constants} from "../Constants.sol"; import {Constants} from "../Constants.sol";
contract BalancerV2ExecutorExposed is BalancerV2Executor { contract BalancerV2ExecutorExposed is BalancerV2Executor {
@@ -24,7 +24,7 @@ contract BalancerV2ExecutorExposed is BalancerV2Executor {
} }
} }
contract BalancerV2ExecutorTest is Test, Constants { contract BalancerV2ExecutorTest is Constants, TestUtils {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
BalancerV2ExecutorExposed balancerV2Exposed; BalancerV2ExecutorExposed balancerV2Exposed;
@@ -96,10 +96,8 @@ contract BalancerV2ExecutorTest is Test, Constants {
} }
function testDecodeIntegration() public view { function testDecodeIntegration() public view {
// Generated by the SwapEncoder - test_encode_balancer_v2
bytes memory protocolData = bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0105"; loadCallDataFromFile("test_encode_balancer_v2");
( (
IERC20 tokenIn, IERC20 tokenIn,
IERC20 tokenOut, IERC20 tokenOut,
@@ -120,7 +118,7 @@ contract BalancerV2ExecutorTest is Test, Constants {
function testSwapIntegration() public { function testSwapIntegration() public {
// Generated by the SwapEncoder - test_encode_balancer_v2 // Generated by the SwapEncoder - test_encode_balancer_v2
bytes memory protocolData = bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0105"; loadCallDataFromFile("test_encode_balancer_v2");
uint256 amountIn = 10 ** 18; uint256 amountIn = 10 ** 18;
deal(WETH_ADDR, address(balancerV2Exposed), amountIn); deal(WETH_ADDR, address(balancerV2Exposed), amountIn);

View File

@@ -1,14 +1,15 @@
// SPDX-License-Identifier: BUSL-1.1 // SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26; pragma solidity ^0.8.26;
import {EkuboExecutor, TokenTransfer} from "@src/executors/EkuboExecutor.sol"; import "../TestUtils.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Constants} from "../Constants.sol"; import {Constants} from "../Constants.sol";
import {Test, console} from "forge-std/Test.sol"; import {EkuboExecutor, TokenTransfer} from "@src/executors/EkuboExecutor.sol";
import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
import {ICore} from "@ekubo/interfaces/ICore.sol"; import {ICore} from "@ekubo/interfaces/ICore.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
import {console} from "forge-std/Test.sol";
contract EkuboExecutorTest is Test, Constants { contract EkuboExecutorTest is Constants, TestUtils {
address constant EXECUTOR_ADDRESS = address constant EXECUTOR_ADDRESS =
0xcA4F73Fe97D0B987a0D12B39BBD562c779BAb6f6; // Same address as in swap_encoder.rs tests 0xcA4F73Fe97D0B987a0D12B39BBD562c779BAb6f6; // Same address as in swap_encoder.rs tests
EkuboExecutor executor; EkuboExecutor executor;
@@ -154,8 +155,6 @@ contract EkuboExecutorTest is Test, Constants {
// Data is generated by test case in swap_encoder::tests::ekubo::test_encode_swap_multi // Data is generated by test case in swap_encoder::tests::ekubo::test_encode_swap_multi
function testMultiHopSwapIntegration() public { function testMultiHopSwapIntegration() public {
multiHopSwap( multiHopSwap(loadCallDataFromFile("test_ekubo_encode_swap_multi"));
hex"00ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032"
);
} }
} }

View File

@@ -0,0 +1,128 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.26;
import "@src/executors/MaverickV2Executor.sol";
import {Constants} from "../Constants.sol";
import "../TestUtils.sol";
contract MaverickV2ExecutorExposed is MaverickV2Executor {
constructor(address _factory, address _permit2)
MaverickV2Executor(_factory, _permit2)
{}
function decodeParams(bytes calldata data)
external
pure
returns (
IERC20 tokenIn,
address target,
address receiver,
TransferType transferType
)
{
return _decodeData(data);
}
}
contract MaverickV2ExecutorTest is TestUtils, Constants {
using SafeERC20 for IERC20;
MaverickV2ExecutorExposed maverickV2Exposed;
IERC20 GHO = IERC20(GHO_ADDR);
IERC20 USDC = IERC20(USDC_ADDR);
function setUp() public {
uint256 forkBlock = 22096000;
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
maverickV2Exposed =
new MaverickV2ExecutorExposed(MAVERICK_V2_FACTORY, PERMIT2_ADDRESS);
}
function testDecodeParams() public view {
bytes memory params = abi.encodePacked(
GHO_ADDR,
GHO_USDC_POOL,
address(2),
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
);
(
IERC20 tokenIn,
address target,
address receiver,
TokenTransfer.TransferType transferType
) = maverickV2Exposed.decodeParams(params);
assertEq(address(tokenIn), GHO_ADDR);
assertEq(target, GHO_USDC_POOL);
assertEq(receiver, address(2));
assertEq(
uint8(transferType),
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
);
}
function testDecodeParamsInvalidDataLength() public {
bytes memory invalidParams =
abi.encodePacked(GHO_ADDR, GHO_USDC_POOL, address(2));
vm.expectRevert(MaverickV2Executor__InvalidDataLength.selector);
maverickV2Exposed.decodeParams(invalidParams);
}
function testSwap() public {
uint256 amountIn = 10e18;
bytes memory protocolData = abi.encodePacked(
GHO_ADDR,
GHO_USDC_POOL,
BOB,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
);
deal(GHO_ADDR, address(maverickV2Exposed), amountIn);
uint256 balanceBefore = USDC.balanceOf(BOB);
uint256 amountOut = maverickV2Exposed.swap(amountIn, protocolData);
uint256 balanceAfter = USDC.balanceOf(BOB);
assertGt(balanceAfter, balanceBefore);
assertEq(balanceAfter - balanceBefore, amountOut);
}
function testDecodeIntegration() public view {
// Generated by the SwapEncoder - test_encode_maverick_v2
bytes memory protocolData =
loadCallDataFromFile("test_encode_maverick_v2");
(
IERC20 tokenIn,
address pool,
address receiver,
TokenTransfer.TransferType transferType
) = maverickV2Exposed.decodeParams(protocolData);
assertEq(address(tokenIn), GHO_ADDR);
assertEq(pool, GHO_USDC_POOL);
assertEq(receiver, BOB);
assertEq(
uint8(transferType),
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
);
}
function testSwapIntegration() public {
// Generated by the SwapEncoder - test_encode_maverick_v2
bytes memory protocolData =
loadCallDataFromFile("test_encode_maverick_v2");
uint256 amountIn = 10 ** 18;
deal(GHO_ADDR, address(maverickV2Exposed), amountIn);
uint256 balanceBefore = USDC.balanceOf(BOB);
uint256 amountOut = maverickV2Exposed.swap(amountIn, protocolData);
uint256 balanceAfter = USDC.balanceOf(BOB);
assertGt(balanceAfter, balanceBefore);
assertEq(balanceAfter - balanceBefore, amountOut);
}
}

View File

@@ -247,7 +247,6 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
} }
function testDecodeIntegration() public view { function testDecodeIntegration() public view {
// Generated by the ExecutorStrategyEncoder - test_executor_strategy_encode
bytes memory protocolData = bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288e6a0c2ddd26feeb64f039a2c41296fcb3f564000000000000000000000000000000000000000010000"; hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc288e6a0c2ddd26feeb64f039a2c41296fcb3f564000000000000000000000000000000000000000010000";
@@ -268,7 +267,6 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
} }
function testSwapIntegration() public { function testSwapIntegration() public {
// Generated by the ExecutorStrategyEncoder - test_executor_strategy_encode
bytes memory protocolData = bytes memory protocolData =
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0000"; hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0000";
uint256 amountIn = 10 ** 18; uint256 amountIn = 10 ** 18;

View File

@@ -2,12 +2,13 @@
pragma solidity ^0.8.26; pragma solidity ^0.8.26;
import "../../src/executors/UniswapV4Executor.sol"; import "../../src/executors/UniswapV4Executor.sol";
import "../TestUtils.sol";
import "./UniswapV4Utils.sol"; import "./UniswapV4Utils.sol";
import "@src/executors/TokenTransfer.sol";
import "@src/executors/UniswapV4Executor.sol"; import "@src/executors/UniswapV4Executor.sol";
import {Constants} from "../Constants.sol"; import {Constants} from "../Constants.sol";
import {Test} from "../../lib/forge-std/src/Test.sol";
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol"; import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
import "@src/executors/TokenTransfer.sol"; import {Test} from "../../lib/forge-std/src/Test.sol";
contract UniswapV4ExecutorExposed is UniswapV4Executor { contract UniswapV4ExecutorExposed is UniswapV4Executor {
constructor(IPoolManager _poolManager, address _permit2) constructor(IPoolManager _poolManager, address _permit2)
@@ -30,7 +31,7 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
} }
} }
contract UniswapV4ExecutorTest is Test, Constants { contract UniswapV4ExecutorTest is Constants, TestUtils {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
UniswapV4ExecutorExposed uniswapV4Exposed; UniswapV4ExecutorExposed uniswapV4Exposed;
@@ -130,9 +131,8 @@ contract UniswapV4ExecutorTest is Test, Constants {
function testSingleSwapIntegration() public { function testSingleSwapIntegration() public {
// USDE -> USDT // USDE -> USDT
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_simple_swap
bytes memory protocolData = bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec7000064000001"; loadCallDataFromFile("test_encode_uniswap_v4_simple_swap");
uint256 amountIn = 100 ether; uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager);
@@ -188,10 +188,8 @@ contract UniswapV4ExecutorTest is Test, Constants {
function testMultipleSwapIntegration() public { function testMultipleSwapIntegration() public {
// USDE -> USDT -> WBTC // USDE -> USDT -> WBTC
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_sequential_swap
bytes memory protocolData = bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c"; loadCallDataFromFile("test_encode_uniswap_v4_sequential_swap");
uint256 amountIn = 100 ether; uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);

View File

@@ -20,7 +20,7 @@ pub static GROUPABLE_PROTOCOLS: LazyLock<HashSet<&'static str>> = LazyLock::new(
/// These protocols need an external in transfer to the pool. This transfer can be from the router, /// These protocols need an external in transfer to the pool. This transfer can be from the router,
/// from the user or from the previous pool. Any protocols that are not defined here expect funds to /// from the user or from the previous pool. Any protocols that are not defined here expect funds to
/// be in the router at the time of swap and do the transfer themselves from msg.sender /// be in the router at the time of swap and do the transfer themselves from `msg.sender`
pub static IN_TRANSFER_REQUIRED_PROTOCOLS: LazyLock<HashSet<&'static str>> = LazyLock::new(|| { pub static IN_TRANSFER_REQUIRED_PROTOCOLS: LazyLock<HashSet<&'static str>> = LazyLock::new(|| {
let mut set = HashSet::new(); let mut set = HashSet::new();
set.insert("uniswap_v2"); set.insert("uniswap_v2");
@@ -30,6 +30,7 @@ pub static IN_TRANSFER_REQUIRED_PROTOCOLS: LazyLock<HashSet<&'static str>> = Laz
set.insert("pancakeswap_v3"); set.insert("pancakeswap_v3");
set.insert("uniswap_v4"); set.insert("uniswap_v4");
set.insert("ekubo_v2"); set.insert("ekubo_v2");
set.insert("vm:maverick_v2");
set set
}); });

View File

@@ -654,7 +654,7 @@ mod tests {
}; };
use super::*; use super::*;
use crate::encoding::models::Swap; use crate::encoding::{evm::utils::write_calldata_to_file, models::Swap};
fn eth_chain() -> Chain { fn eth_chain() -> Chain {
TychoCommonChain::Ethereum.into() TychoCommonChain::Ethereum.into()
@@ -735,9 +735,9 @@ mod tests {
given_token: weth, given_token: weth,
given_amount: BigUint::from_str("1_000000000000000000").unwrap(), given_amount: BigUint::from_str("1_000000000000000000").unwrap(),
checked_token: dai, checked_token: dai,
expected_amount, expected_amount: expected_amount.clone(),
slippage, slippage,
checked_amount, checked_amount: checked_amount.clone(),
sender: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(), sender: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
receiver: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(), receiver: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
swaps: vec![swap], swaps: vec![swap],
@@ -776,10 +776,16 @@ mod tests {
"0000000000000000000000000000", // padding "0000000000000000000000000000", // padding
)); ));
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_swap_strategy_encoder: {hex_calldata}");
assert_eq!(hex_calldata[..456], expected_input); assert_eq!(hex_calldata[..456], expected_input);
assert_eq!(hex_calldata[1224..], expected_swap); assert_eq!(hex_calldata[1224..], expected_swap);
if expected_amount.is_some() & slippage.is_some() & checked_amount.is_none() {
// only write to file for 1 test case
write_calldata_to_file(
"test_single_swap_strategy_encoder",
&hex_calldata.to_string(),
);
}
} }
#[test] #[test]
@@ -858,7 +864,10 @@ mod tests {
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata, expected_input); assert_eq!(hex_calldata, expected_input);
println!("test_single_swap_strategy_encoder_no_permit2: {hex_calldata}"); write_calldata_to_file(
"test_single_swap_strategy_encoder_no_permit2",
hex_calldata.as_str(),
);
} }
#[test] #[test]
@@ -937,7 +946,10 @@ mod tests {
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata, expected_input); assert_eq!(hex_calldata, expected_input);
println!("test_single_swap_strategy_encoder_no_transfer_in: {hex_calldata}"); write_calldata_to_file(
"test_single_swap_strategy_encoder_no_transfer_in",
hex_calldata.as_str(),
);
} }
#[test] #[test]
@@ -990,7 +1002,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_swap_strategy_encoder_wrap: {hex_calldata}"); write_calldata_to_file("test_single_swap_strategy_encoder_wrap", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1043,7 +1055,10 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_split_swap_strategy_encoder_unwrap: {hex_calldata}"); write_calldata_to_file(
"test_single_swap_strategy_encoder_unwrap",
hex_calldata.as_str(),
);
} }
} }
@@ -1114,7 +1129,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_sequential_swap_strategy_encoder: {hex_calldata}"); write_calldata_to_file("test_sequential_swap_strategy_encoder", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1174,7 +1189,6 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_sequential_swap_strategy_encoder_no_permit2: {hex_calldata}");
let expected = String::from(concat!( let expected = String::from(concat!(
"e8a980d7", /* function selector */ "e8a980d7", /* function selector */
@@ -1208,6 +1222,10 @@ mod tests {
)); ));
assert_eq!(hex_calldata, expected); assert_eq!(hex_calldata, expected);
write_calldata_to_file(
"test_sequential_swap_strategy_encoder_no_permit2",
hex_calldata.as_str(),
);
} }
#[test] #[test]
@@ -1334,7 +1352,7 @@ mod tests {
assert_eq!(hex_calldata[..456], expected_input); assert_eq!(hex_calldata[..456], expected_input);
assert_eq!(hex_calldata[1224..], expected_swaps); assert_eq!(hex_calldata[1224..], expected_swaps);
println!("test_cyclic_sequential_swap_split_strategy: {hex_calldata}"); write_calldata_to_file("test_sequential_strategy_cyclic_swap", hex_calldata.as_str());
} }
mod optimized_transfers { mod optimized_transfers {
@@ -1412,7 +1430,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_uniswap_v3_uniswap_v2: {hex_calldata}"); write_calldata_to_file("test_uniswap_v3_uniswap_v2", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1494,7 +1512,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_uniswap_v3_uniswap_v3: {hex_calldata}"); write_calldata_to_file("test_uniswap_v3_uniswap_v3", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1580,7 +1598,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_uniswap_v3_curve: {hex_calldata}"); write_calldata_to_file("test_uniswap_v3_curve", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1647,7 +1665,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_balancer_v2_uniswap_v2: {hex_calldata}"); write_calldata_to_file("test_balancer_v2_uniswap_v2", hex_calldata.as_str());
} }
#[test] #[test]
@@ -1796,7 +1814,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("multi_protocol: {hex_calldata}"); write_calldata_to_file("test_multi_protocol", hex_calldata.as_str());
} }
} }
} }
@@ -1895,7 +1913,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_split_swap_strategy_encoder: {hex_calldata}"); write_calldata_to_file("test_split_swap_strategy_encoder", hex_calldata.as_str());
} }
#[test] #[test]
@@ -2062,7 +2080,7 @@ mod tests {
.join(""); .join("");
assert_eq!(hex_calldata[..520], expected_input); assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps); assert_eq!(hex_calldata[1288..], expected_swaps);
println!("test_split_input_cyclic_swap: {hex_calldata}"); write_calldata_to_file("test_split_input_cyclic_swap", hex_calldata.as_str());
} }
#[test] #[test]
@@ -2227,13 +2245,13 @@ mod tests {
assert_eq!(hex_calldata[..520], expected_input); assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps); assert_eq!(hex_calldata[1288..], expected_swaps);
println!("test_split_output_cyclic_swap: {hex_calldata}"); write_calldata_to_file("test_split_output_cyclic_swap", hex_calldata.as_str());
} }
} }
mod protocol_integration { mod protocol_integration {
// in this module we test protocol specific logic by creating the calldata that then is used // in this module we test protocol specific logic by creating the calldata that then is
// in the solidity tests // used in the solidity tests
use super::*; use super::*;
#[test] #[test]
@@ -2297,7 +2315,57 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_encoding_strategy_ekubo: {hex_calldata}"); write_calldata_to_file("test_single_encoding_strategy_ekubo", hex_calldata.as_str());
}
#[test]
fn test_single_encoding_strategy_maverick() {
// GHO -> (maverick) -> USDC
let maverick_pool = ProtocolComponent {
id: String::from("0x14Cf6D2Fe3E1B326114b07d22A6F6bb59e346c67"),
protocol_system: String::from("vm:maverick_v2"),
..Default::default()
};
let token_in = Bytes::from("0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f");
let token_out = Bytes::from("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
let swap = Swap {
component: maverick_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let swap_encoder_registry = get_swap_encoder_registry();
let encoder = SingleSwapStrategyEncoder::new(
eth_chain(),
swap_encoder_registry,
None,
Bytes::from_str("0xA4AD4f68d0b91CFD19687c881e50f3A00242828c").unwrap(),
false,
)
.unwrap();
let solution = Solution {
exact_out: false,
given_token: token_in,
given_amount: BigUint::from_str("1_000000000000000000").unwrap(),
checked_token: token_out,
expected_amount: None,
checked_amount: Some(BigUint::from_str("1000").unwrap()),
slippage: None,
// Alice
sender: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
receiver: Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2").unwrap(),
swaps: vec![swap],
..Default::default()
};
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
let hex_calldata = encode(&calldata);
write_calldata_to_file("test_single_encoding_strategy_maverick", hex_calldata.as_str());
} }
#[test] #[test]
@@ -2362,7 +2430,10 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_encoding_strategy_usv4_eth_in: {hex_calldata}"); write_calldata_to_file(
"test_single_encoding_strategy_usv4_eth_in",
hex_calldata.as_str(),
);
} }
#[test] #[test]
@@ -2431,7 +2502,10 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_encoding_strategy_usv4_eth_out: {hex_calldata}"); write_calldata_to_file(
"test_single_encoding_strategy_usv4_eth_out",
hex_calldata.as_str(),
);
} }
#[test] #[test]
@@ -2560,7 +2634,7 @@ mod tests {
assert_eq!(hex_calldata[..456], expected_input); assert_eq!(hex_calldata[..456], expected_input);
assert_eq!(hex_calldata[1224..], expected_swaps); assert_eq!(hex_calldata[1224..], expected_swaps);
println!("test_sequential_encoding_strategy_usv4: {hex_calldata}"); write_calldata_to_file("test_sequential_encoding_strategy_usv4", hex_calldata.as_str());
} }
#[test] #[test]
@@ -2568,7 +2642,7 @@ mod tests {
// UWU ──(curve 2 crypto pool)──> WETH // UWU ──(curve 2 crypto pool)──> WETH
let token_in = Bytes::from("0x55C08ca52497e2f1534B59E2917BF524D4765257"); // UWU let token_in = Bytes::from("0x55C08ca52497e2f1534B59E2917BF524D4765257"); // UWU
let token_out = Bytes::from("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); // USDC let token_out = Bytes::from("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); // WETH
let static_attributes = HashMap::from([( let static_attributes = HashMap::from([(
"factory".to_string(), "factory".to_string(),
@@ -2623,7 +2697,7 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_split_encoding_strategy_curve: {hex_calldata}"); write_calldata_to_file("test_single_encoding_strategy_curve", hex_calldata.as_str());
} }
#[test] #[test]
@@ -2686,7 +2760,10 @@ mod tests {
.unwrap(); .unwrap();
let hex_calldata = encode(&calldata); let hex_calldata = encode(&calldata);
println!("test_single_encoding_strategy_curve_st_eth: {hex_calldata}"); write_calldata_to_file(
"test_single_encoding_strategy_curve_st_eth",
hex_calldata.as_str(),
);
} }
} }
} }

View File

@@ -3,8 +3,8 @@ use std::collections::HashMap;
use crate::encoding::{ use crate::encoding::{
errors::EncodingError, errors::EncodingError,
evm::swap_encoder::swap_encoders::{ evm::swap_encoder::swap_encoders::{
BalancerV2SwapEncoder, CurveSwapEncoder, EkuboSwapEncoder, UniswapV2SwapEncoder, BalancerV2SwapEncoder, CurveSwapEncoder, EkuboSwapEncoder, MaverickV2SwapEncoder,
UniswapV3SwapEncoder, UniswapV4SwapEncoder, UniswapV2SwapEncoder, UniswapV3SwapEncoder, UniswapV4SwapEncoder,
}, },
models::Chain, models::Chain,
swap_encoder::SwapEncoder, swap_encoder::SwapEncoder,
@@ -76,6 +76,11 @@ impl SwapEncoderBuilder {
"vm:curve" => { "vm:curve" => {
Ok(Box::new(CurveSwapEncoder::new(self.executor_address, self.chain, self.config)?)) Ok(Box::new(CurveSwapEncoder::new(self.executor_address, self.chain, self.config)?))
} }
"vm:maverick_v2" => Ok(Box::new(MaverickV2SwapEncoder::new(
self.executor_address,
self.chain,
self.config,
)?)),
_ => Err(EncodingError::FatalError(format!( _ => Err(EncodingError::FatalError(format!(
"Unknown protocol system: {}", "Unknown protocol system: {}",
self.protocol_system self.protocol_system

View File

@@ -590,6 +590,49 @@ impl SwapEncoder for CurveSwapEncoder {
} }
} }
/// Encodes a swap on a Maverick V2 pool through the given executor address.
///
/// # Fields
/// * `executor_address` - The address of the executor contract that will perform the swap.
#[derive(Clone)]
pub struct MaverickV2SwapEncoder {
executor_address: String,
}
impl SwapEncoder for MaverickV2SwapEncoder {
fn new(
executor_address: String,
_chain: Chain,
_config: Option<HashMap<String, String>>,
) -> Result<Self, EncodingError> {
Ok(Self { executor_address })
}
fn encode_swap(
&self,
swap: Swap,
encoding_context: EncodingContext,
) -> Result<Vec<u8>, EncodingError> {
let component_id = AlloyBytes::from_str(&swap.component.id)
.map_err(|_| EncodingError::FatalError("Invalid component ID".to_string()))?;
let args = (
bytes_to_address(&swap.token_in)?,
component_id,
bytes_to_address(&encoding_context.receiver)?,
(encoding_context.transfer_type as u8).to_be_bytes(),
);
Ok(args.abi_encode_packed())
}
fn executor_address(&self) -> &str {
&self.executor_address
}
fn clone_box(&self) -> Box<dyn SwapEncoder> {
Box::new(self.clone())
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashMap; use std::collections::HashMap;
@@ -602,7 +645,7 @@ mod tests {
}; };
use super::*; use super::*;
use crate::encoding::models::TransferType; use crate::encoding::{evm::utils::write_calldata_to_file, models::TransferType};
mod uniswap_v2 { mod uniswap_v2 {
use super::*; use super::*;
@@ -721,6 +764,7 @@ mod tests {
mod balancer_v2 { mod balancer_v2 {
use super::*; use super::*;
use crate::encoding::evm::utils::write_calldata_to_file;
#[test] #[test]
fn test_encode_balancer_v2() { fn test_encode_balancer_v2() {
@@ -779,11 +823,13 @@ mod tests {
"05" "05"
)) ))
); );
write_calldata_to_file("test_encode_balancer_v2", hex_swap.as_str());
} }
} }
mod uniswap_v4 { mod uniswap_v4 {
use super::*; use super::*;
use crate::encoding::evm::utils::write_calldata_to_file;
#[test] #[test]
fn test_encode_uniswap_v4_simple_swap() { fn test_encode_uniswap_v4_simple_swap() {
@@ -830,7 +876,6 @@ mod tests {
.encode_swap(swap, encoding_context) .encode_swap(swap, encoding_context)
.unwrap(); .unwrap();
let hex_swap = encode(&encoded_swap); let hex_swap = encode(&encoded_swap);
println!("test_encode_uniswap_v4_simple_swap: {hex_swap}");
assert_eq!( assert_eq!(
hex_swap, hex_swap,
@@ -854,6 +899,7 @@ mod tests {
"000001" "000001"
)) ))
); );
write_calldata_to_file("test_encode_uniswap_v4_simple_swap", hex_swap.as_str());
} }
#[test] #[test]
@@ -1001,7 +1047,6 @@ mod tests {
let combined_hex = let combined_hex =
format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap)); format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap));
println!("test_encode_uniswap_v4_sequential_swap: {combined_hex}");
assert_eq!( assert_eq!(
combined_hex, combined_hex,
String::from(concat!( String::from(concat!(
@@ -1030,11 +1075,12 @@ mod tests {
"00003c" "00003c"
)) ))
); );
println!("{combined_hex}") write_calldata_to_file("test_encode_uniswap_v4_sequential_swap", combined_hex.as_str());
} }
} }
mod ekubo { mod ekubo {
use super::*; use super::*;
use crate::encoding::evm::utils::write_calldata_to_file;
const RECEIVER: &str = "ca4f73fe97d0b987a0d12b39bbd562c779bab6f6"; // Random address const RECEIVER: &str = "ca4f73fe97d0b987a0d12b39bbd562c779bab6f6"; // Random address
@@ -1159,7 +1205,6 @@ 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,
// transfer type // transfer type
@@ -1180,6 +1225,7 @@ mod tests {
"00000000000000000000000000000000000000000001a36e2eb1c43200000032", "00000000000000000000000000000000000000000001a36e2eb1c43200000032",
), ),
); );
write_calldata_to_file("test_ekubo_encode_swap_multi", combined_hex.as_str());
} }
} }
@@ -1497,4 +1543,59 @@ mod tests {
); );
} }
} }
#[test]
fn test_encode_maverick_v2() {
// GHO -> (maverick) -> USDC
let maverick_pool = ProtocolComponent {
id: String::from("0x14Cf6D2Fe3E1B326114b07d22A6F6bb59e346c67"),
protocol_system: String::from("vm:maverick_v2"),
..Default::default()
};
let token_in = Bytes::from("0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f");
let token_out = Bytes::from("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
let swap = Swap {
component: maverick_pool,
token_in: token_in.clone(),
token_out: token_out.clone(),
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver was generated with `makeAddr("bob") using forge`
receiver: Bytes::from("0x1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"),
exact_out: false,
router_address: Some(Bytes::default()),
group_token_in: token_in.clone(),
group_token_out: token_out.clone(),
transfer_type: TransferType::TransferToProtocol,
};
let encoder = MaverickV2SwapEncoder::new(
String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"),
TychoCoreChain::Ethereum.into(),
None,
)
.unwrap();
let encoded_swap = encoder
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
assert_eq!(
hex_swap,
String::from(concat!(
// token in
"40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f",
// pool
"14Cf6D2Fe3E1B326114b07d22A6F6bb59e346c67",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// transfer from router to protocol
"00",
))
.to_lowercase()
);
write_calldata_to_file("test_encode_maverick_v2", hex_swap.as_str());
}
} }

View File

@@ -25,6 +25,7 @@ use crate::encoding::{
/// * `split_swap_strategy`: Encoder for split swaps /// * `split_swap_strategy`: Encoder for split swaps
/// * `native_address`: Address of the chain's native token /// * `native_address`: Address of the chain's native token
/// * `wrapped_address`: Address of the chain's wrapped native token /// * `wrapped_address`: Address of the chain's wrapped native token
#[derive(Clone)]
pub struct TychoRouterEncoder { pub struct TychoRouterEncoder {
single_swap_strategy: SingleSwapStrategyEncoder, single_swap_strategy: SingleSwapStrategyEncoder,
sequential_swap_strategy: SequentialSwapStrategyEncoder, sequential_swap_strategy: SequentialSwapStrategyEncoder,
@@ -213,6 +214,7 @@ impl TychoEncoder for TychoRouterEncoder {
/// # Fields /// # Fields
/// * `swap_encoder_registry`: Registry of swap encoders /// * `swap_encoder_registry`: Registry of swap encoders
/// * `native_address`: Address of the chain's native token /// * `native_address`: Address of the chain's native token
#[derive(Clone)]
pub struct TychoExecutorEncoder { pub struct TychoExecutorEncoder {
swap_encoder_registry: SwapEncoderRegistry, swap_encoder_registry: SwapEncoderRegistry,
native_address: Bytes, native_address: Bytes,

View File

@@ -1,4 +1,10 @@
use std::{cmp::max, env, sync::Arc}; use std::{
cmp::max,
env,
fs::OpenOptions,
io::{BufRead, BufReader, Write},
sync::{Arc, Mutex},
};
use alloy::{ use alloy::{
providers::{ProviderBuilder, RootProvider}, providers::{ProviderBuilder, RootProvider},
@@ -7,6 +13,7 @@ use alloy::{
use alloy_primitives::{aliases::U24, keccak256, Address, FixedBytes, Keccak256, U256, U8}; use alloy_primitives::{aliases::U24, keccak256, Address, FixedBytes, Keccak256, U256, U8};
use alloy_sol_types::SolValue; use alloy_sol_types::SolValue;
use num_bigint::BigUint; use num_bigint::BigUint;
use once_cell::sync::Lazy;
use tokio::runtime::{Handle, Runtime}; use tokio::runtime::{Handle, Runtime};
use tycho_common::Bytes; use tycho_common::Bytes;
@@ -164,6 +171,51 @@ pub fn ple_encode(action_data_array: Vec<Vec<u8>>) -> Vec<u8> {
encoded_action_data encoded_action_data
} }
static CALLDATA_WRITE_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
// Function used in tests to write calldata to a file that then is used by the corresponding
// solidity tests.
pub fn write_calldata_to_file(test_identifier: &str, hex_calldata: &str) {
let _lock = CALLDATA_WRITE_MUTEX
.lock()
.expect("Couldn't acquire lock");
let file_path = "foundry/test/assets/calldata.txt";
let file = OpenOptions::new()
.read(true)
.open(file_path)
.expect("Failed to open calldata file for reading");
let reader = BufReader::new(file);
let mut lines = Vec::new();
let mut found = false;
for line in reader.lines().map_while(Result::ok) {
let mut parts = line.splitn(2, ':'); // split at the :
let key = parts.next().unwrap_or("");
if key == test_identifier {
lines.push(format!("{test_identifier}:{hex_calldata}"));
found = true;
} else {
lines.push(line);
}
}
// If the test identifier wasn't found, append a new line
if !found {
lines.push(format!("{test_identifier}:{hex_calldata}"));
}
// Write the updated contents back to the file
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(file_path)
.expect("Failed to open calldata file for writing");
for line in lines {
writeln!(file, "{line}").expect("Failed to write calldata");
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use num_bigint::BigUint; use num_bigint::BigUint;

View File

@@ -10,7 +10,7 @@ pub trait TychoEncoder {
/// ///
/// # Arguments /// # Arguments
/// * `solutions` - Vector of solutions to encode, each potentially using different setups (swap /// * `solutions` - Vector of solutions to encode, each potentially using different setups (swap
/// paths, protocols, etc.) /// paths, protocols, wrapping, etc.)
/// ///
/// # Returns /// # Returns
/// * `Result<Vec<Transaction>, EncodingError>` - Vector of executable transactions /// * `Result<Vec<Transaction>, EncodingError>` - Vector of executable transactions