曲線不變量簡介 - 第一部分

本文為機器翻譯
展示原文

這篇文章的第一部分討論了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
收藏
評論