# Converting Uniswap sqrtPriceX96 into wei

I'm trying to figure out how to convert a uniswap ratio into wei (and eventually ether).

The uniswap docs commonly mention `sqrtPriceX96`:

A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)

However, I can't figure out how to convert it into wei (and eventually ether).

Here is my C# Code:

``````BigInteger sqrRtPrice = BigInteger.Parse("1407006288156847466476392762276105");
var tt = (sqrRtPrice * sqrRtPrice) * (BigInteger)(1e18) / (BigInteger)(1e18) / BigInteger.Pow(((BigInteger)2), 192);
var eth = Nethereum.Util.UnitConversion.Convert.FromWei(tt);
``````

In this example, `eth` becomes `0.000000000315379099` which is close to what Uniswap says `0.000315432`, but I don't understand why mine is off by 6 decimal places. Both tokens in the pool I'm looking at (WETH-DAI) are 18 decimals long. I'm trying to convert Uniswap `sqrtPriceX96` to the price I see on the Uniswap display, but I don't understand why I'm a few decimal places off.

I got my current formula from here, but I also tried the formula here and had the same problem.

sqrtPriceX96 is represented as token1 over token0 or rather how much token1 is needed for 1 token0.

Because solidity uses fixed point numbers there are no decimal places used.

This is a must read on the topic https://uniswap.org/blog/uniswap-v3-math-primer.

Token 1 is determined by which token contract address base16 value is greater.

``````>>> 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 > 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
True
``````

WETH has 18 decimals of precision, USDC has 6.

Price is reported in the slot0 call avaialble on all Uniswap V3 pools.

``````[ slot0 method Response ]
sqrtPriceX96   uint160 :  1837769053120899173775504701779545
``````

In solidity to get price you would do

``````FullMath.mulDiv(
uint256(_sqrtRatioX96) * uint256(_sqrtRatioX96),
10 ** _decimal0,
1 << 192
);
``````

In nodejs you would do

``````const returnPrice = async (poolContract, decimals0) => {
const sqrtPriceX96 = (await poolContract.slot0())[0];
return sqrtPriceX96
.pow(BigNumber.from("2"))
.mul(BigNumber.from("10").pow(decimals0))
.div(BigNumber.from("2").pow(BigNumber.from("192")));
};
``````

In python you would do

``````one_token0 = round(decimal.Decimal(sqrtPriceX96 * sqrtPriceX96 * ((10**decimal_token0) / (10**decimal_token1)) / (2 ** 192)), decimal_token1)
``````

Also there are some helpful documents in the Discord if you haven't met the wonderful Rachel.

Example

``````>>> one_token0 = round(decimal.Decimal(sqrtPriceX96 * sqrtPriceX96 * ((10**6) / (10**18)) / (2 ** 192)), 18)
>>> one_token0
Decimal('0.000538050080273366') # how much WETH for 1 USDC

>>> one_token1 = 1 / one_token0
>>> one_token1
Decimal('1858.563053260640816896359652') # how much USDC for 1 WETH
``````

The first returned value is in 18 decimal precision. Gwei you would multiple by 1e9 and Wei you would multiply by 1e18.

I'm not sure your sqrtPrice is correct. Here I pull the WETH-DAI 5 bips pool (both tokens are 18 decimals of precision as you note). https://etherscan.io/address/0x60594a405d53811d3bc4766596efd80fd545a270#readContract.

``````[ slot0 method Response ]
sqrtPriceX96   uint160 :  1837867657081239291626318498

>>> one_token0 = round(decimal.Decimal(sqrtPriceX96 * sqrtPriceX96 * ((10**18) / (10**18))
/ (2 ** 192)), 18)
>>> one_token0
Decimal('0.000538107819075710')

>>> one_token1
Decimal('1858.363630020591262902910979')
``````

If things still don't make sense let me know.

`sqrtPriceX96` is the number which is the ratio between pool tokens. it does not represent any value. as you shared a quote from docs

A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0)

Here's how you can consistently convert UniV3 sqrtPriceX96 to price with 18 decimals in Solidity, same principle can be applied in JS. You have to covert it from square root price and adjust for decimals:

``````function getPrice(uint160 sqrtRatioX96, uint dec0, uint dec1)
external
pure
returns (uint256 price)
{
uint256 dec = dec1<=dec0 ? (18-dec1)+dec0 :dec0;
uint256 numerator1 =uint256(sqrtRatioX96) *uint256(sqrtRatioX96);
uint256 numerator2 =10**dec;
price = FullMath.mulDiv(numerator1, numerator2, 1 << 192);
}
``````
• Instead of adding the same answer to multiple question it will be better if you flag them as duplicates.
– Ismael
Commented Jan 28 at 5:41