2

Overview

I am trying to provide single sided range liquidity on the USDC/WETH pool.

I find myself having to lower the tick range in order to mint. As I understand per the docs that the higher priced token is only available to be added above the current rate. So if I wanted to provide liquidity for WETH at 1600 and current price is 1500 I would assume that I would need to raise the desired tick range to that 1600 level, but I find the opposite to be the case in my unit tests. Below is a snippet from the docs.

As the above examples show, in Uniswap V3, the two paired assets in a given pool are separated above and below the spot price, with the higher price asset available above the spot price and the lower-priced asset below.

https://docs.uniswap.org/concepts/protocol/range-orders

Calculating higher / lower tick spacing:

  const tickSpacing = await params.usdcWethPoolContract.tickSpacing();
  let tick = (await params.usdcWethPoolContract.slot0()).tick;
  let tickLower = tick - (tick % tickSpacing) + tickSpacing;
  let tickUpper = tickLower + tickSpacing;
  // raise tick 60 (30 bips spacing) * 10
  if (options.higherTick) {
    tickLower += tickSpacing * 10;
    tickUpper += tickSpacing * 10;
  }
  // lower tick 60 (30 bips spacing) * 10
  if (options.lowerTick) {
    tickLower -= tickSpacing * 10;
    tickUpper -= tickSpacing * 10;
  }

Question

With that, why must I lower the tick range in order to provide single sided WETH if WETH is the higher priced token?

Further, why am I able to add only USDC at the current tick range as well as at a higher tick range and am unable to add only WETH at the current range?

When I try adding WETH at the current range or at a higher range I get a revert with no error emitted.

This was also helpful in understanding ticks and tick spacing: https://blog.uniswap.org/uniswap-v3-math-primer#ticks-vs-tickspacing


Potential Answer

Is this perhaps because token0/1 is USDC/WETH and that an increase in a tick priced token1 / token0 would have an inverse correlation to the expected price?

So say the current ratio is 10 WETH - 1 USDC, an increase range would mean 20-1 and a decrease 5-1 let's say. So really lowering the tick range is expecting a stronger WETH price.

1 Answer 1

0

Summary

If providing liquidity in token 0, tickLower/tickUpper must be above current tick range.

If providing in token 1, tickLower/tickUpper must be below the current tick range.


What are ticks

Ticks are a less precise form of sqrtPriceX96, thus they are also token1/token0.

It's about the price that provides the better execution for the asset.


Arbitrum Example

For example on arbitrum you have USDC/WETH. Price is say $1850 (token1/token0), or price in token1 for 1 token 0.

The better price of this pool for USDC is 1800 because you provide less USDC for 1 WETH. 1800 is a lower tick range, a lower price.

Conversely if you sell 1 WETH for 1900 (high tick range) you're getting a better price than a lower tick range.


Ethereum example

On Ethereum the pool is WETH/USDC, price is:

>>> sqrtPriceX96 = 1860250743572950558737581220524281
>>> decimal_token1 = 18
>>> decimal_token0 = 6
>>> round(sqrtPriceX96 * sqrtPriceX96 * ((10**decimal_token0) / (10**decimal_token1)) / (2 ** 192), decimal_token1)
0.00055129468580304 # price
0.00055129468580304` = 1 USDC.
>>> 0.00055129468580304 * 1814
1.0000485600467146

If providing liquidity in WETH (token1) you'll want a better price which is less WETH per USDC.

Conversely you want a higher price when providing liquidity in USDC. Said differently more WETH per USDC.


This helped a lot https://blog.uniswap.org/uniswap-v3-math-primer


Tick from sqrtPriceX96

let tick = Math.floor(Math.log((sqrtPriceX96 / Q96) ** 2) / Math.log(1.0001));
let tickLower = tick - (tick % tickSpacing);
let tickUpper = tickLower + tickSpacing;

Current tick range:

const tickSpacing = await usdcWethPoolContract.tickSpacing();
let tick = (await usdcWethPoolContract.slot0()).tick;
let tickLower = tick - (tick % tickSpacing);
let tickUpper = tickLower + tickSpacing;

Your Answer

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

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