LiquidityNet

LiquidityNet 是集中流动性池在某个刻度边界上的净流动性变化量。它不是该刻度拥有的流动性总额,而是价格穿越边界后,当前有效流动性应增加或减少的差值。

与 LiquidityGross 的区别

  • liquidityGross 记录引用该刻度的所有仓位流动性绝对值之和,用于判断刻度是否已初始化。
  • liquidityNet 记录从低价方向向高价方向穿越刻度时,有效流动性的净变化。
  • 一个刻度可以具有较大的 liquidityGross,同时 liquidityNet 接近零。这说明在该边界开始和结束的仓位规模相近。

仓位如何影响边界

流动性提供者在区间 [tickLower, tickUpper) 增加数量 L 时,两个边界按以下规则记录:

1
2
liquidityNet[tickLower] += L
liquidityNet[tickUpper] -= L
1
2
3
4
5
flowchart LR
A[低于 tickLower] -->|向上穿越下界 加 L| B[仓位处于有效区间]
B -->|向上穿越上界 减 L| C[高于 tickUpper]
C -->|向下穿越上界 加 L| B
B -->|向下穿越下界 减 L| A

示例

设仓位甲在区间 [-100, 100) 提供 5000 单位流动性,仓位乙在区间 [0, 200) 提供 3000 单位流动性。

刻度 LiquidityNet 含义
-100 5000 仓位甲开始生效
0 3000 仓位乙开始生效
100 -5000 仓位甲停止生效
200 -3000 仓位乙停止生效

价格从刻度 -150 上升到 150 时,有效流动性依次为 0500080003000。所有刻度的 liquidityNet 理论总和应为零,因为每一份流动性都同时具有开始边界与结束边界。

实现要点

1
2
3
4
5
6
7
8
function crossTick(
uint128 currentLiquidity,
int128 liquidityNet,
bool zeroForOne
) pure returns (uint128 nextLiquidity) {
int128 signedDelta = zeroForOne ? -liquidityNet : liquidityNet;
return LiquidityMath.addDelta(currentLiquidity, signedDelta);
}

审计时应重点检查符号方向、整数位宽、流动性下溢、刻度初始化状态,以及删除最后一个仓位后是否正确清理边界数据。

LiquidityNet 原始示意图