feat: Support Curve ETH

Curve pools use a different address from ETH (native token)

- Pass Chain into the SwapEncoderBuilder and SwapEncoder
- Add native_token_curve_address and native_token_address to CurveSwapEncoder
- Added integration test for this curve case

--- don't change below this line ---
ENG-4306 Took 1 hour 4 minutes


Took 11 seconds
This commit is contained in:
Diana Carvalho
2025-04-07 09:20:38 +01:00
parent 1838ccf8a1
commit 913d677ffb
10 changed files with 270 additions and 71 deletions

View File

@@ -4,7 +4,7 @@ pragma solidity ^0.8.26;
import "@interfaces/IExecutor.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
error CurveExecutor__InvalidAddresses();
error CurveExecutor__AddressZero();
interface CryptoPool {
// slither-disable-next-line naming-convention
@@ -39,7 +39,7 @@ contract CurveExecutor is IExecutor {
constructor(address _nativeToken) {
if (_nativeToken == address(0)) {
revert CurveExecutor__InvalidAddresses();
revert CurveExecutor__AddressZero();
}
nativeToken = _nativeToken;
}

View File

@@ -30,7 +30,8 @@ contract Constants is Test, BaseConstants {
address UNPAUSER = makeAddr("unpauser");
// Assets
address ETH_ADDR = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
address ETH_ADDR_FOR_CURVE =
address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
address WETH_ADDR = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
address DAI_ADDR = address(0x6B175474E89094C44Da98b954EedeAC495271d0F);
address BAL_ADDR = address(0xba100000625a3754423978a60c9317c58a424e3D);

View File

@@ -1461,4 +1461,18 @@ contract TychoRouterTest is TychoRouterTestSetup {
vm.stopPrank();
}
function testCurveIntegrationStETH() public {
deal(ALICE, 1 ether);
vm.startPrank(ALICE);
// Encoded solution generated using `test_split_encoding_strategy_curve_st_eth`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"0a83cb080000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000005b005900010000001d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f67022010001000000000000"
);
assertEq(IERC20(STETH_ADDR).balanceOf(ALICE), 1000754689941529590);
vm.stopPrank();
}
}

View File

@@ -98,7 +98,7 @@ contract TychoRouterTestSetup is Test, Constants {
new UniswapV3Executor(factoryPancakeV3, initCodePancakeV3);
balancerv2Executor = new BalancerV2Executor();
ekuboExecutor = new EkuboExecutor(ekuboCore);
curveExecutor = new CurveExecutor(ETH_ADDR);
curveExecutor = new CurveExecutor(ETH_ADDR_FOR_CURVE);
address[] memory executors = new address[](7);
executors[0] = address(usv2Executor);

View File

@@ -50,7 +50,7 @@ contract CurveExecutorTest is Test, Constants {
function setUp() public {
uint256 forkBlock = 22031795;
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
curveExecutorExposed = new CurveExecutorExposed(ETH_ADDR);
curveExecutorExposed = new CurveExecutorExposed(ETH_ADDR_FOR_CURVE);
metaRegistry = MetaRegistry(CURVE_META_REGISTRY);
}
@@ -105,7 +105,8 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(address(curveExecutorExposed), amountIn);
bytes memory data = _getData(ETH_ADDR, STETH_ADDR, STETH_POOL, 1);
bytes memory data =
_getData(ETH_ADDR_FOR_CURVE, STETH_ADDR, STETH_POOL, 1);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
@@ -203,7 +204,8 @@ contract CurveExecutorTest is Test, Constants {
uint256 initialBalance = address(curveExecutorExposed).balance; // this address already has some ETH assigned to it
deal(XYO_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(XYO_ADDR, ETH_ADDR, ETH_XYO_POOL, 2);
bytes memory data =
_getData(XYO_ADDR, ETH_ADDR_FOR_CURVE, ETH_XYO_POOL, 2);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);