區塊鏈數字資產和加密貨幣市場已發展成為一個充滿活力的金融生態系統。但相較於傳統金融市場,絕大多數專案的設計思路都是基於數字資產或加密貨幣在空間上的轉移,而金融本身仍作為時間定價的工具,塑造了一個關於可量化、可交易的時間維度。Compound 專案在此背景下應運而生,該專案是一種基於供求關係的分散式協議,設計了一種基於貨幣市場設定利率的演算法,實現了使用者無時間摩擦地交易以太坊資產。
本文分為三部分,第一部分簡要介紹該專案中與清算相關的基本概念,第二部分透過示例講解清算流程,第三部分介紹如何設計一個清算機器人。
清算的基本概念
Compound 專案中與清算相關的基本概念主要包括:cToken、Comptroller、Liquidity、Close factor 和 Liquidation Incentive。
//cToken
Compound 協議目前支援 Erc20 和 Ether 兩類基礎資產,cToken 是兩類基礎資產在 Compound 上的整合,轉換公式為 cToken = 基礎資產 / 當前匯率。cToken 在 Compound 上有兩種作用,分別是作為利息的衡量標準和貸款的抵押物。有別於傳統銀行的計算方式,利率是透過複利的形式增長的。cToken 在 Compound 協議中作為度量衡使用。
//Comptroller
Comptroller 透過 collateral factor 對 Compound 協議進行風險管理,即 Comptroller 為協議的風險管理層。每類基礎資產都有相互獨立的 collateral factor,其數值大小根據基礎資產的流動性和市值規模在0~90%浮動。流動性越強,市值規模越高數值越大。若 collateral factor 為0,該類基礎資產不能用作抵押或者在清算中進行抵扣。Compound 根據 collateral factor 確定使用者所需抵押品價值以及該使用者是否可以被清算。
//Liquidity
Liquidity 是 Compound 協議清算的標誌位。當賬戶的 Liquidity 不為正數時,將被該協議的其他使用者清算,直到將 Liquidity 重新設定為正數。賬戶 Liquidity 計算由下列公式(1)、(2)、(3)求得:
其中,tokensToDenom 是將其他資產價格轉換為ETH價格的匯率,oraclePrice 是從預言機中獲得的單價。為解決在原始碼中 Liquidity 是 uint 型別、無法表示負數的問題,原始碼中定義 shortfall = sumBorrowPlusEffects – sumCollateral。很多清算程式為統一表示,將 Compound 協議清算標誌位設為 health。Health 小於1,則表示該賬戶需要被清算。
//Close Factor
Close factor 是需要被清算的部分佔未償還貸款的百分比,即基礎貸款需要被清算的部分。例,一個需要被清算的賬戶 close factor 為0.1,那麼需要清算其貸款的10%。如果使用者擁有多種借入資產,close factor 是某一資產的屬性,並非該使用者總資產的屬性。
//Liquidation Incentive
Liquidation incentive 是為清算人提供額外的抵押品,以鼓勵清算人對 underwater 賬戶進行清算。例如,Liquidation incentive 為1.1,則清算人會獲得借款抵押品10%的獎勵。目前 Liquidation incentive 在1.3~1.5之間。假設 Liquidation incentive 為1.05,可以使用公式(7)計算在清算完成時清算人的收益。
清算流程
為保證 Compound 系統平穩執行,該協議設計了一套完備的風險和清算規則。為了降低貸款風險,Compound 協議在每類資產中增加了 collateral factor 屬性。該屬性定義了某類資產單位抵押物可以借貸其他資產的數量。即,抵押率的一種表示方式。目前的主要借貸協議都是透過超額抵押的方式借款,通常要求抵押率低於 150% ,比如:加入市場的抵押率為150%,使用者在 Compound 超額抵押 ETH 借出一筆 DAI 貸款,但不巧的是,在貸款期間恰逢 ETH 的價格大幅下跌,使得該借款人的抵押品價值跌破了對 ETH 要求的抵押品比率 150%。
如果沒有補足或者出售抵押品,就會觸發清算程式,此外,借款人還要繳納清算罰金,這個時候清算人可以觸發 Compound 清算程式,可以以低於市場價格 3% -5% 的折扣獲得ETH抵押品,這部分差價便是 Liquidation Incentive 的由來。由此,借款人償還了 Compound 系統的貸款,避免 Compound 平臺出現債務和壞賬,維持了系統的償付能力,同時,清算人也獲得了單筆3%~5%的收益,類似於礦工費,清算人獲得了收益,平臺也行以正常執行。
在 Compound 的清算機制中,只要清算人透過監控合約發現借款人的抵押率過低,一旦觸發清算程式,清算人就會立刻啟動清算。
如何設計清算機器人?
清算機器人的總體設計原則為更快地發現 Liquidation incentive 高、且需要被清算的 underwater accounts,從而獲得更高的清算收益。
如何發現 underwater accounts
Account API 能夠實現與 Compound 協議互動各種賬戶資訊,可以使用此 API 按地址檢索特定使用者的資料,或獲取 unhealthy accounts 列表。Compound 協議 API 的輸入輸出格式是由 Protocol Buffers 指定的。與典型的 protobufs 不同的是,Compound 除了支援 protobufs 二進位制格式外,還支援JSON格式。若在輸入輸出中都使用 JSON 格式,需要在請求中標明“Content-Type: application / json”和“Accept: application / json”。
決定清算人清算的因素
· 必須有 unhealthy accounts 才能進行清算,這是清算的前提條件。
· 在清算時,應儘量選擇可在交易所輕鬆清算的抵押品作為抵押的賬戶進行清算。流動性高的抵押品更容易實現數字資產的貨幣化;
· 應儘量選擇抵押品和債務集中在少數幾類資產的 unhealthy accounts 進行清算。若 unhealthy accounts 的抵押品和債務分散在眾多資產上,每次呼叫 liquidateBorrow 交易時都需指定一個 debt contract 和一個 collateral contract,以至於需要多次呼叫才能完成清算,增加清算的成本;
· Ethereum 虛擬機器(EVM)是一個全域性狀態機,必須按順序處理 liquidateBorrow 事務。因此,清算人要想獲得更高收益,需要更快地發現並清算 unhealthy accounts;
· 假設某個 unhealthy accounts 全域性 close factor 為0.5,並擁有N個債務和M個抵押資產,要最大程度地增加清算量。這是一個揹包問題的具體應用,即將每個專案建模為<debt.weight,collateral.value>元組,專案總數為N * M。債務權重必須小於等於 close factor,且最大化抵押物價值。
尋找 unhealthy accounts 速度的決定性因素
· 網路延遲和硬體速度
· Gas 花費
· 使用高 Gas 花費來廣播一條清算交易優於廣播多條。若同時廣播多條清算交易,可能某一清算交易已經在以太坊的有效塊中,從而導致區塊鏈打包失敗;
· 應選擇擁有足夠抵押品的 unhealthy accounts 進行清算,如抵押品價值不足將導致交易失敗;
· 建立鏈下快取程式,該程式將 health 值小於1.2的賬戶標記為存在清算風險的賬戶,進行重點監控。一旦滿足清算要求第一時刻發起清算交易,減少與 Compound 協議互動次數。
執行清算的成本
· 執行清算是一項資金密集型操作,為清算100萬美元的貸款,清算人需要有100萬美元的資金;
· 清算交易是一個高度週期性交易行為。幣值市場的重大波動會造成清算交易集中式爆發,從而增加交易成本,並導致短期內大量被清算人走向破產,進而影響整個 Compound 專案的平穩執行;
· 為加快發現 unhealthy accounts,需要一個監控程式對可能被清算的賬戶進行監控,增加了准入的技術門檻;
· Gas 的費用可能會對最終收益產生巨大影響。所有交易的基礎成本為21000 Gas,若與合約進行互動會增加相應的 Gas。因此,清算程式需要預先計算預期收益。
清算與收取抵押物最大值計算方式
某些賬戶的抵押品價值可能少於最大清算金額,如果最大清算量或最大可收集抵押品價值小於交易所花費的 Gas 乘以 Gas 的單價,那麼清算交易永遠不可能獲利。計算最大清算數量和抵押品最大收取量公式如下:
需要注意的是 sum (token_borrow_balance_underlying_in_eth) != total_borrow_value_in_eth。透過呼叫 Account API 可以獲得更加準確的 Oracle Price,但會降低運算速度。為了最佳化速度,在可以接受的誤差範圍內犧牲準確性,使用近似價格計算。透過 PriceOracle 可以獲取 cToken 的 getUnderlyingPrice 和 liquidateCalculateSeizeTokens,透過 cUSDC 合約獲取 exchangeRateStored。透過匯率計算便可以快速、近似地計算出所需收取抵押物的數量。