Web3js

使用恆定乘積做市商公式時,Uniswap WETH_WBTC 價格下降了幾個數量級

  • January 27, 2022

我正在嘗試使用 Web3js 和 Uniswap 智能合約中的方法計算 Uniswap 上的交易所的價值。

這是 WETH(Wrapped Ether)的 Uniswap 合約地址:WBTC(Wrapped Bitcoin)對 0xBb2b8038a1640196FbE3e38816F3e67Cba72D940

使用該合約地址和合約 ABI,我為合約構造了一個 js 對象,如下所示:const pairContract = new web3.eth.Contract(pair.abi, pair.address);

這工作正常,我能夠讀取合約方法以及合約上的呼叫方法(我只使用只讀方法 - 我不需要簽署任何交易)。所以我可以getReserves像這樣呼叫方法

const reserves = await pairContract.methods.getReserves().call();

這是響應(在此_blockTimestampLast

{
 '0': '296352466321',
 '1': '37712426843492788602200',
 '2': '1621116220',
 _reserve0: '296352466321',
 _reserve1: '37712426843492788602200',
 _blockTimestampLast: '1621116220'
}

_reserve0是 WBTC 儲備,_reserve1是 WETH 儲備

現在,在這個實現中,不知何故出了問題……

const BigNumber = require('bignumber.js');

const estimateTrade = (
 baseTokenReserves, 
 quoteTokenReserves, 
 numberOfBaseTokenTradedIn, 
 feePercent)=> {

       // x * y = k

       const feeMultiplier = BigNumber(1).minus(feePercent.dividedBy(100));

       const k = baseTokenReserves.times(quoteTokenReserves);

       const baseTokenNewTotal = baseTokenReserves.plus(numberOfBaseTokenTradedIn.times(feeMultiplier));

       const quoteTokenNewTotal = k.dividedBy(baseTokenNewTotal);

       const quoteTokenReceived = quoteTokenReserves.minus(quoteTokenNewTotal);

       return quoteTokenReceived;

}

estimatedTrade用這些參數呼叫我的方法……

const baseTokenReserves = BigNumber(_reserve0);
const quoteTokenReserves = BigNumber(_reserve1);
const numberOfBaseTokenTradedIn = BigNumber(1);
const feePercent = BigNumber(0.03);

const tokensReceived = estimateTrade(baseTokensReserves, quoteTokenReserves, numberOfBaseTokenTradedIn , feePercent)

console.log(`tokensReceived = ${tokensReceived.toFixed()}`) //tokensReceived = 127151098781.56376683928985070517

這顯然是遙遙無期。當我在 Uniswap 上查看 1 WBTC 可以獲得多少 WETH 時,我大致看到了12.677。我檢查了幾個小時,每次我的答案都小數點後 10 位(10,000,000,000 次)。此方法適用於我嘗試過的所有其他配對(WETH_SUSHI、WETH_UNI 等),除了 WETH_WBTC。任何人都可以看到問題是什麼?謝謝!

在查看 USDC 和 WETH 並使用 ethers.js 時,我遇到了類似的問題。這就是我最初轉換我的大數字的方式:

const reserve0 = Number(ethers.utils.formatUnits(reserves[0], 18)); //USDC
const reserve1 = Number(ethers.utils.formatUnits(reserves[1], 18)); //WETH

我發現問題在於 USDC 只使用 6 位小數,而不是 18 位。所以我不得不將其更改為:

const reserve0 = Number(ethers.utils.formatUnits(reserves[0], 6)); //USDC
const reserve1 = Number(ethers.utils.formatUnits(reserves[1], 18)); //WETH

根據 etherscan 上的 WBTC 合約,WBTC 使用 8 位小數,所以我猜這是你的問題。

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