Javascript

如何始終為所有 BSC 代幣獲得合適的價格?乙太坊.js

  • October 13, 2021

我正在編寫我的小應用程序,但在獲取 BSC 代幣價格時遇到了麻煩。問題是:

  1. 我得到一些特定對的奇怪值(例如 SHARD/WBNB、SAFEMARS/WBNB)
  2. 我怎樣才能得到一個基本的和最接近的對,我可以從中確定價格——比如 pancakeswap 交換錶格下的“路線”。是否所有硬幣都有一對應該始終使用的 WBNB?
  3. 例如,如何獲得像 SAFEMOON 這樣的代幣的市值,其中一些代幣被熏制,所以使用 totalSupply() * Price 可能還不夠?喜歡這裡(charts.bogged.finance)
  4. 有沒有辦法確定創建令牌的日期/時間戳?
  5. 當我呼叫 getjrice() 來填充所有這些變數(名稱、小數等)時,它們都是在來自https://bsc-dataseed1.binance.org的單獨查詢中提供的?如果是這樣,您對如何最有效地減少轉移和時間有什麼建議嗎?

我已經找到了一些使用 ethers.js 的方法,這是我的一些程式碼。

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

這是一種非常痛苦的方式。路由器合約具有稱為getAmountsOutand的函式getAmountsIn,使用它們。只需傳入令牌路徑和輸入或輸出的金額,它將返回如果該交易發生時您將收到的金額。它解釋了價格影響本身,您不必擔心。

結果 token0 和 token1 按配對令牌的 ASC 排序順序排序。

對於 WBNB,BUSD:WBNB 合約地址比 BUSD“小”,所以你得到的金額是正確的。

對於 WBNB,UST: 0x23.. 小於 0xbb,所以輸出順序應該顛倒。

token0 按排序順序必須嚴格小於 token1。

引用自:https://ethereum.stackexchange.com/questions/100062