test: add curve swap tests with pools from indexer
This commit is contained in:
committed by
Diana Carvalho
parent
93bdc86dc6
commit
c3d36ae25f
@@ -11,6 +11,7 @@ interface ICurveRouter {
|
||||
address receiver
|
||||
) external payable returns (uint256);
|
||||
|
||||
// slither-disable-next-line naming-convention
|
||||
function get_dy(
|
||||
address[] memory route,
|
||||
uint256[] memory swapParams,
|
||||
|
||||
@@ -5,6 +5,8 @@ import "@interfaces/IExecutor.sol";
|
||||
import "@interfaces/ICurveRouter.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
error CurveExecutor__InvalidAddresses();
|
||||
|
||||
contract CurveExecutor is IExecutor {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
@@ -12,6 +14,9 @@ contract CurveExecutor is IExecutor {
|
||||
address public immutable ethAddress;
|
||||
|
||||
constructor(address _curveRouter, address _ethAddress) {
|
||||
if (_curveRouter == address(0) || _ethAddress == address(0)) {
|
||||
revert CurveExecutor__InvalidAddresses();
|
||||
}
|
||||
curveRouter = ICurveRouter(_curveRouter);
|
||||
ethAddress = _ethAddress;
|
||||
}
|
||||
@@ -24,15 +29,16 @@ contract CurveExecutor is IExecutor {
|
||||
{
|
||||
CurveRouterParams memory params = _decodeData(data);
|
||||
if (params.route[0] != ethAddress) {
|
||||
// slither-disable-next-line unused-return
|
||||
IERC20(params.route[0]).approve(address(curveRouter), amountIn);
|
||||
|
||||
return curveRouter.exchange(
|
||||
params.route,
|
||||
params.swapParams,
|
||||
amountIn,
|
||||
params.minAmountOut,
|
||||
params.pools,
|
||||
params.receiver
|
||||
params.route,
|
||||
params.swapParams,
|
||||
amountIn,
|
||||
params.minAmountOut,
|
||||
params.pools,
|
||||
params.receiver
|
||||
);
|
||||
} else {
|
||||
return curveRouter.exchange{value: amountIn}(
|
||||
|
||||
@@ -46,6 +46,12 @@ contract Constants is Test, BaseConstants {
|
||||
address CRV_ADDR = address(0xD533a949740bb3306d119CC777fa900bA034cd52);
|
||||
address ADAI_ADDR = address(0x028171bCA77440897B824Ca71D1c56caC55b68A3);
|
||||
address AUSDC_ADDR = address(0xBcca60bB61934080951369a648Fb03DF4F96263C);
|
||||
address SUSD_ADDR = address(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51);
|
||||
address FRAX_ADDR = address(0x853d955aCEf822Db058eb8505911ED77F175b99e);
|
||||
address DOLA_ADDR = address(0x865377367054516e17014CcdED1e7d814EDC9ce4);
|
||||
address XYO_ADDR = address(0x55296f69f40Ea6d20E478533C15A6B08B654E758);
|
||||
address UWU_ADDR = address(0x55C08ca52497e2f1534B59E2917BF524D4765257);
|
||||
address CRVUSD_ADDR = address(0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E);
|
||||
|
||||
// Uniswap v2
|
||||
address WETH_DAI_POOL = 0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11;
|
||||
@@ -102,6 +108,20 @@ contract Constants is Test, BaseConstants {
|
||||
// AAVE - Pool type 0
|
||||
address AAVE_POOL = 0xDeBF20617708857ebe4F679508E7b7863a8A8EeE;
|
||||
|
||||
// BASE META POOL
|
||||
address FRAXPYUSD_ADDR = address(0xA5588F7cdf560811710A2D82D3C9c99769DB1Dcb);
|
||||
|
||||
// Curve pools taken from the substreams
|
||||
address TRICRYPTO_USDT_WETH_WBTC =
|
||||
0xD51a44d3FaE010294C616388b506AcdA1bfAAE46;
|
||||
address SUSD_POOL = 0xA5407eAE9Ba41422680e2e00537571bcC53efBfD;
|
||||
address FRAX_USDC_POOL = 0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2;
|
||||
address USDE_USDC_POOL = 0x02950460E2b9529D0E00284A5fA2d7bDF3fA4d72;
|
||||
address DOLA_FRAXPYUSD_POOL = 0xef484de8C07B6e2d732A92B5F78e81B38f99f95E;
|
||||
address WETH_XYO_POOL = 0x99e09ee2d6Bb16c0F5ADDfEA649dbB2C1d524624;
|
||||
address UWU_WETH_POOL = 0x77146B0a1d08B6844376dF6d9da99bA7F1b19e71;
|
||||
address CRVUSD_USDT_POOL = 0x390f3595bCa2Df7d23783dFd126427CCeb997BF4;
|
||||
|
||||
// Uniswap universal router
|
||||
address UNIVERSAL_ROUTER = 0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af;
|
||||
|
||||
@@ -123,6 +143,9 @@ contract Constants is Test, BaseConstants {
|
||||
// Curve router
|
||||
address CURVE_ROUTER = 0x16C6521Dff6baB339122a0FE25a9116693265353;
|
||||
|
||||
// Curve meta registry
|
||||
address CURVE_META_REGISTRY = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC;
|
||||
|
||||
/**
|
||||
* @dev Deploys a dummy contract with non-empty bytecode
|
||||
*/
|
||||
|
||||
@@ -5,11 +5,18 @@ import "@src/executors/CurveExecutor.sol";
|
||||
import {Test} from "../../lib/forge-std/src/Test.sol";
|
||||
import {Constants} from "../Constants.sol";
|
||||
|
||||
|
||||
interface ICurvePool {
|
||||
function coins(uint256 i) external view returns (address);
|
||||
}
|
||||
|
||||
interface MetaRegistry {
|
||||
function get_n_coins(address pool) external view returns (uint256);
|
||||
function get_coin_indices(address pool, address from, address to)
|
||||
external
|
||||
view
|
||||
returns (int128, int128, bool);
|
||||
}
|
||||
|
||||
interface ILendingPool {
|
||||
function deposit(
|
||||
address asset,
|
||||
@@ -24,7 +31,9 @@ interface ILendingPool {
|
||||
}
|
||||
|
||||
contract CurveExecutorExposed is CurveExecutor {
|
||||
constructor(address _curveRouter, address _ethAddress) CurveExecutor(_curveRouter, _ethAddress) {}
|
||||
constructor(address _curveRouter, address _ethAddress)
|
||||
CurveExecutor(_curveRouter, _ethAddress)
|
||||
{}
|
||||
|
||||
function decodeParams(bytes calldata data)
|
||||
external
|
||||
@@ -39,11 +48,13 @@ contract CurveExecutorTest is Test, Constants {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
CurveExecutorExposed curveExecutorExposed;
|
||||
MetaRegistry metaRegistry;
|
||||
|
||||
function setUp() public {
|
||||
uint256 forkBlock = 22031795;
|
||||
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
|
||||
curveExecutorExposed = new CurveExecutorExposed(CURVE_ROUTER, ETH_ADDR);
|
||||
metaRegistry = MetaRegistry(CURVE_META_REGISTRY);
|
||||
}
|
||||
|
||||
function testDecodeParams() public view {
|
||||
@@ -79,10 +90,10 @@ contract CurveExecutorTest is Test, Constants {
|
||||
assertEq(params.swapParams[0][3], 3);
|
||||
}
|
||||
|
||||
|
||||
function testCurveSwapPoolType0() public {
|
||||
address[11] memory route = _getRoute(ADAI_ADDR, AUSDC_ADDR, AAVE_POOL);
|
||||
uint256[5][5] memory swapParams = _getSwapParams(AAVE_POOL, ADAI_ADDR, AUSDC_ADDR, 1, 1);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(AAVE_POOL, ADAI_ADDR, AUSDC_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
@@ -90,16 +101,24 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
dealAaveDai();
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 999734);
|
||||
assertEq(IERC20(AUSDC_ADDR).balanceOf(address(curveExecutorExposed)), amountOut);
|
||||
assertEq(
|
||||
IERC20(AUSDC_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapPoolType1() public {
|
||||
function testCurveSwapPoolType1() public {
|
||||
address[11] memory route =
|
||||
_getRoute(DAI_ADDR, USDC_ADDR, TRIPOOL_USDT_USDC_DAI);
|
||||
uint256[5][5] memory swapParams =
|
||||
@@ -142,8 +161,7 @@ contract CurveExecutorTest is Test, Constants {
|
||||
}
|
||||
|
||||
function testCurveSwapPoolType4() public {
|
||||
address[11] memory route =
|
||||
_getRoute(ETH_ADDR, STETH_ADDR, STETH_POOL);
|
||||
address[11] memory route = _getRoute(ETH_ADDR, STETH_ADDR, STETH_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(STETH_POOL, ETH_ADDR, STETH_ADDR, 1, 1);
|
||||
|
||||
@@ -153,40 +171,45 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
deal(address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data
|
||||
);
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertTrue(amountOut >= 1 ether);
|
||||
assertEq(IERC20(STETH_ADDR).balanceOf(address(curveExecutorExposed)), amountOut - 1); // Gets 1 wei less than amountOut
|
||||
assertEq(
|
||||
IERC20(STETH_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut - 1
|
||||
); // Gets 1 wei less than amountOut
|
||||
|
||||
// Now reverse the swap
|
||||
amountIn = amountOut - 1;
|
||||
route =
|
||||
_getRoute(STETH_ADDR, ETH_ADDR, STETH_POOL);
|
||||
swapParams =
|
||||
_getSwapParams(STETH_POOL, STETH_ADDR, ETH_ADDR, 1, 1);
|
||||
route = _getRoute(STETH_ADDR, ETH_ADDR, STETH_POOL);
|
||||
swapParams = _getSwapParams(STETH_POOL, STETH_ADDR, ETH_ADDR, 1, 1);
|
||||
|
||||
data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data
|
||||
);
|
||||
amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(address(curveExecutorExposed).balance, 999800010006950374);
|
||||
}
|
||||
|
||||
|
||||
function testCurveSwapPoolType5() public {
|
||||
address[11] memory route =
|
||||
_getRoute(LUSD_ADDR, USDT_ADDR, LUSD_POOL);
|
||||
address[11] memory route = _getRoute(LUSD_ADDR, USDT_ADDR, LUSD_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(LUSD_POOL, LUSD_ADDR, USDT_ADDR, 2, 1);
|
||||
_getSwapParams(LUSD_POOL, LUSD_ADDR, USDT_ADDR, 2, 1);
|
||||
|
||||
// pool.coins(index) reverts, defaulting tokenOut index to 0
|
||||
swapParams[0][1] = 3;
|
||||
@@ -197,24 +220,28 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
deal(LUSD_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data
|
||||
);
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 1001785);
|
||||
assertEq(IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)), amountOut);
|
||||
assertEq(
|
||||
IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function testCurveSwapPoolType6() public {
|
||||
address[11] memory route =
|
||||
_getRoute(DAI_ADDR, USDC_ADDR, CPOOL);
|
||||
address[11] memory route = _getRoute(DAI_ADDR, USDC_ADDR, CPOOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(CPOOL, DAI_ADDR, USDC_ADDR, 2, 1);
|
||||
|
||||
_getSwapParams(CPOOL, DAI_ADDR, USDC_ADDR, 2, 1);
|
||||
|
||||
// pool.coins(index) reverts, defaulting tokenOut index to 0
|
||||
swapParams[0][1] = 1;
|
||||
|
||||
@@ -224,19 +251,27 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
deal(DAI_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data);
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 999549);
|
||||
assertEq(IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)), amountOut);
|
||||
assertEq(
|
||||
IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapPoolType7() public {
|
||||
address[11] memory route = _getRoute(WETH_ADDR, LDO_ADDR, LDO_POOL);
|
||||
uint256[5][5] memory swapParams = _getSwapParams(LDO_POOL, WETH_ADDR, LDO_ADDR, 1, 4);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(LDO_POOL, WETH_ADDR, LDO_ADDR, 1, 4);
|
||||
|
||||
// pool.coins(index) reverts, defaulting tokenOut index to 0
|
||||
swapParams[0][1] = 1;
|
||||
@@ -247,20 +282,33 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 2075236672516568049094);
|
||||
assertEq(IERC20(LDO_ADDR).balanceOf(address(curveExecutorExposed)), amountOut);
|
||||
assertEq(
|
||||
IERC20(LDO_ADDR).balanceOf(address(curveExecutorExposed)), amountOut
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function testCurveSwapPoolType8() public {
|
||||
address[11] memory route = _getRoute(CRV_ADDR, WETH_ADDR, CRV_POOL);
|
||||
uint256[5][5] memory swapParams = _getSwapParams(CRV_POOL, CRV_ADDR, WETH_ADDR, 1, 4);
|
||||
|
||||
// The registry does not have information about the pool.
|
||||
// We manually set the swap params.
|
||||
uint256[5][5] memory swapParams;
|
||||
swapParams[0][0] = 1;
|
||||
swapParams[0][1] = 0;
|
||||
swapParams[0][2] = 1;
|
||||
swapParams[0][3] = 4;
|
||||
swapParams[0][4] = 2;
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
@@ -268,20 +316,253 @@ contract CurveExecutorTest is Test, Constants {
|
||||
|
||||
deal(CRV_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed)
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(
|
||||
amountIn, data);
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 21806692849);
|
||||
assertEq(IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)), amountOut);
|
||||
assertEq(
|
||||
IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
/// These tests are taken from the substreams
|
||||
|
||||
function testCurveSwapTricrypto2() public {
|
||||
address[11] memory route =
|
||||
_getRoute(WETH_ADDR, WBTC_ADDR, TRICRYPTO_USDT_WETH_WBTC);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(TRICRYPTO_USDT_WETH_WBTC, WETH_ADDR, WBTC_ADDR, 1, 3);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 2279618);
|
||||
assertEq(
|
||||
IERC20(WBTC_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapSUSD() public {
|
||||
address[11] memory route = _getRoute(USDC_ADDR, SUSD_ADDR, SUSD_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(SUSD_POOL, USDC_ADDR, SUSD_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 100 * 10 ** 6;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 100488101605550214590);
|
||||
assertEq(
|
||||
IERC20(SUSD_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapFraxUSDC() public {
|
||||
address[11] memory route =
|
||||
_getRoute(FRAX_ADDR, USDC_ADDR, FRAX_USDC_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(FRAX_USDC_POOL, FRAX_ADDR, USDC_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(FRAX_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 998096);
|
||||
assertEq(
|
||||
IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapCryptoSwapNGFactoryPlainPool() public {
|
||||
address[11] memory route =
|
||||
_getRoute(USDC_ADDR, USDE_ADDR, USDE_USDC_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(USDE_USDC_POOL, USDC_ADDR, USDE_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 100 * 10 ** 6;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 100064812138999986170);
|
||||
assertEq(
|
||||
IERC20(USDE_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapMetaPool() public {
|
||||
address[11] memory route =
|
||||
_getRoute(DOLA_ADDR, FRAXPYUSD_ADDR, DOLA_FRAXPYUSD_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(DOLA_FRAXPYUSD_POOL, DOLA_ADDR, FRAXPYUSD_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 100 * 10 ** 6;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(DOLA_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 99688991);
|
||||
assertEq(
|
||||
IERC20(FRAXPYUSD_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapWethXyo() public {
|
||||
address[11] memory route = _getRoute(XYO_ADDR, WETH_ADDR, WETH_XYO_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(WETH_XYO_POOL, XYO_ADDR, WETH_ADDR, 1, 2);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(XYO_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 6081816039338);
|
||||
assertEq(
|
||||
IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapUwuWeth() public {
|
||||
address[11] memory route = _getRoute(UWU_ADDR, WETH_ADDR, UWU_WETH_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(UWU_WETH_POOL, UWU_ADDR, WETH_ADDR, 1, 2);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(UWU_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 2873786684675);
|
||||
assertEq(
|
||||
IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function testCurveSwapStableSwapFactoryPlainPool() public {
|
||||
address[11] memory route =
|
||||
_getRoute(CRVUSD_ADDR, USDT_ADDR, CRVUSD_USDT_POOL);
|
||||
uint256[5][5] memory swapParams =
|
||||
_getSwapParams(CRVUSD_USDT_POOL, CRVUSD_ADDR, USDT_ADDR, 1, 1);
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
uint256 minAmountOut = 0;
|
||||
address[5] memory pools;
|
||||
|
||||
deal(CRVUSD_ADDR, address(curveExecutorExposed), amountIn);
|
||||
bytes memory data = abi.encode(
|
||||
route,
|
||||
swapParams,
|
||||
amountIn,
|
||||
minAmountOut,
|
||||
pools,
|
||||
address(curveExecutorExposed)
|
||||
);
|
||||
|
||||
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
|
||||
|
||||
assertEq(amountOut, 999910);
|
||||
assertEq(
|
||||
IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)),
|
||||
amountOut
|
||||
);
|
||||
}
|
||||
|
||||
function _getRoute(address tokenIn, address tokenOut, address pool)
|
||||
internal
|
||||
@@ -300,43 +581,27 @@ contract CurveExecutorTest is Test, Constants {
|
||||
uint256 swapType,
|
||||
uint256 poolType
|
||||
) internal view returns (uint256[5][5] memory swapParams) {
|
||||
// Get number of coins in pool and their indices
|
||||
uint256 coinInIndex;
|
||||
uint256 coinOutIndex;
|
||||
uint256 nCoins;
|
||||
address lastCoinAddress = address(1);
|
||||
while (lastCoinAddress != address(0)) {
|
||||
try ICurvePool(pool).coins(nCoins) returns (address coin) {
|
||||
lastCoinAddress = coin;
|
||||
nCoins++;
|
||||
if (coin == tokenIn) {
|
||||
coinInIndex = nCoins - 1;
|
||||
}
|
||||
if (coin == tokenOut) {
|
||||
coinOutIndex = nCoins - 1;
|
||||
}
|
||||
} catch {
|
||||
lastCoinAddress = address(0);
|
||||
}
|
||||
}
|
||||
uint256 nCoins = metaRegistry.get_n_coins(pool);
|
||||
(int128 coinInIndex, int128 coinOutIndex, bool isMetapool) =
|
||||
metaRegistry.get_coin_indices(pool, tokenIn, tokenOut);
|
||||
|
||||
swapParams[0][0] = coinInIndex;
|
||||
swapParams[0][1] = coinOutIndex;
|
||||
swapParams[0][0] = uint256(int256(coinInIndex));
|
||||
swapParams[0][1] = uint256(int256(coinOutIndex));
|
||||
swapParams[0][2] = swapType;
|
||||
swapParams[0][3] = poolType;
|
||||
swapParams[0][4] = nCoins;
|
||||
}
|
||||
|
||||
|
||||
function dealAaveDai() internal {
|
||||
deal(DAI_ADDR, address(curveExecutorExposed), 100_000 * 10 ** 18);
|
||||
function dealAaveDai() internal {
|
||||
deal(DAI_ADDR, address(curveExecutorExposed), 100_000 * 10 ** 18);
|
||||
ILendingPool aave =
|
||||
ILendingPool(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9);
|
||||
|
||||
vm.startPrank(address(curveExecutorExposed));
|
||||
IERC20(DAI_ADDR).approve(address(aave), type(uint256).max);
|
||||
aave.deposit(DAI_ADDR, 100_000 * 10 ** 18, address(curveExecutorExposed), 0);
|
||||
aave.deposit(
|
||||
DAI_ADDR, 100_000 * 10 ** 18, address(curveExecutorExposed), 0
|
||||
);
|
||||
vm.stopPrank();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user