加密貨幣交易所 加密貨幣交易所
Ctrl+D 加密貨幣交易所
ads
首頁 > TRX > Info

Compound代碼更新事故_COM:UND

Author:

Time:1900/1/1 0:00:00

"有些事,發生在別人身上是故事,發生在自己身上就成了事故"

代碼的升級是一件痛苦且脆弱的事。尤其是在本就十分復雜的代碼大廈上,任何微小的改動,都可能因為某些邊界條件的疏忽而造成崩塌,Compound最近就遇到了這事

Compound是一個老牌的去中心化借貸平臺

Q1: 為什么要有借貸這回事兒?

在區塊鏈上,所有的資產都是代幣化的。我們看好一個項目,但是卻沒有這個項目發行的代幣。這時最簡單的方法就是去交易所用手里有的幣來換。但是,如果我們又不舍得自己手里的幣,該怎么辦呢。這時可以去借,抵押品便是我們擁有的幣。如果這個項目漲了,獲得收益的同時,還可以贖回曾經抵押的幣。

交易會發生所有權的轉移,而借貸不發生所有權的轉移,只是被暫時鎖在合約中

同時,由于借貸的引入,我們可以操控更大的資金敞口,實現杠桿交易...

Q2:Compound的運作流程?

和AMM類似,在區塊鏈上實現自動化的借貸,首先要做的便是吸引資金(流動性),而用戶所以能將錢存在一個平臺,必然是受到利益的驅使。AMM通過交易費來激勵用戶添加流動性,而借貸平臺的手段便是借款利息

由于存在借貸這一需求,總會有人愿意付出利息來借幣。而有了利息的激勵,也有人愿意將閑錢拿來提供流動性。此外,借貸平臺通過利率模型參數的動態調整,可以維持整個系統的供給平衡與風險

Q3: 如何與Compound交互?

用戶與Compound的交互接口主要是CToken/CEther合約(這些合約本身就是一種代幣), CToken 相當于 Compound這一平臺的"入場券"。通過向不同CToken合約質押其底層代幣(underlying token)便可以獲得相應的CToken

這一操作,表現在代碼層面就是?ctoken.mint(amount),比方說:我手里有1000個ETH,便可以調用cEth.mint(1000)?來向cEth池中 "注入流動性"

Crypto.com NFT、DeFi Swap 和 Tax 將于北京時間 3 月 16 日進行系統維護:金色財經報道,加密交易所 Crypto.com 發文稱,將于北京時間 3 月 16 日 08:00 開始對 Crypto.com NFT、DeFi Swap 和 Tax 進行系統維護,持續時間約為 2 小時。系統維護期間,Crypto.com App 內 Crypto.com NFT 將暫不可用,其他功能仍然可用、Crypto.com NFT 與 Crypto.com Tax 上的所有功能和服務將暫時不可用,用戶也無法登錄。[2023/3/10 12:54:32]

要注意的是,cToken和底層代幣并不是1:1的兌換關系,當蛋糕越做越大時,cToken所能換出的底層代幣也就越多。這和LP token的類似,利息便是以這種形式來發放的

那有了cToken以后,我們可以做什么呢?

最簡單的便是借錢,因為cToken代表用戶質押在Compound的資產,因此可以通過"過抵押"的方式來借出Compound擁有的代幣。Compound會先計算用戶擁有所有cToken的價值(可能來自于不同的池),根據抵押率來計算用戶的流動性(Liquidity)

表現在代碼層面就是?ctoken.borrow(amount),比方說:我通過?ceth.mint(1000)?質押了 1000 個 ETH,如果我想借 Dai 的話,需要調用?cDai.borrow(x)?這里的 x 最多價值750 ETH (抵押率75%)

這些都是以美元計算的,再根據Oracle來換算成不同的Token數量

而Comptroller這一合約是一個中間層,它所做的事情,便是交互前的一些計算與驗證工作,類似銀行的審計員。比方說:張三借了多少錢,欠了多少錢,這小子又來借1000個ETH還能不能借給他

表現在代碼層面就是:getHypotheticalAccountLiquidityInternal()、borrowAllowed()、mintAllowed()?...

0xd6開頭的地址將超過1820億個SHIB轉移到Gemini和Crypto.com:金色財經報道,分析公司 Lookonchain 引用的數據顯示,地址為(0xd6)開頭的錢包將超過 1820 億個 SHIB 轉移到Gemini 和 Crypto.com 。三個月前,同一個錢包將超過 2000 億個 SHIB 轉移到Crypto.com并以美元出售。當時市場價格下跌了7%。

Etherscan 數據顯示,地址為(0xd6)開頭的錢包持有超過 3.1 萬億個 SHIB,按當前價格計算價值近 4000 萬美元。這略高于 SHIB 代幣總供應量的 0.3%。\u2028此外,該錢包于 2020 年 8 月獲得了 SHIB 代幣,初始投資為 10 個以太坊,價值約 3,000 多美元。[2023/2/27 12:32:19]

Q4: COMP代幣與Compound的關系?

COMP代幣是Compound發行的平臺代幣,可以用于管理。因為Compound采用DAO的治理模式。對Compound所有的操作,都需要通過投票來決定,提案(proposals)通過后由一個特權合約來執行寫在提案中的操作。通過COMP可以獲得投票的權重

詳情見:https://compound.finance/governance

當然只能用來投票顯然還是缺少些吸引力的,COMP本質上就是Compound發行的股票,擁有更多的COMP,可以享受更優的利率,隨著Compound的發展,COMP帶來的價值也會越來越大,因此COMP值錢(目前 $300 左右)

同時,為了激勵用戶使用Compound,無論是向Compound提供流動性,還是從Compound借出資產,都會獲得一定的COMP獎勵,這些獎勵以區塊為單位計算(劃重點:這里與本次事件相關)

事故1代碼地址:0x75442Ac771a7243433e033F3F8EaB2631e22938f

事情的起因是這樣的:

2021年9月31日,Compound DAO出現這樣一條提案(Proposals 62: https://compound.finance/governance/proposals/62):

NEXO向Compound存入2000萬USDT,推動后者資金規模和鎖倉量創新高:借貸平臺NEXO冷錢包地址將超2000萬USDT存入去中心化借貸協議Compound。Compound資金規模目前已突破3.5億美元,鎖倉量超2.2億美元,均創歷史新高。截至發稿時,Compound上USDT存款利率為8.77%,借貸利率為15.04%。

此前報道,Compound的治理模塊中,有用戶提交USDT抵押價值的10%可借出其他資產投票,目前贊同票數為100%。原本Compound協議中抵押的USDT無法作為抵押物借出任何其他資產,如果該投票通過后,USDT將可以作為抵押物借出其價值最多10%的其他資產。(DeBank)[2020/6/18]

該提案提出更新 Comptroller 合約以修復一些 Bug

這里我們可以看出 Bug 和 CompSpeed 有關,CompSpeed 這個變量代表是每個區塊可以挖出的 COMP 數量

這里以 mint 為例簡單介紹Bug的原理:

ctoken 的 mint 函數的調用鏈為:mint → mintInternal → mintFresh

可以看到,在?mintFresh?中,會先調用 Comptroller 的?mintAllowed?函數,再更新用戶 ctoken 的余額

而 mintAllowed 中,會先調用 updateCompSupplyIndex,再調用 distributeSupplierComp

前者會更新借貸池的獎勵狀態,主要是 compSupplyState

聲音 | Compound總法律顧問:熊市不會長久 應好好利用:Compound總法律顧問Jake Chervinsky稱:“加密相關的推特內容(現在)比我印象中更安靜、更憤怒,但這項技術比以往任何時候都更令人興奮和充滿希望。我現在明白了人們在2017年說的‘我們錯過了熊市’的意思,在熊市,我們可以和平工作的寧靜日子,讓我們好好利用它們吧——它們不會長久的。”[2019/12/14]

這一結構體中,block字段記錄了更新時的區塊號,index字段記錄的是更新時的獎勵指數

**什么是獎勵指數(index)呢?**這是一個隨時間不斷累加的值,其公式為

表示的是一個借貸池,隨著時間的推移,向每個cToken分發的COMP數量。因此,其差值可以簡單理解為,這段時間內一個cToken可以獲得的COMP數量

接下來我們看另一個函數:distributeSupplierComp。這個函數的作用,就是將用戶可以獲得的COMP數記錄到compAccrued[supplier]?中:

每次有用戶來和 Compound 交互,都會觸發全局的獎勵指數 compSupplyState 更新

與此同時,在上面的函數中,我們可以看到,用戶會先從 compSupplierIndex 中取得上次的 compSupplyState 保存在臨時變量 supplierIndex 中,接下來更新 compSupplyState

這里要區分好 supplyIndex 和 supplierIndex,前者表示當前的獎勵指數,后者表示用戶上次交互時的獎勵指數

而兩個時間點全局獎勵指數的差 * 用戶擁有的 cToken 數量,就是這段時間獎勵給該用戶的 COMP 數量

動態 | 外媒:開發者提交XRP與WooCommerce支付網關插件:據dailyhodl報道,XRPL實驗室的創始人Wietse Wind 于3月7日發布推特稱,XRPL Labs推出針對WooCommerce項目開發人員的獎勵基金。一個半星期后,一位名叫Jesper Wallin的開發者提交了一個完整的支付網關插件,旨在讓WooCommerce用戶輕松接受XRP作為支付方式。[2019/3/17]

現在看起來都是一起正常,歲月靜好,直到...

有一天Compound調用了?setCompSpeed:

因為一個Market的CompSpeed是可以設置為0(表示暫停發放COMP獎勵),所以存在這樣一種情況:

我們先把一個市場的CompSpeed設置為0

過了一段時間后又想要重新開啟COMP獎勵,這時就會調用setCompSpeed設置compSpeed為一個非零值

這會發生什么呢?

很顯然,合約會走到?else if (compSpeed != 0)?這個分支。我們來看這個分支中有兩個if判斷(以第一個為例):if (compSupplyState[address(cToken)].index == 0 && compSupplyState[address(cToken)].block == 0)。其作用是:為一個未初始化的市場,初始化獎勵指數(index)和區塊號(block)

問題1:這里可以想想:未初始化的市場(index = 0 && block = 0)和被暫停的市場(index = 0)一樣嗎?

先別急,我們重新來看?updateCompSupplyIndex:

這里我們可以回答一下問題1:未初始化的市場和暫停的市場是不一樣的,暫停的市場雖然index = 0,但是block會一直更新!

因此,當我們為一個暫停的市場重新設置compSpeed時:index不會被初始化!

[注]Compound假設獎勵指數初始值為CompInitialIndex = 1e36

這會有什么影響呢?

我們再來看下獎勵分發函數?distributeSupplierComp:

看出來了嗎?用戶自己的獎勵指數(supplierIndex)會被初始化為compInitialIndex (1e36),而市場的獎勵指數(supplyIndex)由于上面的問題為0,這就導致:Double memory deltaIndex = sub_(supplyIndex=0, supplierIndex=1e36)?出現下溢!

事故2代碼地址:0x374abb8ce19a73f2c4efad642bda76c797f19233

Compound方面對事故1的修復如下:

Compound很顯然意識到了問題出在setCompSpeed函數只考慮了"未初始化市場",而沒有考慮"暫停的市場"

因此,新代碼中,增加了函數:_initializeMarket?這個函數會在添加新市場時調用。也就是說,只要添加新市場,就會初始化其獎勵指數為compInitialIndex

但是既然市場獎勵指數初始化為了compInitialIndex,那用戶的獎勵指數呢?這是我們來看新的distributeSupplierComp?函數:

因為很多市場的 CompSpeed 為0,所以其獎勵指數會停留在 compInitialIndex(1e36) 這個值,此時如果調用這個函數會發生什么?

很顯然上圖中的if被繞過了,這意味著沒有初始化用戶的獎勵指數(supplierIndex),而市場的獎勵指數(supplyIndex)是compInitialIndex

所以deltaIndex本應是(compInitialIndex - compInitialIndex = 0)就變成了 (compInitialIndex - 0 = 1e36)

哦豁,出大問題。可是,獎勵不僅僅依賴于這個deltaIndex,還需要用戶有cToken(supplierTokens)

是否存在這一情況呢?顯然是存在的,如果用戶在合約更新之前就做了mint操作,其supplierIndex=0,但是手里是存在cToken的。當合約更新后,用戶再次調用該函數,就可以獲得 1e36 * ctoken.balanceOf(user) 數量的COMP獎勵

通過compStateIndex = compInitialIndex,可以很容易的得到受到影響的市場有:

我們以一位涉事者為例:0xa7b95d2a2d10028cc4450e453151181cbcac74fc

我們看到在這筆交易中:0x6416ed016c39ffa23694a70d8a386c613f005be18aa0048ded8094f6165e7308

其Claim大量的COMP代幣,通過調試我們發現,在調用distribute時:

由于事故2,獲得的deltaIndex = 1e36,而恰恰該用戶之前有cToken

從而可以薅到大量的COMP:

最終,事情的解決方式也很簡單

在接下來一條提案中(Proposal 63),暫停COMP獎勵,但是最終被取消掉了

最新的一條提案,更新了Comptroller合約,該提案目前仍在排隊中:

最新的合約里,distributeSupplierComp函數中初始化用戶獎勵指數的判斷條件修改如下:

Compound作為借貸平臺的老大哥,本次的事件有些唏噓

雖然Compound軟硬兼施,一方面承諾拿出10%的白帽獎勵給獲得"意外之財"的用戶,一方面又尋求法律的手段。但是,事故終究已經發生

當我們不斷探索區塊鏈,不斷追求更高的APY,追求項目快速落地。是否還有人記得,區塊鏈最基本的一條原則就是:覆水難收!

啟示如下:

代碼部署上鏈前一定要做好充足的審計與測試工作

使用代理模式時,更新邏輯合約要保證一致性,注意是否會對原來的Storage產生影響

DAO模式雖然減少了中心化的風險,但是應對緊急情況時的反應遲緩問題

即使是大公司依然會有犯錯誤的可能,借鑒其他項目代碼時要注意檢查

參考

Comptroller: compSpeed bug:?https://www.comp.xyz/t/comptroller-compspeed-bug/2111

github issue:?https://github.com/compound-finance/compound-protocol/pull/144/commits/f6d717bb78bef0c9851ad672f7b9aa1d90b0f00a

Tags:COMOMPCOMPUNDCOMFI幣FOMP價格Compounderbefund

TRX
四周年 | 徐義吉:從技術發展看行業趨勢_ANC:NFT Gallery

10月23日,在金色財經成立四周年之際,特別策劃——“同行者”線上區塊鏈高峰論壇開啟,論壇為期6天,其間大咖云集,全方位解讀行業。在論壇上,星云鏈創始人徐義吉主題演講《從技術發展看行業趨勢》.

1900/1/1 0:00:00
一文了解CoinMarketCap推出的DEX聚合服務_SWAP:TOKE

6月30日消息,加密資產導航網站CoinMarketCap宣布推出了自己的代幣交換服務,用戶可連接支持的加密錢包并直接在CoinMarketCap 上交易相關token.

1900/1/1 0:00:00
DeFi應用的范式變革:OKEx上線波卡鏈首個DeFi項目OM_DEFI:okex

OKEx官方消息顯示,8月25日18:00(HKT)OKEx正式上線知名DeFi項目MANTRA DAO(OM)。目前OKEx已開啟OM充值,并開放OM/USDT、OM/ETH的市場交易.

1900/1/1 0:00:00
印度政府:加密貨幣監管法案已進入最后階段_加密貨幣:BPA

作者:Kevin Helms  翻譯:Penny印度政府告訴該國最高法院,負責起草加密監管的委員會正處于審議的最后階段。在政府制定加密監管后,法院計劃聽取中央銀行關于銀行禁令的請愿.

1900/1/1 0:00:00
以太坊合并馬上來了 普通人能做點什么?_ETH:ETHPLO價格

來源:老雅痞 信息來源自BanklessDao,略有修改 編譯:RR 來了來了它來了。隨著Goerli測試網合并成功完成,TTD被設定為 58750000000000000000000,合并時間.

1900/1/1 0:00:00
SushiSwap CTO回應前員工指責:多數人因表現不佳或無法與團隊合作而被要求離開_SUSHI:USH

此前原 SushiSwap 亞太地區負責人 AG 離職后,公開譴責 SushiSwap 管理層毫無作為,已經不是一個由社區領導的項目,而是變為由少數領導者掌控的「公司」.

1900/1/1 0:00:00
ads