2

enter image description here

-> How to calculate totalValueLocked of each token in each tick of a certain pool in uniswap from subgraph api and also the TVL percentage in each tick of a pool ?

Currently, I am fetching all ticks for a certain pool and each tick's liquidityNet using this query:

var query = "{ticks(first:1000,orderBy:tickIdx,orderDirection:asc,where:{tickIdx_gt:" + lastTickIdx +",poolAddress:""+id+""}){tickIdx liquidityNet}}";

here lastTickIdx is the maximum tickIdx extracted till now.

Now , what I am trying to do is distribute the total liquidity of the pool in the ticks before the currentTick of the pool and after the current ticks of the pool, so I'm starting with pool's liquidity at the current tick then use this formula => here p0 and p1 are the price points of this tick and previous tick and d0 and d1 are the respective decimals of the two tokens.

//value of token0 locked in this tick

tvl00 = (Math.Sqrt(p0) - Math.Sqrt(p1)) * loopLiquidity * Math.Pow(10, 0 - d0);

// value of token1 locked in this tick.

tvl11 = tvl00 * (Math.Pow(1.0001, curr)) * Math.Pow(10, d0 - d1);

 lets say currentTick is 5 , then loopLiquiditys are like this:
         
        

 2  -> loopLiquidity = loopLiquidity at tick3  - LiquidityNet at tick2 
             3  -> loopLiquidity = loopLiquidity at tick4  - LiquidityNet at tick3
             4  -> loopLiquidity = loopLiquidity at tick5  - LiquidityNet at tick4
 currentTick 5  -> loopLiquidity = pools Liquidity
             6  -> loopLiquidity = loopLiquidity at tick5  + LiquidityNet at tick6 
             7  -> loopLiquidity = loopLiquidity at tick6  + LiquidityNet at tick7

     

so after doing this my values obtained for each tick are matching with the values obtained on the uniswap , liquidity graph, for ticks near the currentTick, but my total value locked for token0 and total value for token1 for whole pool comes out to be less than the TVL values otained for the pool from the subgraph, so basically calculated tvl by using my code comes out to be less than the actual tvl values of the pool.

         Here is the code that I am using to generate these values:



// currTick of pool
    double currTick = Convert.ToDouble(currTickx);
    // feeTier of pool
    double feeTier = Convert.ToDouble(feeTierx);
    //decimals of token0
    double d0 = Convert.ToDouble(d0x);
    //decimals of token1
    double d1 = Convert.ToDouble(d1x);
    //dictionary to hold tickIdx <-> liquidity net pair
    Dictionary<double, double> dict = new Dictionary<double, double>();
    foreach (var tick in extractedTicks)
    {
        dict[tick.tickIdx] = Convert.ToDouble(tick.liquidityNet);
      
    }
    //tickSpacing (gaps between two consecutive ticks)
    double tickSpacing = feeTier / 50;
    
    // previous tick of currentTick
    double upperTick = currTick - ((currTick % tickSpacing)+tickSpacing)%tickSpacing;
    
    //next tick of the currentTick
    double lowerTick = upperTick + tickSpacing;
    

    //get minTick and maxTick
    double minTick = extractedTicks[0].tickIdx;
   
    double maxTick = extractedTicks[extractedTicks.Length - 1].tickIdx;
    
    // total0 is the TVLtoken0 for the entire pool, similarly for total1 which is TVLtoken1 for entire pool
    double total0 = 0, total1 = 0;
    
    // This is the total liquidity of the given pool 
    double loopLiquidity = Convert.ToDouble(poolLiquidity);
    //go from lowerTick to maxTick  -> this should give token0 value locked
    for(double curr = lowerTick; curr <= maxTick; curr += tickSpacing)
    {
       
        if (dict.ContainsKey(curr) == true) { loopLiquidity += dict[curr]; loopLiquidity1 += dict1[curr];
            
        }
        double p0 = Math.Pow(1.0001, curr-tickSpacing);
        p0 = 1 / p0;
        double p1 = Math.Pow(1.0001, curr);
        p1 = 1 / p1;
        //value of token0 in this tick
        var tvl00 = (Math.Sqrt(p0) - Math.Sqrt(p1)) * loopLiquidity * Math.Pow(10, 0 - d0);

        // value of token1 in this tick
        var tvl11 = tvl00 * (Math.Pow(1.0001, curr)) * Math.Pow(10, d0 - d1);
       
       total0 += tvl00;
        
    }
    
    //go from upperTick to minTick  -> this will give token1 value locked
    loopLiquidity = Convert.ToDouble(poolLiquidity);
    
    dict[upperTick + tickSpacing] = 0;
    for (double curr = upperTick; curr>=minTick; curr -= tickSpacing)
    {
        
        
        double k = curr + tickSpacing;
        if (dict.ContainsKey(curr + tickSpacing) == true) { loopLiquidity -= dict[curr + tickSpacing];}
        double p0 = Math.Pow(1.0001, curr-tickSpacing);
        p0 = 1 / p0;
        double p1 = Math.Pow(1.0001, curr );
        p1 = 1 / p1;

        //total value of token 0 in this tick
        var tvl00 = (Math.Sqrt(p0) - Math.Sqrt(p1)) * loopLiquidity * Math.Pow(10, 0 - d0);
        
        //total value of token 0 in this tick
        var tvl11 = tvl00 * (Math.Pow(1.0001, curr)) * Math.Pow(10, d0 - d1);

        total1 += tvl11;
        
    }
    // here totalValuelocked0 and totalValuelocked1 are the pool's actual tvl values obtained by the 
    //subgraph directly by querying the pool 
    Console.WriteLine("token0 from lower half => " + total0 + "  " + totalValuelocked0);
    Console.WriteLine("token1 from upper half => " + total1 + "  " + totalValuelocked1);
    [This is what I'm trying to calculate,in the hover box value locked in this tick is mentioned , I want to calculate that for each tick][1]
    
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
  • Subgraph's value is not necessarily the ground truth. There are know issues with the TVL shown in the subgraph that may not be fully fixed. https://github.com/Uniswap/v3-subgraph/issues/49 – kfx Jun 25 '22 at 19:09

0 Answers0