uniswap – How to Get Ticks Ranged Within +- of a Trade in Uniswap V3

nodejstypescriptuniswapuniswapv3

I'm trying to grab all relavent ticks to a trade using uniswap. I have a function to retreive the ticks.

const tradeAmount = CurrencyAmount(WETH_TOKEN, 1000 * 10 ** 18)

const poolStateContract = getPoolStateContract('0x45dda9cb7c25131df268515131f647d726f50608');

const slot0 = poolStateContract.slot0();

//returns 10
const tickSpacing = poolStateContract.tickSpacing()

//returns 206044
slot0.tick

//returns no useful information since I'm not at the start of the tick e.g (206040)
getTickRange(tradeAmount , slot0.tick, ''0x45dda9cb7c25131df268515131f647d726f50608')

export function getTickRange(tradeAmount: CurrencyAmount<Token>, tick:Number, poolAddress: string) {
    const tickRange = getTickRange(tradeAmount, tick, poolAddress);
    const ticks = getTicksViaMulticall(tickRange, poolAddress);
}

I 2 have questions

  1. Since the how do I calculate the initial tick from the given tick e.g for this example it's easy since the tick spacing is 10, however if the tick spacing was something harder like 12, how do I find the closest tick? Does tick counting start from TickMath.Min or does it start from 0?

  2. Given the trade amount in this case 1000 eth, I would like to calculate the tick that swapping this trade would end on, e.g if the current tick is 206044, what would the current tick be after swapping 1000 eth?

EDIT for clarification I'm oversimplifying the problem, in reality im using a multicall to get all the data, and I would not want to enumerate my calls to tick, Preferably I'd like to figure out a way to calculate the end tick, so I can grab all the ticks in a single shot.

Best Answer

To start here is the math for tick spacing, this will give a single active tick range

web3 style

const V3poolC = new web3.eth.Contract(V3poolabi, V3pool);
var S0 = await V3poolC.methods.slot0().call().catch(function (err){log(err)});
var CT = parseInt(S0.tick);
var Tsp = parseInt(V3poolC.methods.tickSpacing().call().catch(function (err){log(err)}));
var NLT = (math.floor(CT/Tsp))*Tsp;
var NHT = ((math.floor(CT/Tsp))*Tsp)+Tsp;
var TickL = NLT.toString();  //Nearest usable lower tick This would have the current tick range Liquidity
var TickU = NHT.toString();  //Nearest usable upper tick   

So to calculate the swap you would really need to do all the liquidity math, get the token amounts in an active tick range. Then you would need to calculate the swap with those, if not enough lq in that range then you would have to include the next tick. The math on this is crazy, and there is a better way via code

The Devs made a quoter for V3 which is really awesome, and will return the active / initiated ticks crossed in a swap, along with expected output, and gas estimation.

IQuoterV2 Web3 called correctly is gasless https://docs.uniswap.org/protocol/reference/periphery/interfaces/IQuoter https://docs.uniswap.org/sdk/guides/creating-a-trade#using-callstatic-to-return-a-quote 0x61fFE014bA17989E743c5F6cB21bF9697530B21e Web3

const V3quoter = new web3.eth.Contract(V3quote, contractUNI);
let encoded = {'tokenIn':TokenIn address,'tokenOut':TokenOut address,'fee':Fee.toString(),'amountIn':AmountIn.toString(),'sqrtPriceLimitX96':'0'};
let myQuote = await V3quoter.methods.quoteExactInputSingle(encoded).call();

etherjs

var results = await IQuoterV2.Contract.callStatic.quoteExactInputSingle(encoded)

return will look like

Result {
  '0': '236927878461501597',
  '1': '2226553910065733853767841080728134',
  '2': '0',
  '3': '83578',
  amountOut: '236927878461501597',
  sqrtPriceX96After: '2226553910065733853767841080728134',
  initializedTicksCrossed: '0',
  gasEstimate: '83578'
}
Related Topic