繁体   English   中英

UniswapV3 position 铸币算法无法根据我传入的参数获得正确的矿池地址

[英]UniswapV3 position minting algorithm can't get correct pool address based on params I've passed in

Uniswap V3 PoolAddress.computeAddress计算的地址与我从UniswapV3poolFactory.getPool获得的地址不同。 在我的代码中没关系,我可以从这个映射中获取池地址,但是 uniswap 合约使用PoolAddress库来获取池地址。

When I try to mint new position using mint function from NonfungiblePositionManager.sol this function calls addLiquidity from LiquidityManagement.sol and this function has call to the PoolAddress.sol library method computeAddress . 它在那里抛出,因为在计算pool地址之后它尝试从pool调用方法,但它不能导致地址错误。

我尝试更改传递给mint function 的令牌的顺序,但顺序是正确的,我还使用安全帽本地链记录了与 uniswap 合约中的池地址计算相关的所有数据,它是与我用于getPool映射的那个相同。 在我看来,唯一仍然会导致错误计算的是PoolAddress库中的POOL_INIT_CODE_HASH常量,但我没有改变它。 我将在文本下方发布所有提到的方法以及指向 uniswap 存储库的链接。 我用于所有 unsiwap 合约的编译器版本是0.7.6 如果有人知道如何解决这个问题,请告诉我。

v3-核心

v3-外围

NonfungiblePositionManager.sol

流动性管理.sol

池地址.sol

NonfungiblePositionManager.sol

function mint(MintParams calldata params)
    external
    payable
    override
    checkDeadline(params.deadline)
    returns (
      uint256 tokenId,
      uint128 liquidity,
      uint256 amount0,
      uint256 amount1
    )
  {
    IUniswapV3Pool pool;
    

// it throws
---> (liquidity, amount0, amount1, pool) = addLiquidity(
      AddLiquidityParams({
        token0: params.token0,
        token1: params.token1,
        fee: params.fee,
        recipient: address(this),
        tickLower: params.tickLower,
        tickUpper: params.tickUpper,
        amount0Desired: params.amount0Desired,
        amount1Desired: params.amount1Desired,
        amount0Min: params.amount0Min,
        amount1Min: params.amount1Min
      })
    );
    

    _mint(params.recipient, (tokenId = _nextId++));

    bytes32 positionKey = PositionKey.compute(address(this), params.tickLower, params.tickUpper);
    (, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, , ) = pool.positions(positionKey);
    
    // idempotent set
    uint80 poolId = cachePoolKey(
      address(pool),
      PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee})
    );
    
    _positions[tokenId] = Position({
      nonce: 0,
      operator: address(0),
      poolId: poolId,
      tickLower: params.tickLower,
      tickUpper: params.tickUpper,
      liquidity: liquidity,
      feeGrowthInside0LastX128: feeGrowthInside0LastX128,
      feeGrowthInside1LastX128: feeGrowthInside1LastX128,
      tokensOwed0: 0,
      tokensOwed1: 0
    });
    
    emit IncreaseLiquidity(tokenId, liquidity, amount0, amount1);
  }
LiquidityManagement.sol

function addLiquidity(AddLiquidityParams memory params)
    internal
    returns (
      uint128 liquidity,
      uint256 amount0,
      uint256 amount1,
      IUniswapV3Pool pool
    )
  {
    PoolAddress.PoolKey memory poolKey = PoolAddress.PoolKey({
      token0: params.token0,
      token1: params.token1,
      fee: params.fee
    });
    

    // here is the computation of pool address
---> pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));

    // all subsequent operations fails 

    // compute the liquidity amount
    {
      (uint160 sqrtPriceX96, , , , , , ) = pool.slot0();
      console.log("liquidity 4");
      uint160 sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(params.tickLower);
      console.log("liquidity 5");
      uint160 sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(params.tickUpper);
      console.log("liquidity 6");

      liquidity = LiquidityAmounts.getLiquidityForAmounts(
        sqrtPriceX96,
        sqrtRatioAX96,
        sqrtRatioBX96,
        params.amount0Desired,
        params.amount1Desired
      );
      console.log("liquidity 7");
    }

    (amount0, amount1) = pool.mint(
      params.recipient,
      params.tickLower,
      params.tickUpper,
      liquidity,
      abi.encode(MintCallbackData({poolKey: poolKey, payer: msg.sender}))
    );
    

    require(amount0 >= params.amount0Min && amount1 >= params.amount1Min, "Price slippage check");
  }
PoolAddress.sol

  bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM