本文详细探讨了Uniswap中的价格定义,强调价格作为一种比率的重要性,并介绍了时间加权平均价格(TWAP)的概念及其在防止价格操纵攻击中的作用。此外,文章深入分析了如何在Solidity中实现TWAP的计算和相关的智能合约设计,包括累积价格、快照机制和可能的溢出问题。
假设我们在一个池中有 1 个以太币和 2,000 个 USDC。这意味着以太币的价格是 2,000 USDC。具体来说,以太币的价格是 2,000 USDC / 1 Ether(忽略小数)。
更一般地说,资产的价格,在另一资产的价格方面,是一个比例,其中“你关心的资产”处于分母中。
$$ \mathsf{price}(\text{foo})=\frac{\mathsf{reserve}(\text{foo})}{\mathsf{reserve}(\text{bar})} $$
在上面的例子中,在问“需要多少个 bar 才能获得一个 foo”(忽略手续费)。
因为价格是一个比例,它们需要以具有小数点的数据类型来存储(而 Solidity 类型默认没有小数点)。
也就是说,我们说以太坊的价格是 2000,而 USDC(在以太坊价格中)是 0.0005(这是忽略了两个资产的小数部分)。
Uniswap 使用 固定点数字,在小数点的每一侧有 112 位的精度,这总共占用 224 位,当与 32 位数字打包时,它仅使用一个插槽。
在计算机科学术语中,预言机是“真相的来源”。价格预言机是价格的来源。当持有两个资产时,Uniswap 有一个隐含的价格,其他智能合约可以将其用作价格预言机。
预言机的预期用户是其他智能合约,因为其他智能合约可以轻松与 Uniswap 通信以确定价格,但从链外交易所获取价格数据要困难得多。
然而,仅仅通过余额的比例来获取当前价格并不安全。
测量池中资产的瞬时快照留下了闪电贷攻击的机会。也就是说,某人可以利用闪电贷进行巨额交易,从而导致价格的暂时剧烈变化,然后利用另一个使用此价格做出决策的智能合约。
Uniswap V2 预言机以两种方式对其进行防御:
这不应给人留下印象,即使用移动平均的预言机对价格操纵攻击免疫。如果资产流动性不足,或者进行平均的时间窗口不够大,那么资源充足的攻击者仍然可以在足够长的时间内支撑或压制价格,以操纵测量时的平均价格。
TWAP(时间加权平均价格)类似于简单移动平均,只是时间价格“保持不变”的时间更长会得到更大的权重——TWAP 按 价格保持在某一水平的时间 加权价格。
一般来说,TWAP 的公式是
$$ \text{time-weighted average price} = \frac{P_1T_1+P_2T_2+\dots+P_nTn}{\sum{i=1}^nT_i} $$
这里 T 是持续时间,而不是时间戳。也就是说,价格在该水平保持了多久。
在我们上面的例子中,我们仅查看了过去 24 小时的价格,但如果你关心过去一小时、一周或其他某个时间段的价格呢?Uniswap 当然不能存储每个人可能感兴趣的每个回顾,并且也没有好的方法来始终快照价格,因为某人必须支付汽油费用。
解决方案是,Uniswap 仅存储值的分子——每当流动性比例发生变化(调用 mint、burn、swap 或 sync 时),它记录新的价格和 先前价格持续的时间。
![twap 代码注释](https://img.learnblockchain.cn/2025/02/26/935a00_db5fb7c3ed5b4e37ae3550b1f...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!