使用恆定乘積做市商公式時,Uniswap WETH_WBTC 價格下降了幾個數量級
我正在嘗試使用 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 位小數,所以我猜這是你的問題。