1

i am using this code to create and initialize a pool and mint a new position on it.

// 1 ETH (y) = 2000 USDC (x)
pool = IUniswapV3Pool(factory.createPool(address(weth), address(usdc), 500));
pool.initialize(1771595571142957166518320255467520); // current tick : 200311

// mint a new position
INonfungiblePositionManager.MintParams memory params = 
            INonfungiblePositionManager.MintParams(
                address(usdc),
                address(weth),
                500,
                200310,
                200320,
                2000 * 10 ** 6, // Desired amount of token0
                1 * 10 ** 18, // Desired amount of token1
                1900 * 10 ** 6, // Minimum amount of token1
                0.1 * 10 ** 18, // Minimum amount of token0
                recepient,
                block.timestamp + 33600 // Deadline 1 hour from now
            );

in the above code i have initialized a pool between usdc and weth for 500 bip fee (remember usdc has 6 decimals and weth has 18) i then initialize with a sqrtpricex96 that is based upon the price exchange 1 eth = 2000 usdc.

when i use this code to calculate price from sqrtpricex96 i get the correct price

def sqrtp_to_price(p):
  return (p/q96) ** 2

p = sqrtp_to_price(1771595571142957166518320255467520)
q = p * 1e6/1e18
print(q) // 0.0005

when minting a new position, i pass exactly that amount the 2000 usdc which gets used up fully but only o.1 of my 1 weth get used up, why? Is thehre a way to calculate the amounts that are going to get used up before hand as to avoid trial and error in slippage tolerance.

1 Answer 1

4

Uniswap V3 positions consist of ticks with equal amount of liquidity in each tick. So if the current tick is 200312 and your are placing position between 200310 and 200320, the position will end up having roughly 80% of one token and 20% of the other token. NFT manager will try to maximize amounts of tokens getting in, but it's normal to have one of the two tokens left over.

To calculate how many tokens a position would take you could use something like this:

(uint256 amt0, uint256 amt1) = _amountsForLiquidity(
    sqrtRatioX96, // take it from slot0
    tickLow, // 200310
    tickHigh, // 200320
    10**18 // just some number here
);

// after you get amt0 and amt1 you could see the proportions between 
// these two tokens in a position with 10**18 liquidity that could 
// theoretically go in. Use this proportion to calculate real amounts 
// based on the funds you have at hand. 

function _amountsForLiquidity(
    uint160 sqrtRatioX96,
    int24 tickLower,
    int24 tickUpper,
    uint128 liquidity
) internal pure returns (uint256 amount0, uint256 amount1) {
    // LiquidityAmounts is a lib from Uniswap V3 periphery
    (amount0, amount1) = LiquidityAmounts.getAmountsForLiquidity(
        sqrtRatioX96,
        TickMath.getSqrtRatioAtTick(tickLower),
        TickMath.getSqrtRatioAtTick(tickUpper),
        liquidity
    );
}
8
  • why did you pass 10 ** 18 in place for liquidity? in case of usdc/weth pool should i pass 10 ** 12? also how did you estimate on the basis of my ticks that the ration will be 80/20?
    – Ren
    Commented Aug 23, 2023 at 7:44
  • 10**18 is just a hypothetical number - doesn't matter what liquidity amount you use there. The goal is not to get real amounts, but to find in what proportion tokens will go into the position with boundaries set to 200310 and 200320. After you get amt0 and amt1, you can apply this knowledge to real amounts you want to put in (in your example 2000 * 10 ** 6 and 1 * 10 ** 18)
    – Vas Treck
    Commented Aug 23, 2023 at 13:08
  • Let's call them t0 and t1. if amt0/t0 > amt1/t1, then 100% of token0 will go in and (t0/amt0)*amt1 of token1 will go in as well. And visa versa if amt0/t0 < amt1/t1
    – Vas Treck
    Commented Aug 23, 2023 at 13:15
  • as far as 80/20, it's just a rough approximation for the example where current tick is 200312 and position spans 10 ticks (200310-200320). It would indicate that 2 ticks will be filled with one token and 8 ticks with the other. It's not precise at all because amounts of tokens in ticks further away from price are smaller and also composition inside the price tick itself could be different at any time. But it's an OK way to produce rough estimate just by looking at ticks
    – Vas Treck
    Commented Aug 23, 2023 at 13:23
  • but thats the point, why aren't both token's being consumed? beacause the the ratio is set 1:1 i.e i usdc = 0.0005 eth and since their is noothe txn the ratio isn't disturbed and both of my tokens should be consumed fully
    – Ren
    Commented Aug 23, 2023 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.