Solidity
從 Q64.96 數字計算 Uniswap V3 對價格
我正在嘗試計算 Uniswap v3 池獎。
我可以得到 Q64.96 數字的平方根價格
uint160
(例如, -DAI1234217676608908277512433764
/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