Skip to content

Commit

Permalink
Call initialize directly
Browse files Browse the repository at this point in the history
hensha256 committed Oct 16, 2024

Verified

This commit was signed with the committer’s verified signature.
hensha256 Alice
1 parent 696d96d commit ef8bb2f
Showing 12 changed files with 70 additions and 98 deletions.
12 changes: 10 additions & 2 deletions contracts/base/Dispatcher.sol
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ import {ERC20} from 'solmate/src/tokens/ERC20.sol';
import {IAllowanceTransfer} from 'permit2/src/interfaces/IAllowanceTransfer.sol';
import {ActionConstants} from '@uniswap/v4-periphery/src/libraries/ActionConstants.sol';
import {CalldataDecoder} from '@uniswap/v4-periphery/src/libraries/CalldataDecoder.sol';
import {PoolKey} from '@uniswap/v4-core/src/types/PoolKey.sol';
import {IPoolManager} from '@uniswap/v4-core/src/interfaces/IPoolManager.sol';

/// @title Decodes and Executes Commands
/// @notice Called by the UniversalRouter contract to efficiently decode and execute a singular command
@@ -240,8 +242,14 @@ abstract contract Dispatcher is Payments, V2SwapRouter, V3SwapRouter, V4SwapRout
_checkV3PositionManagerCall(inputs, msgSender());
(success, output) = address(V3_POSITION_MANAGER).call(inputs);
} else if (command == Commands.V4_INITIALIZE_POOL) {
_checkV4InitializeCall(inputs);
(success, output) = address(V4_POSITION_MANAGER).call(inputs);
PoolKey calldata poolKey;
uint160 sqrtPriceX96;
assembly {
poolKey := inputs.offset
sqrtPriceX96 := calldataload(add(inputs.offset, 0xa0))
}
(success, output) =
address(V4_POOL_MANAGER).call(abi.encodeCall(IPoolManager.initialize, (poolKey, sqrtPriceX96)));
} else if (command == Commands.V4_POSITION_CALL) {
// should only call modifyLiquidities() to mint
_checkV4PositionManagerCall(inputs);
8 changes: 6 additions & 2 deletions contracts/modules/MigratorImmutables.sol
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ pragma solidity ^0.8.24;

import {INonfungiblePositionManager} from '@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol';
import {IPositionManager} from '@uniswap/v4-periphery/src/interfaces/IPositionManager.sol';
import {IPoolManager} from '@uniswap/v4-core/src/interfaces/IPoolManager.sol';

struct MigratorParameters {
address v3PositionManager;
@@ -12,13 +13,16 @@ struct MigratorParameters {
/// @title Migrator Immutables
/// @notice Immutable state for liquidity-migration contracts
contract MigratorImmutables {
/// @notice v3PositionManager address
/// @notice v3 PositionManager address
INonfungiblePositionManager public immutable V3_POSITION_MANAGER;
/// @notice v4PositionManager address
/// @notice v4 PositionManager address
IPositionManager public immutable V4_POSITION_MANAGER;
/// @notice v4 PoolManager address
IPoolManager public immutable V4_POOL_MANAGER;

constructor(MigratorParameters memory params) {
V3_POSITION_MANAGER = INonfungiblePositionManager(params.v3PositionManager);
V4_POSITION_MANAGER = IPositionManager(params.v4PositionManager);
V4_POOL_MANAGER = V4_POSITION_MANAGER.poolManager();
}
}
10 changes: 0 additions & 10 deletions contracts/modules/V3ToV4Migrator.sol
Original file line number Diff line number Diff line change
@@ -68,16 +68,6 @@ abstract contract V3ToV4Migrator is MigratorImmutables {
}
}

function _checkV4InitializeCall(bytes calldata inputs) internal pure {
bytes4 selector;
assembly {
selector := calldataload(inputs.offset)
}
if (selector != PoolInitializer.initializePool.selector) {
revert InvalidAction(selector);
}
}

/// @dev check that the v4 position manager call is a safe call
function _checkV4PositionManagerCall(bytes calldata inputs) internal view {
bytes4 selector;
29 changes: 8 additions & 21 deletions test/integration-tests/V3ToV4Migration.test.ts
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ import {
encodeBurn,
encodeModifyLiquidities,
encodeERC721PermitV4,
encodeInitializePool,
} from './shared/encodeCall'
import { executeRouter } from './shared/executeRouter'
import { USDC_WETH, ETH_USDC } from './shared/v4Helpers'
@@ -974,33 +973,21 @@ describe('V3 to V4 Migration Tests:', () => {
describe('V4 Commands', () => {
beforeEach(async () => {
// initialize new pool on v4
const initializePoolParams = {
key: USDC_WETH.poolKey,
sqrtPriceX96: USDC_WETH.price,
}

const initializePoolCall = encodeInitializePool(initializePoolParams)

planner.addCommand(CommandType.V4_INITIALIZE_POOL, [initializePoolCall])
planner.addCommand(CommandType.V4_INITIALIZE_POOL, [USDC_WETH.poolKey, USDC_WETH.price])
await executeRouter(planner, bob, router, wethContract, daiContract, usdcContract)
planner = new RoutePlanner()
})

it('initializes a pool', async () => {
const initializePoolParams = {
key: {
currency0: USDC.address,
currency1: WETH.address,
fee: FeeAmount.HIGH, // to make it different to USDC_WETH.poolKey
tickSpacing: 10,
hooks: '0x0000000000000000000000000000000000000000',
},
sqrtPriceX96: USDC_WETH.price,
const poolKey = {
currency0: USDC.address,
currency1: WETH.address,
fee: FeeAmount.HIGH, // to make it different to USDC_WETH.poolKey
tickSpacing: 10,
hooks: '0x0000000000000000000000000000000000000000',
}

const initializePoolCall = encodeInitializePool(initializePoolParams)

planner.addCommand(CommandType.V4_INITIALIZE_POOL, [initializePoolCall])
planner.addCommand(CommandType.V4_INITIALIZE_POOL, [poolKey, USDC_WETH.price])
let tx = await executeRouter(planner, bob, router, wethContract, daiContract, usdcContract)

// check that an initialize event was emitted on the pool manager
19 changes: 7 additions & 12 deletions test/integration-tests/gas-tests/V3ToV4Migration.gas.test.ts
Original file line number Diff line number Diff line change
@@ -264,20 +264,15 @@ describe('V3 to V4 Migration Gas Tests', () => {

describe('initialize pool', () => {
it('gas: initialize a pool', async () => {
const initializePoolParams = {
key: {
currency0: USDC.address,
currency1: WETH.address,
fee: FeeAmount.HIGH, // to make it different to USDC_WETH.poolKey
tickSpacing: 10,
hooks: '0x0000000000000000000000000000000000000000',
},
sqrtPriceX96: USDC_WETH.price,
const poolKey = {
currency0: USDC.address,
currency1: WETH.address,
fee: FeeAmount.HIGH, // to make it different to USDC_WETH.poolKey
tickSpacing: 10,
hooks: '0x0000000000000000000000000000000000000000',
}

const initializePoolCall = encodeInitializePool(initializePoolParams)

planner.addCommand(CommandType.V4_INITIALIZE_POOL, [initializePoolCall])
planner.addCommand(CommandType.V4_INITIALIZE_POOL, [poolKey, USDC_WETH.price])

const { commands, inputs } = planner
await snapshotGasCost(router['execute(bytes,bytes[],uint256)'](commands, inputs, DEADLINE))
Original file line number Diff line number Diff line change
@@ -3,42 +3,42 @@
exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Batch reverts gas: 2 sub-plans, both fail but the transaction succeeds 1`] = `
Object {
"calldataByteLength": 1764,
"gasUsed": 270178,
"gasUsed": 270222,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Batch reverts gas: 2 sub-plans, neither fails 1`] = `
Object {
"calldataByteLength": 1764,
"gasUsed": 245901,
"gasUsed": 245945,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Batch reverts gas: 2 sub-plans, second sub plan fails 1`] = `
Object {
"calldataByteLength": 1764,
"gasUsed": 245901,
"gasUsed": 245945,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Batch reverts gas: 2 sub-plans, the first fails 1`] = `
Object {
"calldataByteLength": 1764,
"gasUsed": 270178,
"gasUsed": 270222,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Interleaving routes gas: V2, then V3 1`] = `
Object {
"calldataByteLength": 836,
"gasUsed": 189541,
"gasUsed": 189563,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Interleaving routes gas: V3, then V2 1`] = `
Object {
"calldataByteLength": 836,
"gasUsed": 177124,
"gasUsed": 177146,
}
`;

@@ -73,35 +73,35 @@ Object {
exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Split routes gas: ERC20 --> ERC20 split V2 and V3, one hop 1`] = `
Object {
"calldataByteLength": 996,
"gasUsed": 176968,
"gasUsed": 176990,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Split routes gas: ERC20 --> ERC20 split V2 and V3, one hop, ADDRESS_THIS flag 1`] = `
Object {
"calldataByteLength": 996,
"gasUsed": 176743,
"gasUsed": 176765,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Split routes gas: ERC20 --> ETH split V2 and V3, exactOut, one hop 1`] = `
Object {
"calldataByteLength": 964,
"gasUsed": 192178,
"gasUsed": 192200,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Split routes gas: ERC20 --> ETH split V2 and V3, one hop 1`] = `
Object {
"calldataByteLength": 964,
"gasUsed": 184842,
"gasUsed": 184864,
}
`;

exports[`Uniswap Gas Tests Mixing V2 and V3 with Universal Router. Split routes gas: ETH --> ERC20 split V2 and V3, one hop 1`] = `
Object {
"calldataByteLength": 1124,
"gasUsed": 191884,
"gasUsed": 191906,
}
`;

@@ -283,69 +283,69 @@ Object {
exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactIn, one trade, one hop 1`] = `
Object {
"calldataByteLength": 516,
"gasUsed": 105507,
"gasUsed": 105529,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactIn, one trade, three hops 1`] = `
Object {
"calldataByteLength": 548,
"gasUsed": 253904,
"gasUsed": 253970,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactIn, one trade, two hops 1`] = `
Object {
"calldataByteLength": 548,
"gasUsed": 177091,
"gasUsed": 177135,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactOut, one trade, one hop 1`] = `
Object {
"calldataByteLength": 516,
"gasUsed": 112942,
"gasUsed": 112964,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactOut, one trade, three hops 1`] = `
Object {
"calldataByteLength": 548,
"gasUsed": 248950,
"gasUsed": 249016,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ERC20 gas: exactOut, one trade, two hops 1`] = `
Object {
"calldataByteLength": 548,
"gasUsed": 172650,
"gasUsed": 172694,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ETH gas: exactIn swap 1`] = `
Object {
"calldataByteLength": 644,
"gasUsed": 121837,
"gasUsed": 121859,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ERC20 --> ETH gas: exactOut swap 1`] = `
Object {
"calldataByteLength": 644,
"gasUsed": 129344,
"gasUsed": 129366,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ETH --> ERC20 gas: exactIn swap 1`] = `
Object {
"calldataByteLength": 644,
"gasUsed": 215389,
"gasUsed": 215411,
}
`;

exports[`Uniswap Gas Tests Trade on UniswapV3 with Universal Router. ETH --> ERC20 gas: exactOut swap 1`] = `
Object {
"calldataByteLength": 772,
"gasUsed": 124525,
"gasUsed": 124547,
}
`;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`UniversalRouter Gas Tests gas: bytecode size 1`] = `19615`;
exports[`UniversalRouter Gas Tests gas: bytecode size 1`] = `19826`;
Original file line number Diff line number Diff line change
@@ -7,32 +7,32 @@ Object {
}
`;

exports[`Uniswap UX Tests gas: Comparisons Casual Swapper - 3 swaps Permit2 Max Approval Swap 1`] = `1104436`;
exports[`Uniswap UX Tests gas: Comparisons Casual Swapper - 3 swaps Permit2 Max Approval Swap 1`] = `1104656`;

exports[`Uniswap UX Tests gas: Comparisons Casual Swapper - 3 swaps Permit2 Sign Per Swap 1`] = `1138798`;
exports[`Uniswap UX Tests gas: Comparisons Casual Swapper - 3 swaps Permit2 Sign Per Swap 1`] = `1139018`;

exports[`Uniswap UX Tests gas: Comparisons Casual Swapper - 3 swaps SwapRouter02 1`] = `1124979`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper - 10 swaps Permit2 Max Approval Swap 1`] = `3081919`;
exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper - 10 swaps Permit2 Max Approval Swap 1`] = `3082579`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper - 10 swaps Permit2 Sign Per Swap 1`] = `3235244`;
exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper - 10 swaps Permit2 Sign Per Swap 1`] = `3235904`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper - 10 swaps SwapRouter02 1`] = `3195011`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper across 3 swap router versions - 15 swaps across 3 versions Permit2 Max Approval Swap 1`] = `4103761`;
exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper across 3 swap router versions - 15 swaps across 3 versions Permit2 Max Approval Swap 1`] = `4104641`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper across 3 swap router versions - 15 swaps across 3 versions Permit2 Sign Per Swap 1`] = `4307487`;
exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper across 3 swap router versions - 15 swaps across 3 versions Permit2 Sign Per Swap 1`] = `4308367`;

exports[`Uniswap UX Tests gas: Comparisons Frequent Swapper across 3 swap router versions - 15 swaps across 3 versions SwapRouter02 1`] = `4282374`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Complex Swap Permit2 Max Approval Swap 1`] = `508868`;
exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Complex Swap Permit2 Max Approval Swap 1`] = `508956`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Complex Swap Permit2 Sign Per Swap 1`] = `509186`;
exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Complex Swap Permit2 Sign Per Swap 1`] = `509274`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Complex Swap SwapRouter02 1`] = `500008`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Simple Swap Permit2 Max Approval Swap 1`] = `299628`;
exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Simple Swap Permit2 Max Approval Swap 1`] = `299672`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Simple Swap Permit2 Sign Per Swap 1`] = `299564`;
exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Simple Swap Permit2 Sign Per Swap 1`] = `299608`;

exports[`Uniswap UX Tests gas: Comparisons One Time Swapper - Simple Swap SwapRouter02 1`] = `270033`;
Original file line number Diff line number Diff line change
@@ -30,8 +30,8 @@ Object {

exports[`V3 to V4 Migration Gas Tests V4 Commands initialize pool gas: initialize a pool 1`] = `
Object {
"calldataByteLength": 484,
"gasUsed": 62478,
"calldataByteLength": 452,
"gasUsed": 58324,
}
`;

Loading

0 comments on commit ef8bb2f

Please sign in to comment.