# How to get the virtual and real reserves from a Uniswap V3 pair?

I need help with math of Uniswap V3 virtual and real reserves. Need to find the true reserves of a pair.

Example: let's say we have this DAI/WETH pair: `0x60594a405d53811d3BC4766596EFD80fd545A270` balance of DAI was `2591437269710515203595384` and balance of WETH was `2838497576725882781612`

As we can see here, reserve's of tokens in this pool disbalanced:

• DAI value in pool: `2,594,028.706980225` \$ (43 %)
• WETH value in pool: `3,461,888.414526421` \$ (57 %)

If I'm not mistaken, because of concentrated liquidity we have a different virtual reserve's in every "concentrated" zone. Also, those virtual reserve's should be balanced (50/50 - value) by x*y=k. Does anyone know how to find those virtual and/or real reserve's?

I've successfully calculated a price of both tokens:

``````token0Price = sqrtRatioX96 ** 2 / 2 ** 192 = 2267580935849786082246943435 **2 / 2 **192 = 5.141923300629392e+54 / 6.277101735386681e+57 = 0.0008191556417896165

token1Price =  2 ** 192 / sqrtRatioX96 ** 2 = 6.277101735386681e+57 / 2267580935849786082246943435 **2 = 6.277101735386681e+57 / 5.141923300629392e+54 = 1220.7692274636495
``````

And prices are fine.

Reserves token0:

``````x = L / sqrt(P)
x = 776218541774739337116335 / sqrt(0.0008191556417896165)
x = 776218541774739337116335 / 0.02862089519
x = 2.7120694046143822e+25
x = 27120694046143822000000000
``````

Reserves token1

``````y = L * sqrt(P)
# Suppose that sqrt(P) is sqrt(token1Price) then:
y = 776218541774739337116335 * sqrt(1220.7692274636495)
y = 776218541774739337116335 * 34.9395081171
y = 2.7120694040982028e+25
y = 27120694040982028000000000
``````

Comparing x and y:

``````x = 27120694046143822000000000
y = 27120694040982028000000000
``````

It looks like 50/50, but not by it's token reserves value. I'm not sure, that's my math is correct.

• The virtual reserves in terms of `x` and `y` are very rarely needed; liquidity is almost always what you want to calculate and use. Real reserves in a pool are complex to calculate because of the non-uniform liquidity. See my answer here stackoverflow.com/a/71815432/2435820
– kfx
Nov 22, 2022 at 11:19
• In the question, `token0Price` and `token1Price` are successfully calculated using `sqrtRatioX96 ** 2 / (2 ** 192)` and `(2 ** 192 )/ sqrtRatioX96 ** 2` respectively. But, in V3, how to get the `sqrtRatioX96`, as we're having `sqrt_price_x96` derived from `slot0` as `slot0. sqrtPriceX96`, so is there a way to calculate `sqrtRatioX96` using `sqrtPriceX96` ? Apr 13 at 10:13
• @SYEDASADKAZMI `sqrtRatioX96` and `sqrtPriceX96` are used as synonyms in the Uniswap v3 code, they're just different names for the same thing.
– kfx
Apr 13 at 10:50
• @kfx, here's my question: ethereum.stackexchange.com/questions/162525/…. Apr 13 at 11:20

Here is a mjs file I created for the token balance of a V3 position, the math should be easily extractable

``````import { JSBI } from "@uniswap/sdk";
import { ethers } from 'ethers'
import * as fs from 'fs';

// ERC20 json abi file
const ERC20 = JSON.parse(ERC20Abi);

// V3 pool abi json file
const IUniswapV3PoolABI = JSON.parse(pool);

// V3 factory abi json
const IUniswapV3FactoryABI = JSON.parse(facto);

// V3 NFT manager abi
const IUniswapV3NFTmanagerABI = JSON.parse(NFT);

const provider = new ethers.providers.JsonRpcProvider("https://eth-mainnet.alchemyapi.io/v2/<API_Key>")

// V3 standard addresses (different for celo)
const NFTmanager = "0xC36442b4a4522E871399CD717aBDD847Ab11FE88";

async function getData(tokenID){
let FactoryContract = new ethers.Contract(factory, IUniswapV3FactoryABI, provider);

let NFTContract =  new ethers.Contract(NFTmanager, IUniswapV3NFTmanagerABI, provider);
let position = await NFTContract.positions(tokenID);

let token0contract =  new ethers.Contract(position.token0, ERC20, provider);
let token1contract =  new ethers.Contract(position.token1, ERC20, provider);
let token0Decimal = await token0contract.decimals();
let token1Decimal = await token1contract.decimals();

let token0sym = await token0contract.symbol();
let token1sym = await token1contract.symbol();

let V3pool = await FactoryContract.getPool(position.token0, position.token1, position.fee);
let poolContract = new ethers.Contract(V3pool, IUniswapV3PoolABI, provider);

let slot0 = await poolContract.slot0();

let pairName = token0sym +"/"+ token1sym;

let dict = {"SqrtX96" : slot0.sqrtPriceX96.toString(), "Pair": pairName, "T0d": token0Decimal, "T1d": token1Decimal, "tickLow": position.tickLower, "tickHigh": position.tickUpper, "liquidity": position.liquidity.toString()}

return dict
}

const Q96 = JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(96));
const MIN_TICK = -887272;
const MAX_TICK = 887272;

function getTickAtSqrtRatio(sqrtPriceX96){
let tick = Math.floor(Math.log((sqrtPriceX96/Q96)**2)/Math.log(1.0001));
return tick;
}

async function getTokenAmounts(liquidity,sqrtPriceX96,tickLow,tickHigh,token0Decimal,token1Decimal){
let sqrtRatioA = Math.sqrt(1.0001**tickLow);
let sqrtRatioB = Math.sqrt(1.0001**tickHigh);

let currentTick = getTickAtSqrtRatio(sqrtPriceX96);
let sqrtPrice = sqrtPriceX96 / Q96;

let amount0wei = 0;
let amount1wei = 0;
if(currentTick <= tickLow){
amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtRatioA)/(sqrtRatioA*sqrtRatioB)));
}
else if(currentTick > tickHigh){
amount1wei = Math.floor(liquidity*(sqrtRatioB-sqrtRatioA));
}
else if(currentTick >= tickLow && currentTick < tickHigh){
amount0wei = Math.floor(liquidity*((sqrtRatioB-sqrtPrice)/(sqrtPrice*sqrtRatioB)));
amount1wei = Math.floor(liquidity*(sqrtPrice-sqrtRatioA));
}

let amount0Human = (amount0wei/(10**token0Decimal)).toFixed(token0Decimal);
let amount1Human = (amount1wei/(10**token1Decimal)).toFixed(token1Decimal);

console.log("Amount Token0 wei: "+amount0wei);
console.log("Amount Token1 wei: "+amount1wei);
console.log("Amount Token0 : "+amount0Human);
console.log("Amount Token1 : "+amount1Human);
return [amount0wei, amount1wei]
}

async function start(positionID){
let data = await getData(positionID);
let tokens = await getTokenAmounts(data.liquidity, data.SqrtX96, data.tickLow, data.tickHigh, data.T0d, data.T1d);
}

start(5)
``````
• Thank's al lot!) Will test! Dec 12, 2022 at 12:52
• yeah, no problem. feel free to ask questions, and I'm a uniswap friend in the uniswap discord Dec 15, 2022 at 4:09

To get the real reserves you can use the pool's `balance0` and `balance1` functions or the pool tokens' `balanceOf` function. Mind that these will also include unclaimed fees and removed liquidity that does not participate in market making. For more detailed answer, see here.

To get the virtual reserves, you can use the Uniswap v2 math formulas on the liquidity and price returned by the v3 pool's on-chain functions:

Python code (Web3.py) for this:

``````# get the liquidity and sqrt of price