我正在查看uniswap 文档,其中说明了这个示例:
\n\n\n在 WETH / USDC 池中查找 WETH 价格的示例,其中\nWETH 是 token0,USDC 是 token1:
\n您有一个 oracle 读数,显示 tickCumulative 返回为\n[70_000, 1_070_000],观察之间的经过时间为\n10 秒。
\n我们可以通过累加器值的差值 (1_070_000 - 70_000 = 1_000_000) 并除以经过的时间 (1_000_000 / 10 = 100_000) 来得出此间隔内的平均刻度。
\n当价格变动读数为 100_000 时,我们可以通过将当前价格变动用作公式 p(i) = 1.0001**i 中的 i 来求出代币 1 (USDC)\n 以代币 0 (WETH) 表示的值(参见公式 p(i) = 1.0001**i 中的 6.1)白皮书)。
\n1.0001**100_000 \xe2\x89\x85 22015.5 USDC / WETH
\n
WETH 的价格不是 22015.50 美元。我想也许他们只是用了一个简单数字的例子。所以我决定尝试一下USDC/WETH 矿池白皮书中的示例
\n\n调用slot0合约返回:
制定价格
\n\n\n1.0001 ** 205930 = 876958666.4726943
\n
显然 ETH 的价格不是 876958666 USDC。当前价格为 205930,但 ETH 的价格仅为 1200.49 USDC。如何从报价中获取 ETH 的正确 USDC 价格?
\nkfx*_*kfx 27
在主网上,USDC ERC-20代币有6位小数,ETH有18位小数。然而,Uniswap 内部跟踪的价格并不知道这些小数:它实际上是每 1 wei 1 个微型 USDC(即 0.000001 USDC)的价格。
该价格是通过计算 Uniswap v3 报价基础常数 1.0001 的指数来计算的。如果价格变动为 205930,您将得到结果:
1.0001 ** 205930 = 876958666.4726943
Run Code Online (Sandbox Code Playgroud)
要将此内部价格调整为人类可读的价格,您必须将其乘以10**6(USDC 的小数点)并除以10**18 ([W]ETH 的小数点),这等于将价格乘以10**-12。
876958666.4726943 * (10 ** -12) = 0.0008769586664726943
Run Code Online (Sandbox Code Playgroud)
最后,您可能想要这个数字的倒数。您刚刚得到的小数字是 USDC 以 ETH 表示的价格,但我们通常希望跟踪以 USD[C] 表示的 ETH 价格。这是因为 Uniswap 中的价格被定义为等于token1/token0,这是一个 USDC/WETH 池,也就是说token0是 USDC,token1是 WETH。
计算逆:
1 / 0.0008769586664726943 = 1140.3045984164828
Run Code Online (Sandbox Code Playgroud)
答案是每 1 ETH 大约 1140.30 USDC。
如果你这样做Solidity,请考虑到它没有浮点数,所有计算都是用定点数完成的。具体来说,Uniswap 使用二进制定点数(Q 数字),并跟踪价格乘以 的平方根2**96。