mirror of
https://github.com/lux-amm/v4-periphery.git
synced 2026-10-30 20:54:39 +00:00
376 lines
15 KiB
Solidity
376 lines
15 KiB
Solidity
// SPDX-License-Identifier: UNLICENSED
|
|
pragma solidity ^0.8.19;
|
|
|
|
import {Currency, CurrencyLibrary} from "@luxamm/v4-core/src/types/Currency.sol";
|
|
|
|
import {IV4Router} from "../../src/interfaces/IV4Router.sol";
|
|
import {RoutingTestHelpers} from "../shared/RoutingTestHelpers.sol";
|
|
import {Planner} from "../shared/Planner.sol";
|
|
import {Actions} from "../../src/libraries/Actions.sol";
|
|
import {ActionConstants} from "../../src/libraries/ActionConstants.sol";
|
|
|
|
contract V4RouterTest is RoutingTestHelpers {
|
|
function setUp() public {
|
|
setupRouterCurrenciesAndPoolsWithLiquidity();
|
|
plan = Planner.init();
|
|
}
|
|
|
|
function test_gas_bytecodeSize() public {
|
|
vm.snapshotValue("V4Router_Bytecode", address(router).code.length);
|
|
}
|
|
|
|
function test_router_initcodeHash() public {
|
|
vm.snapshotValue(
|
|
"router initcode hash (without constructor params, as uint256)",
|
|
uint256(keccak256(abi.encodePacked(vm.getCode("MockV4Router.sol:MockV4Router"))))
|
|
);
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////
|
|
ERC20 -> ERC20 EXACT INPUT
|
|
//////////////////////////////////////////////////////////////*/
|
|
|
|
function test_gas_swapExactInputSingle_zeroForOne() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
IV4Router.ExactInputSingleParams memory params =
|
|
IV4Router.ExactInputSingleParams(key0, true, uint128(amountIn), 0, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(key0.currency0, key0.currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactInputSingle");
|
|
}
|
|
|
|
function test_gas_swapExactIn_1Hop_zeroForOne() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn1Hop_zeroForOne");
|
|
}
|
|
|
|
function test_gas_swapExactIn_1Hop_oneForZero() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency0);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency1, currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn1Hop_oneForZero");
|
|
}
|
|
|
|
function test_gas_swapExactIn_2Hops() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency2, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn2Hops");
|
|
}
|
|
|
|
function test_gas_swapExactIn_3Hops() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
tokenPath.push(currency3);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency3, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn3Hops");
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////
|
|
ETH -> ERC20 and ERC20 -> ETH EXACT INPUT
|
|
//////////////////////////////////////////////////////////////*/
|
|
|
|
function test_gas_nativeIn_swapExactInputSingle() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
IV4Router.ExactInputSingleParams memory params =
|
|
IV4Router.ExactInputSingleParams(nativeKey, true, uint128(amountIn), 0, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(nativeKey.currency0, nativeKey.currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions{value: amountIn}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactInputSingle_nativeIn");
|
|
}
|
|
|
|
function test_gas_nativeOut_swapExactInputSingle() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
IV4Router.ExactInputSingleParams memory params =
|
|
IV4Router.ExactInputSingleParams(nativeKey, false, uint128(amountIn), 0, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(nativeKey.currency1, nativeKey.currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactInputSingle_nativeOut");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactIn_1Hop() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions{value: amountIn}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn1Hop_nativeIn");
|
|
}
|
|
|
|
function test_gas_nativeOut_swapExactIn_1Hop() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, CurrencyLibrary.ADDRESS_ZERO, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn1Hop_nativeOut");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactIn_2Hops() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions{value: amountIn}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn2Hops_nativeIn");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactIn_3Hops() public {
|
|
uint256 amountIn = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
IV4Router.ExactInputParams memory params = _getExactInputParams(tokenPath, amountIn);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_IN, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency2, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions{value: amountIn}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactIn3Hops_nativeIn");
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////
|
|
ERC20 -> ERC20 EXACT OUTPUT
|
|
//////////////////////////////////////////////////////////////*/
|
|
|
|
function test_gas_swapExactOutputSingle_zeroForOne() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
IV4Router.ExactOutputSingleParams memory params =
|
|
IV4Router.ExactOutputSingleParams(key0, true, uint128(amountOut), type(uint128).max, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(key0.currency0, key0.currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOutputSingle");
|
|
}
|
|
|
|
function test_gas_swapExactOut_1Hop_zeroForOne() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut1Hop_zeroForOne");
|
|
}
|
|
|
|
function test_gas_swapExactOut_1Hop_oneForZero() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency0);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency1, currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut1Hop_oneForZero");
|
|
}
|
|
|
|
function test_gas_swapExactOut_2Hops() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency2, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut2Hops");
|
|
}
|
|
|
|
function test_gas_swapExactOut_3Hops() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
tokenPath.push(currency3);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, currency3, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut3Hops");
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////
|
|
ETH -> ERC20 and ERC20 -> ETH EXACT OUTPUT
|
|
//////////////////////////////////////////////////////////////*/
|
|
|
|
function test_gas_nativeIn_swapExactOutputSingle_sweepExcessETH() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
IV4Router.ExactOutputSingleParams memory params =
|
|
IV4Router.ExactOutputSingleParams(nativeKey, true, uint128(amountOut), type(uint128).max, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(nativeKey.currency0, nativeKey.currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActionsAndSweepExcessETH{value: 2 ether}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOutputSingle_nativeIn_sweepETH");
|
|
}
|
|
|
|
function test_gas_nativeOut_swapExactOutputSingle() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
IV4Router.ExactOutputSingleParams memory params =
|
|
IV4Router.ExactOutputSingleParams(nativeKey, false, uint128(amountOut), type(uint128).max, 0, bytes(""));
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT_SINGLE, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(nativeKey.currency1, nativeKey.currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActionsAndSweepExcessETH(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOutputSingle_nativeOut");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactOut_1Hop_sweepExcessETH() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency0, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActionsAndSweepExcessETH{value: 2 ether}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut1Hop_nativeIn_sweepETH");
|
|
}
|
|
|
|
function test_gas_nativeOut_swapExactOut_1Hop() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency0, CurrencyLibrary.ADDRESS_ZERO, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut1Hop_nativeOut");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactOut_2Hops_sweepExcessETH() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency1, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActionsAndSweepExcessETH{value: 2 ether}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut2Hops_nativeIn");
|
|
}
|
|
|
|
function test_gas_nativeIn_swapExactOut_3Hops_sweepExcessETH() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency2);
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(CurrencyLibrary.ADDRESS_ZERO, currency2, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActionsAndSweepExcessETH{value: 2 ether}(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut3Hops_nativeIn");
|
|
}
|
|
|
|
function test_gas_nativeOut_swapExactOut_3Hops() public {
|
|
uint256 amountOut = 1 ether;
|
|
|
|
tokenPath.push(currency2);
|
|
tokenPath.push(currency1);
|
|
tokenPath.push(currency0);
|
|
tokenPath.push(CurrencyLibrary.ADDRESS_ZERO);
|
|
|
|
IV4Router.ExactOutputParams memory params = _getExactOutputParams(tokenPath, amountOut);
|
|
|
|
plan = plan.add(Actions.SWAP_EXACT_OUT, abi.encode(params));
|
|
bytes memory data = plan.finalizeSwap(currency2, CurrencyLibrary.ADDRESS_ZERO, ActionConstants.MSG_SENDER);
|
|
|
|
router.executeActions(data);
|
|
vm.snapshotGasLastCall("V4Router_ExactOut3Hops_nativeOut");
|
|
}
|
|
}
|