0

I need help with math of UniSwap V3 virtual and real reserves. Need to find the true reserves of a pair (value of token0 = value of token1). Example:

Let's say we have this DAI/WETH pair: 0x60594a405d53811d3BC4766596EFD80fd545A270 balance of DAI was - 2591437269710515203595384 & 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'am 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 succesfully calculated a price of both token's: 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 price's are fine.

Also, I've got: 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

x = 27120694046143822000000000 y = 27120694040982028000000000

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

Thank you!

1
  • 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

1 Answer 1

0

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
let ERC20Abi = fs.readFileSync('<path>/ERC20.json');
const ERC20 = JSON.parse(ERC20Abi);

    // V3 pool abi json file
let pool = fs.readFileSync('<path>/V3PairAbi.json');
const IUniswapV3PoolABI = JSON.parse(pool);

    // V3 factory abi json
let facto = fs.readFileSync('<path>/V3factory.json');
const IUniswapV3FactoryABI = JSON.parse(facto);

    // V3 NFT manager abi
let NFT = fs.readFileSync('<path>/UniV3NFT.json');
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 factory = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
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)
2
  • Thank's al lot!) Will test!
    – Chenky
    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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.