UniswapV3 Pricing – Fixing Incorrect Pricing Calculated Using sqrtPriceX96

nodejsuniswapv3

I'm calculating a UniswapV3 pool's token0 price in Node.js. Using UniswapV3 SDK gives correct result, but manual calculation isn't.

From the docs

sqrtPriceX96 = sqrt(price) * 2 ** 96
# divide both sides by 2 ** 96
sqrtPriceX96 / (2 ** 96) = sqrt(price)
# square both sides
(sqrtPriceX96 / (2 ** 96)) ** 2 = price
# expand the squared fraction
(sqrtPriceX96 ** 2) / ((2 ** 96) ** 2)  = price
# multiply the exponents in the denominator to get the final expression
sqrtRatioX96 ** 2 / 2 ** 192 = price

Now let's take pool WMATIC-USDC on Polygon, querying slot0 returns

  sqrtPriceX96                uint160 :  76424446980909989196624
  tick                        int24   :  -277045
  observationIndex            uint16  :  4
  observationCardinality      uint16  :  64
  observationCardinalityNext  uint16  :  64
  feeProtocol                 uint8   :  0
  unlocked                    bool    :  true

Let's assign this value into the formula above –

token0Price = 76140828840970807549375^2 / 2^192 = 0.000000000000924

Which is wrong, it should be 0.9102578244 (calculated by UniswapV3 SDK).

Any idea what's wrong there?

Best Answer

It seems to be a floating point issue, formula works if the value is converted using its token's number of decimals, in this case WMATIC has 18 decimals and USDC has 6 -

76140828840970807549375^2 / 2^192 * 10^18 / 10^6

= 76140828840970807549375^2 / 2^192 * 10^12

= 0.924
Related Topic