0

I have a simple code to get prices from Uniswap V2

const getTokenExchangeRate = async (tokenA, tokenB) => {
  return (
    await dexRouter.methods.getAmountsOut(toWei("1"), [tokenA, tokenB]).call()
  )[1];
};

// usage

const price = await getTokenExchangeRate(LINK, DAI)
priceNormal = web3.utils.fromWei(price)

console.log(priceNormal)

If both coins have equal decimals it works normal, but if there is a difference in decimals I get a huge number. For example

const price = await getTokenExchangeRate(LINK, USDC)
priceNormal = web3.utils.fromWei(price)

console.log(priceNormal)
PS C:\Users\Viktor\Desktop\Uniswap3JS> node test.js
0.000000000009015961

What should I add to get human readable numbers for all possible pairs? Thanks.

3 Answers 3

1
  1. Create an instance for ERC20 contract.
  2. Create instance for the UniswapPair contract
  3. Call decimals() of that tokens.
  4. Create a logic like:
if(tokenDecimals < 18){
 const amountOut = await pair.methods.getReserves().call()
 const parsedAmount = Number(amountOut.tokenB._hex).toFixed(18)
 await dexRouter.methods.getAmountsOut(parsedAmount, [tokenA,tokenB]).call()
}

Can't test if this code will compile but here's is the north.

2
  • Could you upvote? :) Commented Aug 14, 2022 at 18:43
  • 1
    Thanks for the feedback! You need at least 15 reputation to cast a vote, but your feedback has been recorded. Commented Aug 14, 2022 at 18:47
1

Well, I found an answer, though I don't like it. And now I don't understand why getAmountsOut (WETH, USDC) gives a real price and getAmountsOut (USDC, WETH) gives some weird numbers. But that's another story.

const getTokenExchangeRate = async (tokenA, tokenB) => {
  return (
    await dexRouter.methods.getAmountsOut(toWei("1"), [tokenA, tokenB]).call()
  )[1];
};
const price = await getTokenExchangeRate(USDC, WETH9)

// DECIMALS
const abi2 = [
  {
    "constant": true,
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "name": "",
        "type": "uint8"
      }
    ],
    "payable": false,
    "type": "function"
  },
];


const check = new web3.eth.Contract(
  abi2,
  WETH9 //TokenB
);

const result = await check.methods.decimals().call()
let humanPrice = price/(10**result)
0

I would recommend to convert all numbers to a common denominator (i.e. 18 decimal places precision) and perform the analysis with these decimal places.

The Aave V2 repo has some nice utility functions for this purpose.

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.