AMM自動撮合交易合約模型解析 Lidquidity pool交易模型 流動性份額計算與更新 交易價格計算

在上篇文章當中,我們講解了在Defi應用當中的一種去中心化撮合交易形式——Liquidity Pool。這次,我們來通過詳細地瞭解它的模型來分析它是如何工作的,以及有哪些利與弊。

首先,作爲一個在區塊鏈上的數學模型,我認爲很重要的一件事情就是,它必須很簡單+很可靠,作爲一個交易資產的項目,每一行代碼都關乎到用戶的錢,如果出了問題就會影響到大家對這個項目的觀感,對項目的影響是非常直接的。

在ETH的智能合約裏,用的基本上都是integer arithmetic(整數運算),所以有時候會遇到計算之後得到的是浮點數導致的誤差,有些時候這種誤差是很致命的,但是在文章裏有講到如何把這種運算結果進行取整同時將影響控制在有限的範圍內,這些我們在後面會講到。

下面的部分參考自Uniswap的Whitepaper,網址:https://hackmd.io/C-DvwDSfSxuh-Gd4WKE_ig(需要翻牆)

Uniswap是一個簡單易用、使用gas效率高、能通過審查且零租金的鏈上交易系統。

Lidquidity pool交易模型

1.y×x=k模型

一個交易對是基於兩個Token進行的,我們假設他們爲X和Y,那麼x和y則是X和Y在這個交易對當中作爲儲備金的token個數。

這個交易對的比率(也就是價格),是基於交易對當中X和Y的數量決定的。在整個交易的過程當中,這個y×x=k的k是一定的。

我們假設在交易過程當中,當你買入了Δx的幣,並且賣出了Δy的幣,那麼公式如下:


推導公式可得出X+Δx和Y-Δy,以及Δx和Δy的值:

這是最基礎的自動交易模型,它可以保持這兩個幣種能一直有一個對應的價格和數量一直進行交易(前提是交易的數量不超過池子內幣種的數量)。

2.加入fee的連續乘積模型

在之前的模型當中,我們默認交易前後的乘積k是不變的。但是這樣很難刺激大家把自己的錢放入到市場當中作爲流動提供者,爲了刺激持幣者,我們需要在交易的時候收取一些手續費來作爲提供流動性的報酬。

收取手續費的比率在0~1之間,我們可以設置爲0.3%,手續費的符號是𝜌,除了手續費外的交易金額爲𝛾=1-𝜌

同樣的,我們可以得到交易後的X與Y的token數量,以及交易兌換變化的Δx和Δy的值。

現在所得到的這個數值就是我們在實際應用過程當中使用的計算公式了,當𝛾=1也就是沒有手續費的時候,這個公式跟上面那個公式就是一樣的了。

這個公式的除了能讓提供流動性的做市商獲得盈利之外,在經濟學上還有一個顯著的變化,就是這個模型的k不是恆定的了,而是會隨着交易有一個緩慢地增長

流動性份額計算與更新

我們使用充值提幣兩種形式來代表對這個交易對的流動性增加和減少。(這裏要注意的是,充值和提幣的操作都是對這個交易對的兩邊的幣種同時進行操作,一次提取和存入的都是兩種貨幣)

在這裏我就以充幣爲例介紹一下在程序裏的實現公式注意事項,在這裏會涉及到之前說過的integer arithmetic(整數運算)所帶來的誤差取整,如果有對智能合約安全感興趣或者想自己做項目的可以仔細看看,沒有興趣的同學可以直接跳到最後的tips了。

1.增加流動性數學公式

在開始之前先介紹一下我們會用到的符號,e代表ether的數量(以wei計,1eth=1,000,000,000,000,000,000wei),t代表交易對另外一個幣的數量,l代表增加流動性的數量,帶'的符號代表狀態改變了之後(存完幣)的數值。

在我們提供了流動性之後,uniswap會返回給你一個erc20的代幣,代表你佔流動性池子的份額。

在數學公式裏,一般都會有一個限定條件,這裏的限定條件就是,這個公式裏的所有的東西都是處於靜態狀態的,也就是隻有從這個狀態變到下個狀態之後裏面的值纔會改變。

α=Δe/e,這個公式很好理解,就是往裏面存的X幣和Y幣的數量一定是等比例的,這個比例取決於之前池子裏X和Y的比例,在你提供了這些流動性之後,池子裏的流動性l就增加了,增加的這部分l就歸你了。

同時也保證了,在整個計算過程當中,e:t:l的比例都是固定的。

通過上面這個式子的額外推導,我們可以得出以下的幾條定理:

2.增加流動性的代碼實現

這一部分就牽扯到之前說的integer arithmetic(整數運算),由於α=Δe/e得到的數字是一個浮點數,取整之後會有一個誤差。在Uniswap當中,他們利用了這個誤差<1的特點,設計了下面這個方式來消除誤差的影響。

Δe的數量是優先決定的,Δt的數量在之前那個計算之後向下取整,最後提供的總體流動性也是向下取整的。

這個設計可以得到下面這些定理:


首先要保證的是,用戶得到的流動性代幣<=用戶充值後提供的流動性。這裏l的比較久可以說明這一點,l''代表的是在程序當中最後計算出置換給用戶的流動性代幣,這個代幣後面會用於提幣的時候的憑證,通過這個代幣可以從池子當中提取流動性。

同時,這個取整+1的操作保證了對用戶的價值減少會控制在一個很小很小的範圍內,因爲數字貨幣的有效數字基本上都在10位以上,所以可以說是沒有影響。

關於增加流動性的操作就講到這裏,提幣(減少流動性)也就是將剛剛我說的這些公式反過來罷了,如果很有興趣的朋友可以直接去看上面鏈接的文章。

交易價格計算

我們一開始講了關於整個交易的k變化的計算,但是在交易的時候,我們總是要提供給交易者他交易的價格,才能讓交易者知道自己的代幣是以一個什麼價格成交的。與普通的報價單不同,交易價格是隨着交易者選擇交易貨幣的數量變化而變化的

其實算價格很簡單,price=Δx/Δy,我們所需要計算的就是在已知其中一個情況下計算另外一個是多少。

這裏有兩種算法,一個叫getInputPrice(通過限定Δx來算出Δy),另外一個叫getOutputPrice(通過限定Δy來算出Δx)。

getInputPrice

當手續費爲0.3%時,直接代入下列公式,就可以得到Δy的值

getOutputPrice

同樣帶入公式,就可以得到Δx的值

這裏的代碼計算同樣需要用到我們之前提到的那個整數運算向下取整的方法來規避套利者利用漏洞攻擊合約的行爲。

基本上關於合約模型就到這裏結束了,在論文當中後面的第四部分還就合約交易的3種模式進行了講解(ETHtoToken、TokentoETH、TokentoToken),其中用到的東西基本上就是上面我所說的這些數值了,基本上都是比較重複的概念。

寫在最後的tips:

看到這裏的同志都不容易,其實這篇論文是在2018年發表的,所以其中的技術都是Uniswap v1的概念,Uniswap v2在此之上還進行了一些改動,取消了完全以eth作爲橋樑的交易方式,可以直接進行token-token之間的交易,這樣可以降低這種交易所消耗的gas。

在合約裏,數學完備性是最重要的一條,即使是像我上面分析的這麼簡單的公式,也很難適應於所有的代幣。

比如這個通縮模型的BOMB幣,在每筆交易過後會銷燬整個網絡當中0.2%交易量的代幣,在Uniswap上線之後被人發現可以用於套利,由此發展出各種各樣通縮類型的代幣。

上面講的這個例子也只是冰山一角,在Uniswap上多次被攻擊提取走eth的示例也還有很多。其實這件事告訴我們,一個代幣的經濟模型有可能對這個交易模型產生影響,如果在設計交易模型的時候不考慮代幣的經濟模型,很容易產生bug。所以如果想參與這種池子類型交易的同學,最好選擇固定總量的代幣或者是通脹代幣。

Uniswap其實也並沒有這篇文章講的這麼簡單,它在設計的理念當中還涉及到一個“閃貸”的套利方式,可以在一個區塊內實現轉換+套利+反轉換的操作,有興趣的同學也可以去看看。

作爲一個API比較完備的項目,很多其他的Defi項目會使用Uniswap作爲交易媒介,這樣整個智能合約都可以在鏈上實現,完全規避主體風險。

但是我們也要考慮到這種全部都在智能合約上實現的系統性風險,畢竟就如2008年的次貸危機一樣,這種套利機器有可能給市場上想撬動槓桿的人一個可乘之機,觸發CTA信號或者質押的平倉線產生突發性的行情。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章