流動性的計算
Last updated
Last updated
乘積固定的交易模型(v2模式),滿足資金池中的兩種代幣金額滿足:xy=K。如果設定K=L^2的話,xy=L^2。 L就是我們說的流動性。由乘積固定的交易模型得出如下的公式:(P=price)
在已知L和sqrt(P)的情況下,也能推導出資金需求量x和y。
通過公式,在流動性不變的情況下(不添加刪除流動性),流動性可以看成是單位“價格波動”的y資金量的變化。 ”價格波動“打上引號是因為事實上是sqrt(P)的變化。
這個是V3核心公式,用相對值(資金和價格相對值)來計算流動性。所謂的流動性,就是單位“價格變化”的資金量。在一定的交易量的情況下,如果流動性好,價格變化就小,流動性不夠的話,價格波動就大。
V2的流動性是“普適”的,在所有價格點上流動性相同。 V3的流動性是由一系列不同區間上的流動性組成。相對來說,在當前價格左右的流動性比較高。流動性提供者LP只有提供了可供交易的流動性才能獲取交易費。為了獲取更多的交易費,為了提高資金的利用率,流動性提供者會將資金提供在合理的價格波動範圍內。也就是說,在某個區間swap交易產生的手續費,只有該區間流動性提供者才能獲取手續費。為了計算每個區間獲取的手續費,引入了Tick的概念和計算方法。
在區間上提供流動性,帶來很多複雜的情況:區間和區間的重疊覆蓋。因為不同區間的流動性沒有可比性,某個交易費並不能混入到流動資金中,等刪除流動性時候一併提取。為了解決這個問題,V3引入了Tick的概念。交易費用實時結算並單獨記錄,並不混入流動資金中。雖然整個區間和區間的流動性沒有可比性,但是,在具體的某個價格點上(一個價格片上),流動性是可比較的。 V3將整個價格範圍(負無窮到正無窮)分成一個個的Tick(價格點):
後一個價格點的價格是前一個價格點價格基礎上浮動萬分之一。
每個Tick也有一個唯一的序號。區間(Position)可以由兩個Tick表示。邏輯上交易手續費可以一個個的Tick計算,並在每一個Tick上根據流動性的佔比進行交易分配。先看看一個Tick範圍的swap的計算。
假設有一個很小的量的y,需要swap為x。通過下面的公式,可以計算出因為y的變化導致的價格變化。
再利用下面的公式可以算出換取的x的量。
V3針對同樣的交易對設置了不同的交易費:0.1%,0.2%以及0.5% 。如果是從Y換取X,則在換取之前先扣除手續費再進行上述的交換。 在同一交易池中只支持一種費率。也就是說,在一個交易池中支持不同的價格區間,但是都是同樣的費率。如果需要添加同樣交易對的不同交易費的交易池,必須創建新的交易池。 接下來,深入講解一下 添加/刪除流動性以及交易費用的計算邏輯。
V3的添加/刪除流動性是當前價格情況下在某個區間添加或者刪除流動性。所有的流動性添加/刪除流動性採用如下的公式:
注意,價格變化並不是指區間的大小,而是在某個區間上提供流動性,相對當前價格,“需要相應資金變化”對應的價格變化。
分為三種情況,想要添加的流動性區間和當前價格的關係。
1. 當前價格處於流動性價格區間 (il <=ic < iu)
因為價格在區間範圍內,如果價格滑動到il,則需要提供y資金。如果價格滑動到iu,則需要提供相應的x資金。所以,對於delta_Y來說的,價格變化為sqrt(P) - sqrt(p(il));對於delta_X來說,價格變化為1/sqrt(P) - 1/sqrt(p(iu))。
2. 當前價格低於流動性價格區間
因為當前價格遠低於il,即使從當前價格向iu滑動,也只需要x的資金,不需要y的資金。所以,在這種情況下,delta_Y=0。因為從il滑向iu需要整個區間的x的資金,對於delta_X來說,價格變化為1/sqrt(il) - 1/sqrt(p(iu))。
在某個Tick上可以存在多個區間。在計算交易費用時,需要平攤這些費用給所有在這個Tick上多個區間的總的流動性。在每個區間的邊界的Tick上記錄下delta_L(所有以這個Tick為邊界的區間的流動性總和)。
存在一個全局狀態:liquidity,保存當前價格對應Tick的流動性總和。當價格波動,穿過某個Tick時,會進行流動性的增加或者減少(取決於價格波動方向)。舉例來說,價格從左到右穿過區間,當穿過區間的第一個Tick時,流動性需要增加,穿出最後一個Tick時,流動性需要減少,中間的Tick都沒有流動性的增加和減少(delta_L為0)。
計算一個區間上的交易費用率,採用總的費用率減去區間外的費用率的方法。在一個區間的邊界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的費用率可以用如下的方式計算:
以低於最低Tick的費用率的計算為例,如果ic>=i (當前的價格是高於最低Tick的),低於Tick的所有的費用率就是fo(定義如此)。如果ic<i的情況下,fo記錄的是高於Tick的所有費用率,所以需要翻轉,即fg - fo。在獲取了一個區間外的所有費用的情況下,計算本區間的費用率:
獲取的費用率的基礎上,用費用率乘以區間的流動性可以計算出該區間收取的費用。