Solidity

從 Q64.96 數字計算 Uniswap V3 對價格

  • October 31, 2021

我正在嘗試計算 Uniswap v3 池獎。

我可以得到 Q64.96 數字的平方根價格uint160(例如, -DAI 1234217676608908277512433764/ETH 池的價值(當時價格約為 1 ETH 換 4090 DAI))。

這可以通過檢索IUniswapV3PoolState.slot0()

正如函式文件字元串所說:“sqrtPriceX96 池的目前價格為 sqrt(token1/token0) Q64.96 值”

如何將此數字轉換為uint256

計算出的價格應該表明 1 ETH 對應 4090 DAI 的價值

有沒有其他方法可以獲得 Uniswap V3 對的價格?

答案最好是可靠的,但其他答案也是可以接受的。

不成功的嘗試

我嘗試將數字平方1234217676608908277512433764,然後將其移動 96,但結果1.922666416729829e+25似乎不太正確。

(1234217676608908277512433764^2) >> 96 = 1.922666416729829e+25

   function getPrice(address tokenIn, address tokenOut)
       external
       view
       returns (uint256 price)
   {
       IUniswapV3Pool pool = IUniswapV3Pool(factory.getPool(tokenIn, tokenOut, FEE);
       (uint160 sqrtPriceX96,,,,,,) =  pool.slot0();
       return uint(sqrtPriceX96).mul(uint(sqrtPriceX96)).mul(1e18) >> (96 * 2);
   }

以 1e18 精度返回現貨價格。小心使用現貨價格,因為它是閃電貸攻擊的對象。要麼使用 TWAP 價格,要麼在使用現貨價格之前檢查價格沒有太大變化。此外,我還沒有測試此程式碼的精度損失和上限/下限。因為 Uniswap v3 對小數使用 Q64.96 概念,但它似乎並不實用。該函式的輸出是一個精度為 e18 的數字。這取決於您在項目中使用的十進制庫。

sqrtPriceX96 和 price 的關係在官方文件中有提到:https ://docs.uniswap.org/sdk/guides/fetching-prices

   sqrtPriceX96 = sqrt(price) * 2 ** 96
   # divide both sides by 2 ** 96
   sqrtPriceX96 / (2 ** 96) = sqrt(price)
   # square both sides
   (sqrtPriceX96 / (2 ** 96)) ** 2 = price
   # expand the squared fraction
   (sqrtPriceX96 ** 2) / ((2 ** 96) ** 2)  = price
   # multiply the exponents in the denominator to get the final expression
   sqrtRatioX96 ** 2 / 2 ** 192 = price

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