作者:Polaris,ScaleBit 研究團隊,來源:ScaleBit
本文深入研究了 DeFi 槓杆的多樣性和應用場景,詳細分析了代碼層面的漏洞,同時提出了槓杆協議關鍵的安全要點。
最近 dYdX V4 的推出引發了大家對永續合約交易所的大量關注和參與。dYdX 成功應用了槓杆交易的案例,而我們不僅應該期待 dYdX V4 的巨大潛力,更要注重槓杆協議的安全性。接下來,我們將會結合具體的代碼分析和示例帶領大家熟悉不同的槓杆策略和安全考量。
在金融領域,槓杆是一種策略,依賴於借入資金以增加投資的潛在回報。簡而言之,投資者或交易員借入資金,以放大對特定類型的資產、項目或工具的敞口,遠遠超過僅依賴自己的資本所能達到的程度。通常情況下,通過使用槓杆,投資者能夠在市場上放大其購买力。
使用槓杆是加密資產交易中最重要且常見的特性之一。在去中心化交易所成立後不久,盡管加密市場已經表現出高度波動性,但使用槓杆進行交易變得越來越流行。
與傳統金融一樣,交易員使用槓杆要么僅僅是爲了借入資金以增加其購买力,要么是爲了利用各種金融衍生品,如期貨和期權。
槓杆比例也從 3 倍、5 倍增加到超過 100 倍。更高的槓杆意味着更高的風險,但正如大多數中心化交易所所見,隨着槓杆交易量的增長,這是尋求更高回報的激進交易員愿意承擔的風險。
就 DeFi 而言,槓杆產品主要分爲四種類型,其產生槓杆的機制各不相同:槓杆借貸,保證金交易槓杆,永續合約槓杆,槓杆代幣。
DeFi 借貸和借出是最早也是最大的 DeFi 應用之一,市場上已經有像 MakerDao、Compound、AAVE、Venus 等巨頭在運營。通過借貸加密資產獲取槓杆的邏輯很簡單。
例如,如果你持有 1 萬美元的以太幣(ETH)並看漲,你可以將你的 ETH 作爲抵押存入 Compound,並借出 5,000 美元的 USDC,然後用這 5,000 美元的 USDC 交易換取另外 5,000 美元的 ETH。這樣你將在 ETH 上獲得 1.5 倍槓杆,相比於你最初的 1 萬美元資本,你將獲得 1.5 萬美元的 ETH 敞口。
同樣,如果你看跌,你可以選擇存入穩定幣並借出 ETH。如果 ETH 價格下跌,你可以以更低的價格在市場上購买 ETH 並償還債務。
需要注意的是,由於你將從一個去中心化協議中借款,如果抵押物的價值下降或你所借資產的價值超過一定閾值,你可能會被清算。
通過 DeFi 借貸,你可以用這些數字資產做你想做的事。DeFi 保證金交易更注重增加頭寸規模(增加購买力),被認爲是真正的“槓杆頭寸”。然而,有一個重要的區別——在保證金頭寸仍然开放時,交易者的資產充當了借款資金的抵押品。
dYdX 是知名的去中心化保證金交易平台,允許最高槓杆爲 5 倍。在 dYdX 的保證金交易中,交易者使用自己的資金作爲擔保,將其原始本金放大數倍,並使用這些放大的資金進行更大規模的投資。
交易者需要支付利息費用以及與交易相關的費用。該頭寸不是虛擬構造的,它涉及到實際的借款和購买/賣出。
如果市場朝不利的方向發展,交易者的資產可能無法完全償還借款。爲防止這種情況發生,協議將在達到一定的清算比例之前清算你的頭寸。
對於保證金交易中槓杆如何變化——
假設你在保證金交易中看漲 ETH 3 倍,但又不愿意時常調整敞口。
你持有 100 美元的 USDC,借入另外 200 美元的 USDC,用於交易 300 美元的 ETH 以建立所需的 ETH 多頭頭寸。槓杆水平爲 300 美元 / 100 美元 = 3 倍。
如果 ETH 的價格上漲 20%,你的利潤將爲 300(1+20%)-300 = 60 美元。你相對於被清算的風險更低,而實際的槓杆水平降低爲 360/(360-200)= 2.25 倍。換句話說,你在 ETH 價格上漲時會自動減槓杆。
如果 ETH 的價格下跌 20%,你的虧損將爲 300(1-20%)-300 = -60美元。在涉及清算的方面,你處於更危險的位置,而實際的槓杆水平會自動增加爲 240/(240-200)= 6 倍。換句話說,你在 ETH 價格下跌時會重新平衡槓杆,這表明你比之前處於更高的風險位置。
因此,盡管你可能認爲通過進行固定的 3 倍保證金交易,可以保持不變的槓杆,但實時的槓杆是不斷變化的。請查看下圖,了解根據價格變動槓杆將會如何變化。
永續合約類似於傳統的期貨合約,但沒有到期日。永續合約模仿基於保證金的現貨市場,因此交易接近基礎參考指數價格。
有許多 DeFi 項目爲交易者提供永續合約,如 dYdX、MCDEX、Perpetual Protocol、Injective 等。許多交易者可能很難區分在保證金交易和永續合約上的區別 —— 實際上,它們都涉及用戶的槓杆。
然而,在槓杆機制、費用和槓杆水平上存在一些差異。
永續合約是一種交易合成資產的衍生產品,具有按保證金進行交易的特性。對基礎資產價格的跟蹤以一種合成的方式進行,無需交易實際的基礎資產。但是,保證金交易涉及實際借款和實際加密資產的交易。
隨着永續合約的出現,出現了資金費率的概念,其目的是保持永續合約的交易價格與基礎參考價格保持一致。如果合約價格高於現貨價格,則多頭將支付空頭。換句話說,交易者需要不斷爲借款支付費用。
永續合約中的槓杆通常比保證金交易中的槓杆更高,可以高達 100 倍。清算和實際槓杆機制與保證金交易相同。
槓杆代幣是一種衍生品,爲持有者提供對加密貨幣市場的槓杆敞口,而無需擔心積極管理槓杆頭寸。雖然它們爲持有者提供了槓杆敞口,但不要求他們處理保證金、清算、抵押品或資金費率。
槓杆代幣與保證金交易/永續合約的最大區別在於,槓杆代幣將定期或在達到一定閾值時重新平衡,以保持特定的槓杆。
這顯然與保證金交易和永續合約不同 - 這些產品的實際槓杆根據價格波動不斷變化,即使交易者最初可能指定了一個槓杆水平。
讓我們看一下上面的 3 倍 ETH 示例中重新平衡的工作方式:
你持有 100 美元的 USDC 並購买一個 ETHBULL(3 倍)槓杆代幣。協議將自動借入 200 美元的 USDC 並交易 200 美元的 ETH。
假設 ETH 的價格上漲了 20%,而 ETHBULL(3 倍)代幣價格在重新平衡之前上升到 300*(1+20%)-200 = 160 美元。現在,你的實際槓杆變爲 2.25(360/160),低於目標槓杆。
在重新平衡過程的一部分,協議將從穩定幣池中借入更多的美元,並購买額外的 ETH 代幣,以將槓杆調回到 3 倍。在我們的示例中,協議將再借入 120 美元並將其兌換成 ETH。因此,總槓杆再次變爲(360+120)/160 = 3 倍。
假設 ETH 的價格下跌了 20%,而 ETHBULL(3 倍)代幣價格在重新平衡之前下降到 300*(1-20%)-200 = 40 美元。現在,你的實際槓杆將變爲 6(240/40),高於目標槓杆。
在這種情況下,協議將出售 ETH 代幣並償還未償還的債務以降低槓杆。在這個例子中,協議將出售 120 美元的 ETH 以支付給池。債務將變爲 80 美元,總槓杆再次爲(240-120)/40 = 3 倍。
換句話說,槓杆代幣將在盈利中自動重新槓杆,而在虧損中去槓杆,以恢復其目標槓杆水平。如果這個機制運作良好,即使在不利的市場趨勢中,槓杆代幣持有者也不會被清算,因爲去槓杆機制將不斷降低用戶的有效槓杆水平。
因此,在槓杆代幣模型中的借貸池將免於清算風險,比保證金交易中的借貸池更安全。
我們已經了解了一些槓杆的常見 DeFi 協議類型,接下來我們結合具體的 DeFi 協議詳解槓杆的應用。
GMX
GMX 是一個去中心化的現貨和永續交易所,爲交易者提供高達 50 倍槓杆的資產交易能力。該協議目前在 Arbitrum 和 Avalanche 上運行。在 GMX 上,交易者完全了解對手方的情況,這與在 CEX 上交易完全不同。GMX 與其他永續合約協議如 dYdX 不同,它完全在鏈上運作,並使用 AMM 功能來實現槓杆交易。
GMX 與其他服務的不同之處在於它是一個提供槓杆交易服務的去中心化交易所。在這方面,它將類似於 Uniswap 等其他 DeFi 交易所的體驗與 Binance 等提供的槓杆交易服務相結合。
GMX 有一個流動性池 GLP,這是一個爲保證金交易提供流動性的多資產池:用戶可以通過鑄造和銷毀 GLP 代幣來做多/ 做空和執行交易。該池從交易和槓杆交易中賺取 LP 費用,這些費用會分配給 GMX 和 GLP 持有人。
爲了進行槓杆交易,交易者將抵押品存入協議中。交易者可以選擇最高 50 倍的槓杆,槓杆越高,清算價格越高,隨着借貸費用的增加,清算價格將逐漸增加。
例如,當做多 ETH 時,交易者正在從 GLP 池中“租出”ETH 的上行空間;當做空 ETH 時,交易者正在從 GLP 池中“租出”穩定幣相對於 ETH 的上漲空間。但 GLP 池中的資產實際上並沒有被租出。
平倉時,如果交易者押對了,利潤將從 GLP 池中以代幣做多的形式支付;否則,損失將從抵押品中扣除並支付到池中。GLP 從交易者的損失中獲利,並從交易者的利潤中獲利。
在此過程中,交易者支付交易費、开倉/平倉費和借入費,以換取對美元做多/做空指定代幣(BTC、ETH、AVAX、UNI 和 LINK)的上行空間。
Merkle Trade 是一個去中心化的交易平台,提供加密貨幣、外匯和大宗商品交易,槓杆率高達 1,000 倍,並提供以用戶爲中心的高級交易功能。Merkle Trade 由 Aptos 區塊鏈提供支持,具有一流的性能和可擴展性。相比 Gains Network 在提供同樣高槓杆的情況下,具有更低的交易延時和手續費。
與大多數交易所不同,Merkle Trade 上沒有訂單簿。相反,Merkle LP 充當每筆交易的交易對手,當交易者虧損時,它收取抵押品,並在具有正收益的封閉交易上支付利潤。
- 交易加密貨幣、外匯和大宗商品,槓杆高達 1,000 倍
Merkle Trade 旨在從一开始提供廣泛的交易對,包括加密貨幣、外匯和大宗商品,並提供市場上一些最高的槓杆;在加密貨幣上最高可達 150 倍,在外匯上最高可達 1,000 倍。
- 公平價格的訂單執行,毫秒級延遲,最小滑點
借助迄今爲止最低延遲的 Aptos 產生區塊鏈,能夠提供最快的鏈上交易體驗。對於交易者來說,這意味着更迅速的交易體驗,由於執行延遲而導致的價格滑點更小。
- 去中心化、非托管的交易,無交易對手風險
交易者與流動性池(Merkle LP)進行交易,該流動性池充當協議上每筆交易的交易對手。所有交易和結算都由智能合約執行,任何時候都沒有用戶資金的托管。
- 最低手續費
Merkle Trade 宣稱在市場上擁有迄今爲止最低的手續費之一。在推出時,加密貨幣交易對的手續費低至 0.05%,外匯交易對的手續費低至 0.0075%。
dYdX是一個去中心化交易所(DEX),賦予用戶在完全掌控資產的同時高效交易永續合約的能力。自 2021 年上线以來,dYdX V3 採用了獨特的非托管第二層擴展解決方案來實現其交易所,但其訂單簿和撮合引擎仍然由中心化管理。
而現在,通過 dYdX V4,該協議正在發展成爲自己的鏈,並全面重構整個協議以實現完全去中心化,同時提高吞吐量。dYdX 同時包含借貸、槓杆交易與永續合約三種功能。槓杆交易自帶借貸功能,用戶存入的資金自動組成資金池,交易時若資金不足,則自動借入並支付利息。
我們介紹了槓杆在 DeFi 中常見類型和應用,同樣在槓杆的設計中依然存在很多的安全問題值得我們注意,我們將結合具體的審計案例分析 DeFi 槓杆的安全問題和審計點。
在大多數槓杆的交易所應用中,都存在限價單和市價單,對限價單和市價單的嚴格區分和校驗是很有必要的。接下來,將以我們在 Merkle Trade 審計中發現的問題來做詳細分析。
let now = timestamp::now_seconds(); if (now - order.created_timestamp > 30) { cancel_order_internal<PairType, CollateralType>( _order_id, order, T_CANCEL_ORDER_EXPIRED ); return };
該部分代碼是執行訂單函數中的校驗,在該函數中,它會檢查訂單創建後是否已超過 30 秒。如果滿足條件,則調用 cancel_order_internal() 取消訂單。但是,如果訂單是限價訂單,則意味着訂單有一個由交易者設定的具體價格,他們愿意在該價格买入或賣出資產。在執行限價單的時候不應有該判斷,這可能導致大多數限價單無法得到執行。因此嚴格區分限價單和市價單的交易邏輯是很重要的。
計算錯誤一直是 DeFi 中很常見的問題,在槓杆中也尤爲常見,我們將以 Unstoppable[6] 協議在第三方審計中發現的問題,來深入研究槓杆的計算問題。
讓我們來看 Unstoppable 中計算槓杆的代碼:
def _calculate_leverage(
_position_value: uint256, _debt_value: uint256, _margin_value: uint256
) -> uint256:
if _position_value <= _debt_value:
# bad debt
return max_value(uint256)
return (
PRECISION
* (_debt_value + _margin_value)
/ (_position_value - _debt_value)
/ PRECISION
)
_calculate_leverage 函數通過使用 _debt_value + _margin_value 作爲分子而不是 _position_value,導致錯誤地計算了槓杆。該函數的三個輸入參數 _position_value、_debt_value 和 _margin_value 都是由 Chainlink 鏈上預言機提供的價格信息決定的。其中,_debt_value 表示將倉位的負債份額轉換爲美元債務金額的價值。_margin_value 表示倉位初始保證金金額的當前價值(以美元計)。_position_value 表示倉位初始倉位金額的當前價值(以美元計)。
以上計算的問題在於 _debt_value + _margin_value 不代表倉位的價值。槓杆是當前倉位價值與當前保證金價值之間的比率。_position_value - _debt_value 是正確的,它表示當前的保證金價值,但 _debt_value + _margin_value 並不代表倉位的當前價值,因爲不能保證負債代幣和倉位代幣有相關的價格波動。
舉例說明:負債代幣爲 ETH,倉位代幣爲 BTC。
Alice 使用 1 個 ETH 作爲保證金,借入 14 個 ETH(每個 ETH 2,000 美元)並獲得 1 個 BTC(每個 BTC 30,000 美元)的倉位代幣。槓杆爲 14。
第二天,ETH 的價格仍爲 2,000 美元/ETH,但 BTC 的價格從 30,000 美元/BTC 下跌到 29,000 美元/BTC。此時,槓杆應爲(_position_value == 29,000)/(_position_value == 29,000 - _debt_value == 28,000)= 29,而不是合約中計算的值:(_debt_value == 28,000 + _margin_value == 2,000)/(_position_value == 29,000 - _debt_value == 28,000)= 30。
因此,爲了修復這個問題,應該使用上述提到的正確的公式來計算智能合約中的槓杆。槓杆計算錯誤可能導致不公平的清算或者在價格波動的情況下出現過度槓杆的倉位。
在智能合約中,確保正確的槓杆計算對於維護系統的穩健性和用戶的利益至關重要。正確的槓杆計算應該基於倉位的當前價值和當前保證金價值之間的比率。如果使用了錯誤的計算公式,可能會導致系統對於價格變動的反應不當,可能會清算不應該被清算的倉位,或者允許過度槓杆的倉位繼續存在,從而增加系統和用戶的風險。
邏輯錯誤在智能合約的審計中尤其需要重視,特別是在 DeFi 槓杆交易等復雜邏輯中。
讓我們以 Tigris(Tigris 是一個基於 Arbitrum 和 Polygon 的去中心化合成槓杆交易平台)在第三方審計中發現的問題,來討論 DeFi 槓杆中需要注意的邏輯問題。
讓我們來看 Tigris 中的限價平倉函數邏輯:
function limitClose(
uint _id,
bool _tp,
PriceData calldata _priceData,
bytes calldata _signature
)
external
{
_checkDelay(_id, false);
(uint _limitPrice, address _tigAsset) = tradingExtension._limitClose(_id, _tp, _priceData, _signature);
_closePosition(_id, DIVISION_CONSTANT, _limitPrice, address(0), _tigAsset, true);
}
function _limitClose(
uint _id,
bool _tp,
PriceData calldata _priceData,
bytes calldata _signature
) external view returns(uint _limitPrice, address _tigAsset) {
_checkGas();
IPosition.Trade memory _trade = position.trades(_id);
_tigAsset = _trade.tigAsset;
getVerifiedPrice(_trade.asset, _priceData, _signature, 0);
uint256 _price = _priceData.price;
if (_trade.orderType != 0) revert("4"); //IsLimit
if (_tp) {
if (_trade.tpPrice == 0) revert("7"); //LimitNotSet
if (_trade.direction) {
if (_trade.tpPrice > _price) revert("6"); //LimitNotMet
} else {
if (_trade.tpPrice < _price) revert("6"); //LimitNotMet
}
_limitPrice = _trade.tpPrice;
} else {
if (_trade.slPrice == 0) revert("7"); //LimitNotSet
if (_trade.direction) {
if (_trade.slPrice < _price) revert("6"); //LimitNotMet
} else {
if (_trade.slPrice > _price) revert("6"); //LimitNotMet
}
//@audit stop loss is closed at user specified price NOT market price
_limitPrice = _trade.slPrice;
}
}
在使用止損平倉時,用戶的平倉價格是其設定的止損價,而不是資產的當前價格。在方向性市場和高槓杆的情況下,用戶可能會濫用這一點,實現幾乎無風險的交易。用戶可以开設一個做多倉位,並設置一個止損價格,該價格比當前價格低 $0.01。
如果在下一次更新中價格立即下跌,他們將以他們的入場價格平倉,只需支付开倉和平倉手續費。如果價格上漲,他們則有可能獲得大額收益。以致於用戶可以濫用止損的價格設定方式,以开設高槓杆、上行潛力大、下行風險小的交易。
價格波動對 DeFi 槓杆的影響是很重要的,時刻考慮價格波動才能保證槓杆協議的安全。讓我們以 DeFiner[8] 協議在第三方審計中發現的問題作爲例子深入分析:
DeFiner 協議在處理提款之前進行兩次檢查。
首先,該方法檢查用戶請求提取的金額是否超過了該資產的余額:
function withdraw(address _accountAddr, address _token, uint256 _amount) external onlyAuthorized returns(uint256) {
// Check if withdraw amount is less than user's balance
require(_amount <= getDepositBalanceCurrent(_token, _accountAddr), "Insufficient balance.");
uint256 borrowLTV = globalConfig.tokenInfoRegistry().getBorrowLTV(_token);
其次,該方法會檢查提款是否會使用戶的槓杆率過高。提取的金額會從用戶當前價格的 "borrow power" 中減去。如果用戶的借貸總值超過了新的 borrow power,則方法失敗,因爲用戶不再有足夠的抵押品來支持其借貸頭寸。不過,只有在用戶尚未過度槓杆化的情況下,才會檢查此 require:
if(getBorrowETH(_accountAddr) <= getBorrowPower(_accountAddr)) require( getBorrowETH(_accountAddr) <= getBorrowPower(_accountAddr).sub( _amount.mul(globalConfig.tokenInfoRegistry().priceFromAddress(_token)) .mul(borrowLTV).div(Utils.getDivisor(address(globalConfig), _token)).div(100) ), "Insufficient collateral when withdraw.");
如果用戶借入的資金已超過其 "borrow power" 所允許的數額,則無論如何都可以提款。這種情況可能出現在多種情況下,最常見的是價格波動。該協議並沒有考慮價格波動對協議的影響,所以造成了這個問題。
除了上面提到的沒有區分限價單和市價單、計算錯誤、邏輯錯誤、價格波動的影響,還有許多與槓杆協議相關的安全要點需要我們注意。這包括但不限於閃電貸攻擊、價格操縱、預言機安全、權限控制、槓杆檢查不夠嚴格或缺少檢查等問題。在設計和實施槓杆協議時,必須細致審慎地考慮這些因素,以確保協議的健壯性和用戶資產的安全。預防措施、實時監控和緊急響應計劃也是關鍵,以降低潛在風險並保障用戶利益。
槓杆交易的引入在 DeFi 協議中確實爲市場提供了更大的可操作性,同時也帶來了更復雜的交易機制。盡管槓杆交易爲用戶提供了更多的投資機會,但其潛在風險和對協議安全性的挑战也變得更加顯著。
隨着槓杆的增加,協議的操作變得更爲靈活,但也因此變得更加脆弱,更容易受到各種安全威脅的影響。這包括潛在的沒有嚴格區分限價單和市價單、計算錯誤、邏輯錯誤,以及對價格波動等因素的極端敏感性。在這種情況下,我們必須更加關注協議的安全性,以確保用戶的資產得到有效保護。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
標題:dYdX V4熱潮背後 深度解析DeFi槓杆分類、應用及安全實踐
地址:https://www.torrentbusiness.com/article/79060.html