1

I'm creating a statistics app for tracking my positions on uniswap.

As you can see below I have 0.019 unclaimed ETH rewards. However, when I try to reproduce this in my statistics app, I get 0.016 unclaimed ETH rewards. When running the numbers for the USDT token it is also off by about 10USDT. I will walk you trough how I've done this:

enter image description here

I get my active positions using a graphql query from the Uniswap API, you can run the query at https://thegraph.com/explorer/subgraph/uniswap/uniswap-v3:

{
  positions(where: { owner: "0x44A2432332ca9166EC606501DA8067fC3C3c9058", liquidity_gt: 0}) {
    liquidity
    feeGrowthInside0LastX128
    feeGrowthInside1LastX128
    token0 {
      decimals
      derivedETH
    }
    token1
    {
      decimals
      derivedETH
    }
    tickUpper {
      tickIdx
      feeGrowthOutside0X128
      feeGrowthOutside1X128
    }
    tickLower {
      tickIdx
      feeGrowthOutside0X128
      feeGrowthOutside1X128
    }
    pool {
      tick
      feeGrowthGlobal0X128
      feeGrowthGlobal1X128,
      totalValueLockedUSD
    }
  }
}

Using the information I found at https://blog.uniswap.org/uniswap-v3-math-primer-2#calculating-uncollected-fees-in-a-position I created the following functions (C#) to calculate the rewards.

var value0 = CalculateReward(
    BigRational.Parse(position.Liquidity),
    BigRational.Parse(position.Pool.FeeGrowthGlobal0X128),
    BigRational.Parse(position.TickUpper.FeeGrowthOutside0X128),
    BigRational.Parse(position.TickLower.FeeGrowthOutside0X128),
    BigRational.Parse(position.FeeGrowthInside0LastX128), 
    position.TickUpper.TickIdx, 
    position.TickLower.TickIdx, 
    position.Pool.Tick);
value0 = value0 / BigRational.Pow(10, position.Token0.Decimals);

private BigRational CalculateReward(
    BigRational liquidity,
    BigRational feeGrowthGlobal,
    BigRational feeGrowthOutsideUpperTick,
    BigRational feeGrowthOutsideLowerTick,
    BigRational feeGrowthInside,
    int tickUpper,
    int tickLower,
    int tick)
{
    var feeGrowthInsideCurrent = CalculateCurrentFeeGrowthInside(
        feeGrowthGlobal,
        feeGrowthOutsideUpperTick,
        feeGrowthOutsideLowerTick,
        tickUpper,
        tickLower,
        tick);
    return liquidity * (feeGrowthInsideCurrent - feeGrowthInside) / BigRational.Pow(2, 128);
}

private BigRational CalculateCurrentFeeGrowthInside(
    BigRational feeGrowthGlobal,
    BigRational feeGrowthOutsideUpperTick,
    BigRational feeGrowthOutsideLowerTick,
    int tickUpper,
    int tickLower,
    int tick)
{
    var feesBelowLowerTick = CalculateFeesBelowLowerTick(feeGrowthGlobal, feeGrowthOutsideLowerTick, tickLower, tick);
    var feesBelowUpperTick = CalculateFeesBelowUpperTick(feeGrowthGlobal, feeGrowthOutsideUpperTick, tickUpper, tick);
    return feeGrowthGlobal - feesBelowLowerTick - feesBelowUpperTick;
}

private BigRational CalculateFeesBelowLowerTick(
    BigRational feeGrowthGlobal,
    BigRational feeGrowthOutsideLowerTick,
    int tickLower,
    int tick)
{
    if (tick >= tickLower)
    {
        return feeGrowthOutsideLowerTick;
    }
    else
    {
        return feeGrowthGlobal - feeGrowthOutsideLowerTick;
    }
}

private BigRational CalculateFeesBelowUpperTick(
    BigRational feeGrowthGlobal,
    BigRational feeGrowthOutsideUpperTick,
    int tickUpper,
    int tick)
{
    if (tick >= tickUpper)
    {
        return feeGrowthGlobal - feeGrowthOutsideUpperTick;
    }
    else
    {
        return feeGrowthOutsideUpperTick;
    }
}

For example, if I run the following numbers (which I got from running the above graphql query) through the calculations, I get 0.016 instead of 0.019. What am I doing wrong?

var value0 = CalculateReward(
    BigRational.Parse("1367429764868973"),
    BigRational.Parse("356531773596110297175139730895619992793974"),
    BigRational.Parse("0"),
    BigRational.Parse("349599952281522978521834276098134191845749"),
    BigRational.Parse("2736330194804551556695334267654167873990"), 
    -196915, 
    -199341, 
    -198304);
value0 = value0 / BigRational.Pow(10, 18);

I also tried communicating with the smart contracts directly, with the same result.

0

Your Answer

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

Browse other questions tagged or ask your own question.