曲线不变量简介 - 第一部分

本文为机器翻译
展示原文

这篇文章的第一部分讨论了StableSwap不变量。

StableSwap

放大不变量是一个数学概念,旨在通过减少交易中的滑点来提高流动性池的效率,同时仍然允许价格失衡的灵活性。它结合了恒定和恒定乘积不变量的特点,创造了一个在低滑点(接近平衡)和任何价格下的可追溯性之间取得平衡的公式。

感谢您阅读Verichains!免费订阅以接收新帖并支持我的工作。

  • 恒定乘积不变量(∏x_i=k):用于Uniswap类型的池。它非常灵活,支持任何价格的交易,但大交易的滑点会显著增加。

  • 恒定和不变量(∑x_i=k):用于稳定币。它对平衡交易没有滑点,但无法处理大的价格失衡。

  • 放大不变量结合了两者的优点:接近平衡时的低滑点和失衡交易的灵活性。StableSwap中放大系数参数的特点是,系数越低,不变量就越接近恒定乘积。

引入了一个杠杆因子χ来减少滑点。这个因子调整了不变量的形状,使其能够融合恒定乘积和恒定和不变量的特性,提高其在不同交易场景下的效率。

一般公式为:

其中:

  • χ:控制不变量曲率的杠杆因子。

  • D:平衡时代币价值之和的常数。

  • n:池中代币的数量。

  • ∑x_i:代币数量之和。

  • ∏x_i​:代币数量之积。

如果这个方程式一直成立,用户将获得杠杆χ的交易。但是,它不会支持价格远离理想价格1.0的情况。不变量应该支持任何价格(以确保在任何时候都有一些流动性)。所以Stable Swap使χ动态化。当投资组合完全平衡时,它等于一个常数A,但当失衡时会降至0:

StableSwap不变量将χ加入到一般公式(1)中:

有两个常见的数学运算需要计算:

  • 给定固定的A值和储备x_1,x_2,...x_n(其中n是池支持的代币数量,在部署池时就固定了),计算D

  • 给定D,用户希望增加一个储备xi​的值到x'_i,计算另一个储备x_j​需要减少多少,以保持方程平衡。

在Curve V1(StableSwap)中,D的行为类似于Uniswap V2中的k​ - D越大,储备越多,价格曲线就越"远离"。在添加或移除流动性,或费用变化导致池平衡发生变化后,D都需要重新计算。

定义S=∑x_i和P=∏x_i​,方程(3)现在变为:

例如,如果池中只有两种代币,不变量将变为:

在StableSwap源代码中,它通过计算D_next来计算D:

aaaa

这段代码中的方程可以写为:

例如,我们有100,000 USDC和1,000,000 USDT在池中。使用(3)或(4),我们可以计算出D约为1,094,540.84。这是一个使用(5)(因为它是(4)的示例)计算D的简单Python脚本:

我们可以再次使用该常量D来计算USDT或USDC的数量,使用(6)。

StableSwap使用牛顿法数值求解方程,因为它无法代数求解。StableSwap创建f(D),当方程(4)平衡时等于0。此外,它还计算导数f′(D)

StableSwap使用牛顿法求解D,其中D可以理解为当前的D值:

首先,我们可以通过将所有元素合并成一个分数,并将分数的分子和分母都乘以D来重写(8):

通过使分母等于f'(D)来重写牛顿法,然后用(10)代替:

将所有项分配到分子中的括号中:

在(11)中消除所有项后,我们可以定义一个元素D_p为:

方程变为:

这个方程等同于(6)中定义的方程。

此外,在Viper代码中,D_p的计算方式为:

D_P: uint256 = D # D_P = Sfor _x in xp:D_P = D_P * D / (_x * N_COINS)

xp是代币数量,所以循环将运行n次。因此,我们在分母中有D乘以自身n次。

然后我们可以计算yx'_j(即x_j​的新值)当用户增加一个储备x_i​的值到x'_i​时。

使用S=∑x_iP=∏x_i.假设要计算代币y的值,给定D, A, n;让我们稍微调整一下SP的公式:

SP′是除了我们要计算的代币y之外的所有代币的余额之和和乘积。

公式从(4)变为:

同样,StableSwap使用牛顿法数值求解方程。这次它创建了f(y)和导数f′(y)

StableSwap的牛顿法求解y为:

将(13)和(14)组合成该方程,可以转换为:

再次重写(16)方法,使分母等于(14):

另一方面,(12)可以重写为f(ADn^n):

将其代入(17),然后消除所有项:

我们将分子和分母都乘以y/(A*n^n):

再次重写不变量(12),并将其代入(20):

公式(23)可以执行为:

在Viper源代码中,定义了两个变量:

将其代入公式(24),我们得到:

Curve源代码中有两个计算y的函数,get_yget_Y_D。`get_Y_D`函数根据D计算y,与上述方法相同。此外,`get_y`函数在一个代币x的数量从x变为x'时计算新的y。回到上面的例子,如果我们想将10,000 USDT兑换成USDC,使用get_y函数,用户可以获得9,253.70 USDC。这是因为,在该示例中,USDT的数量是USDC的10倍。因此,当用户将USDT兑换为USDC时,会产生滑点。

aaaaa

需要注意的一点是,Curve的白皮书使用的不变量是An^n (A * n ** n),但在Viper源代码中,不变量是Ann (A * n * n)。

aaaaaa

代码库反而计算A_ * n。这种差异是因为代码库将A_存储为:

参考

https://docs.curve.fi/

https://www.rareskills.io/post/curve-get-d-get-y

感谢阅读Verichains!订阅免费接收新帖并支持我的工作。

相关赛道:
来源
免责声明:以上内容仅为作者观点,不代表Followin的任何立场,不构成与Followin相关的任何投资建议。
喜欢
1
收藏
评论