UniswapV3 – Resolving Differences Between Pool Deployer and PoolAddress.computeAddress() in Uniswap V3

uniswapv3

I have deployed all UniswapV3 contracts locally in a Foundry test, then tried to mint a new position following https://docs.uniswap.org/contracts/v3/guides/providing-liquidity/mint-a-position

I realized when I made a new pool by calling:
nonFungiblePositionManager.createAndInitializePoolIfNecessary(...) , which calls

PoolInitializer.createAndInitializePoolIfNecessary(...), which calls

pool = IUniswapV3Factory(factory).createPool(token0, token1, fee);, which calls

pool = deploy(address(this), token0, token1, fee, tickSpacing);, which calls

UniswapV3PoolDeployer.deploy(...){
        parameters = Parameters({factory: factory, token0: token0, token1: token1, fee: fee, tickSpacing: tickSpacing});
        pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());
//pool address1
        delete parameters;
    }

Then I got a new pool address.
But when I tried to mint a new position by adding liquidity to that pool:
NonFungiblePositionManager.mint(), which calls

LiquidityManagement.addLiquidity(){
    PoolAddress.PoolKey memory poolKey =
    PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee});
    pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));
//pool address2
    { (uint160 sqrtPriceX96,,,,,,) = pool.slot0();//failed here
  ... }
...
}

Then it failed because this pool address2 is different from the pool address1 !!??

A closer look at the PoolAddress library:

    function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
        require(key.token0 < key.token1);
        pool = address(
            uint256(
                keccak256(
                    abi.encodePacked(
                        hex'ff',
                        factory,
                        keccak256(abi.encode(key.token0, key.token1, key.fee)),
                        POOL_INIT_CODE_HASH
                    )
                )
            )
        );
    }

Although removing POOL_INIT_CODE_HASH does not help, but why does Uniswap have this POOL_INIT_CODE_HASH?
Something is causing this address calculation not to match the address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}())

Why is that? What did I miss?

Best Answer

POOL_INIT_CODE_HASH is a hash on the UniswapV3Pool code. If you modified the pool contract's code in any way in your fork, then this hash won't match and you'll get issues like the one you described above. So either don't modify the code or calculate new hash and put it in your fork.

Related Topic