和第一种情况类似,不重复分析了。 Swap 交易费用Uniswap 最复杂的逻辑是计算交易费用并分配。在添加和删除流动性之前需要将相应的交易费用提取。 Tick 上的总流动性在某个 Tick 上可以存在多个区间。在计算交易费用时,需要平摊这些费用给所有在这个 Tick 上多个区间的总的流动性。在每个区间的边界的 Tick 上记录下 delta_L (所有以这个 Tick 为边界的区间的流动性总和)。 存在一个全局状态:liquidity,保存当前价格对应 Tick 的流动性总和。当价格波动,穿过某个 Tick 时,会进行流动性的增加或者减少(取决于价格波动方向)。举例来说,价格从左到右穿过区间,当穿过区间的第一个 Tick 时,流动性需要增加,穿出最后一个 Tick 时,流动性需要减少,中间的 Tick 都没有流动性的增加和减少(delta_L 为 0)。 区间(Position)上的交易费用率计算一个区间上的交易费用率,采用总的费用率减去区间外的费用率的方法。 在一个区间的边界 Tick 上记录 feeGrowthOutside。所谓的 feeGrowthOutside,就是「另外」一个方向上总的费用率。另外的一个方向是相对穿过当前 Tick 的方向而言。当价格从左到右穿过一个 Tick,feeGrowthOutside 指的是 Tick 左边所有区间的费用率。简单的说,就是价格要去方向的相反方向所有区间的费用率。feeGrowthOutside 用 fo 表示。因为 fo 是一个 Tick 的两个方向的总的费用率,两个方向的费用率的总和肯定是等于 fg (全局的费用率)。所以当穿过一个 Tick 时,这个 Tick 上的 fo 要进行翻转: 当一个区间创建时,区间边界上 Tick 的 fo 需要初始化: 如果当前的价格大于 Tick 的价格时,因为即使当前价格在设置的区间内,但是之前费用也不会分到,所以,可以简单的假想为所有的费用发生在 Tick 价格之下,也就是 fo=fg。如果 Tick 的价格大于当前价格,价格还没有穿过 Tick,因为假设了之前所有发生的费用发生在 Tick 价格之下,Tick 之上是没有费用的,所以 fo=0。在理解了这些逻辑的基础上,在 swap 的过程中,随着价格的波动,一个区间上,超过最高 Tick 的费用率以及低于最低 Tick 的费用率可以用如下的方式计算:
|