0

I have the following functions based on the Uniswap library, but the result of the amounts I get for the two tokens in the pool are different from those shown by Dexscreener. How can I fix this?

const FixedPoint96 = {
  Q96: Big(2).pow(96)
};

function mulDiv(a, b, denominator) {
  return a.mul(b).div(denominator);
}

function getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
  if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
    [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
  }
  const numerator = liquidity.mul(FixedPoint96.Q96).mul(sqrtRatioBX96.sub(sqrtRatioAX96));
  return numerator.div(sqrtRatioBX96).div(sqrtRatioAX96);
}

function getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity) {
  if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
    [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
  }
  return liquidity.mul(sqrtRatioBX96.sub(sqrtRatioAX96)).div(FixedPoint96.Q96);
}

function getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity) {
  let amount0 = Big(0);
  let amount1 = Big(0);

  if (sqrtRatioAX96.gt(sqrtRatioBX96)) {
    [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
  }

  if (sqrtRatioX96.lte(sqrtRatioAX96)) {
    amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
  } else if (sqrtRatioX96.lt(sqrtRatioBX96)) {
    amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity);
    amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity);
  } else {
    amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity);
  }

  return [amount0, amount1];
}

async function getPoolBalances(_poolContract, _token0, _token1, _priceInDecimals = false, _print = false) {
  let amounts0 = new Big(0);
  let amounts1 = new Big(0);

  const liquidity = new Big((await _poolContract.liquidity()).toString());
  const MIN_TICK  = -887272;
  const MAX_TICK  =  887272;

  const { sqrtPriceX96 } = await _poolContract.slot0();
  const sqrtPriceCurrent = new Big(sqrtPriceX96.toString());

  const sqrtRatioAX96 = Big(TickMath.getSqrtRatioAtTick(MIN_TICK).toString());
  const sqrtRatioBX96 = Big(TickMath.getSqrtRatioAtTick(MAX_TICK).toString());

  const [amount0, amount1] = getAmountsForLiquidity(sqrtPriceCurrent, sqrtRatioAX96, sqrtRatioBX96, liquidity);

  amounts0 = amount0;
  amounts1 = amount1;

  const decim0 = Big(10).pow(Number(_token0.decimals));
  const decim1 = Big(10).pow(Number(_token1.decimals));

  const balance0 = amounts0.div(decim0);
  const balance1 = amounts1.div(decim1);

  if (_print) {
    const add = await _poolContract.getAddress()
    console.log(
      add.substring(0, 9), "Balance",_token0.symbol, balance0.toString(), "Balance", _token1.symbol, balance1.toString()
    );
  }

  if (_priceInDecimals) {
    return [balance0.toString(), balance1.toString()];
  } else {
    return [amounts0.toString(), amounts1.toString()];
  }
}

1 Answer 1

2

You can just query balanceOf(poolAddress) for token0 and token1, that would be much easier.

2
  • I've tried it before and sometimes the amounts are wrong.
    – emilts
    Commented Oct 27 at 9:02
  • Wym "wrong"? BalanceOf can't exactly get it "wrong", what kinda discrepancy do you see?
    – Foxxxey
    Commented Oct 29 at 22:00

Your Answer

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

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