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?