3

I'm coding my small app and I'm having trouble getting BSC token prices. The problem is:

  1. I'm getting weird values for some specific pairs (eg. SHARD/WBNB, SAFEMARS/WBNB)
  2. How can I get a basic and closest pair from which I can determine prices - something like 'Routes' under the exchange form on pancakeswap. Do all coins have a pair to WBNB that should always be used?
  3. How to get marketcap for a coin like SAFEMOON for example, where some of the tokens are smoked, so using totalSupply() * Price is probably not enough? Like here (charts.bogged.finance)
  4. Is there any way to determine the date/timestamp the token was created?
  5. When I call getjrice() to fill all these variables (name, decimals etc), it is all delivered in separate queries from https://bsc-dataseed1.binance.org ? If so, do you have any advice on how to do this most efficiently to reduce transfer and time?

I have already found some ways to play with ethers.js, and here is some of my code.

import { ethers } from 'ethers'
const fs = require('fs');

let url = 'https://bsc-dataseed1.binance.org';
let provider = new ethers.providers.JsonRpcProvider(url);


const USDT = '0x55d398326f99059ff775485246999027b3197955'
const BUSD = '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56';
const WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
const UST = '0x23396cf899ca06c4472205fc903bdb4de249d6fc';
const DAI = '0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3';
const SHARD = '0xD8a1734945b9Ba38eB19a291b475E31F49e59877';
const SAFEMARS = '0x3aD9594151886Ce8538C1ff615EFa2385a8C3A88';
let SAFEMOON = '0x8076C74C5e3F5852037F31Ff0093Eeb8c8ADd8D3';
let PHANTOM = '0xcECdC98AA5Ef7f687C914a3aAE00cCe17DdeaFa3';

// LP V2
const pancakeFactoryAddress = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73"

// JSON files from here: https://github.com/risingsun007/pancakeswap_get_price
const pancakeFactoryJson = "pancake_factory.json";
const pancakeFactory = JSON.parse(fs.readFileSync(pancakeFactoryJson));
const pancakePairJson = "pancakepair.json";
const pancakePair = JSON.parse(fs.readFileSync(pancakePairJson));

const pancake = new ethers.Contract(pancakeFactoryAddress, pancakeFactory, provider);


export const getPrice = async (token0: string, token1: string) => {
  const pairAddress = await pancake.getPair(token0, token1);

  if(pairAddress === '0x0000000000000000000000000000000000000000'){
    return {
      status: 'Pair not found'
    }
  }
  
  
  const tokenContract0 = new ethers.Contract(token0, pancakePair, provider),
        tokenContract1 = new ethers.Contract(token1, pancakePair, provider),
        tokenDecimals0 = tokenContract0.decimals(),
        tokenDecimals1 = tokenContract1.decimals(),
        pairContract = new ethers.Contract(pairAddress, pancakePair, provider),
        reserves = await pairContract.getReserves(),
        totalSupply = await pairContract.totalSupply()

  let r0, r1;
  r0 = reserves._reserve0;
  r1 = reserves._reserve1;

  return {
    tokens: [await tokenContract0.name(), await tokenContract1.name()],
    decimals: [await tokenDecimals0, await tokenDecimals1],
    pairAddress: pairAddress,
    totalSupply: totalSupply.toString(),
    reserves: [
      r0.toString(), 
      r1.toString()
    ],
    price: (r1 / 10 ** await tokenDecimals1) / (r0 / 10 ** await tokenDecimals0)
  }
}


getPrice(WBNB, BUSD).then((result) => {console.log(result)})
// RESULT OK - price: 354.66429096612507
// exchange.pancakeswap shows: 354.431 BUSD per WBNB


getPrice(PHANTOM, BUSD).then((result) => {console.log(result)})
// RESULT OK - price: 0.6465541804048065
// exchange.pancakeswap shows: 0.644938 BUSD per Phantom


getPrice(WBNB, UST).then((result) => {console.log(result)})
// WRONG RESULT - price: 0.0028052627557905675
// if I change the price formula for: reserve0 / reserve1 the result is ok (for this pair)


getPrice(SHARD, WBNB).then((result) => {console.log(result)})
// WRONG RESULT - price: 1215.2873592032508
// exchange.pancakeswap shows:  0.000000177215 WBNB per SHARD


getPrice(SAFEMOON, WBNB).then((result) => {console.log(result)})
// WRONG RESULT - price: 1.1423152711429623e-8
// exchange.pancakeswap shows: 0.0000000112533 WBNB per SAFEMOON


getPrice(SAFEMARS, WBNB).then((result) => {console.log(result)})
// WRONG RESULT - price: 5.565101362273654e-10
// exchange.pancakeswap shows: 0.000000195489 BUSD per SAFEMARS
1
  • This question would be better as several separate questions. A single question per SE post works the best.
    – Gajus
    Jun 1, 2021 at 23:14

3 Answers 3

1

This is a SERIOUSLY painful way to take. The router contract has functions called getAmountsOut and getAmountsIn, use them. Simply pass in the token path&amount inputted or outputted and it will return the amount you would receive if that tx were to happen. It accounts for price impact itself, you don't have to worry about that.

1
  • I'm looking at the code for the pancake factory contract and I'm not seeing either of those events. Could you elaborate in your answer on your method for getting pancakeswap prices with the ether.js api please? Nov 5, 2021 at 13:42
0

resulting token0 and token1 are ordered by ASC sort order of pairing tokens.

for WBNB, BUSD: WBNB contract address is 'smaller' than BUSD, so you get the correct amount.

for WBNB, UST: 0x23.. is smaller than 0xbb, so the output order should be reversed.

token0 must be strictly less than token1 by sort order.

2
  • let WHITELIST: string[] = [ "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82", // CAKE "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", // WBNB "0xe9e7cea3dedca5984780bafc599bd69add087d56", // BUSD "0x55d398326f99059ff775485246999027b3197955", // USDT "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d", // USDC "0x23396cf899ca06c4472205fc903bdb4de249d6fc", // UST "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", // BTCB "0x2170ed0880ac9a755fd29b2688956bd959f933f8", // WETH ]; @levent can you suggest me correct order here? What is the logic behind correct order. facing same issue. Oct 14, 2021 at 9:48
  • 2
    pairReserves = await contract.getReserves(); if (token1.toLowerCase() > token2.toLowerCase()) { pairIndex=1; } else { pairIndex=0; } return pairReserves[pairIndex]; You can find the correct order by comparing them like in this code, looks stupid but it works.
    – levent
    Oct 15, 2021 at 10:08
0

Stop using getReserves(). Use kLast().

2

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.