昨天晚上(2024.2.23)uni瞬間拉盤,價格從7美元,一瞬間漲到了11美元。
compound這個借貸協議是允許用戶抵押其他幣(如usdc)借uni,就在這個uni瞬間拉盤之后的一小段時間里,compound沒有及時更新uni的價格,導致在協議里可以用低uni價值的抵押品去借走uni。
這被極少數幾個人發現后抵押usdc借走了大量的uni,然后賣掉uni變成usdc,然后你會發現,它獲得的usdc數量竟然多于他抵押進compound的數量。
我來認真分析一下這次對借貸協議的攻擊,數據來源https://bad-debt.riskdao.org/。
攻擊獲利的地址有下面四個
0x6980a47bee930a4584b09ee79ebe46484fbdbdd0
0x5968ada261a84e19a6c85830e655647752585ed4
0x49bc3cec1fb7978746f742a4e485d0d601831cea
0x2f99fb66ea797e7fa2d07262402ab38bd5e53b12
現在在debank上去查看這四個地址的余額,你會發現在compound這個協議里,這四個地址都有一筆債務,但抵押品幾乎為零,如下面:
這個截圖顯示,這個地址0x2f99fb66ea797e7fa2d07262402ab38bd5e53b12在compound抵押了1.1503Dai和0.051715usdc,但借走了28702.7973uni 。
抵押品幾乎為0,但借走的uni價值高達 33萬U。這種情況下,這個地址肯定是不會去還這筆uni債務的。
其他三個地址都一樣,使用了幾乎為零的抵押品,借走了十幾萬U的uni幣。
這四個地址累計借走了 55,565.9001uni,目前按12U一個計算,總價值是 55565.9*12=666790.8 usdt,66萬U虧損。
為什么會發生可以使用幾乎為0抵押品,卻能借賣幾十萬U的uni幣?
整個攻擊邏輯是下面這樣的:
1.假設現在是T0時間點,uni在市場上的價格是7U/uni,compound對uni的喂價正常,也是7U/uni
2.然后在T1時間點,uni在市場上的價格突然爆漲,瞬間漲到了11U/uni。但compound里對uni的喂價出現錯誤,還是停留在7U/uni。
3.然后有人發現了compound對uni的喂價錯誤,立刻抵押了20萬usdc進去compound充當抵押品,并頂格借走了uni幣,按compound的喂價(7u/uni,和85%的借貸率),可以借走 20*0.85=17 萬U的uni, 170000/7=24285.7143 uni,即可以借走 2.4萬uni。
4.然后將這2.4萬uni在市場上(比如uniswap v3)賣掉換成usdc,因為市場上的價格是 11U/uni,因此可以賣到 2.4*11=26.4 wUsdc,比抵押品多了? 6.4萬Usdc,這就是利潤。
下面這筆交易 https://etherscan.io/tx/0xaee0f8d1235584a3212f233b655f87b89f22f1d4890782447c4ef742b37af58d 可以非常清晰地看到上面的邏輯
它抵押了 193020usdc,借出了19748uni,并且將uni賣成了ETH然后ETH又賣成了usdc,最終收到195461usdc,比抵押品多了195461-193020=2441 usdc。
5.等compound將正確的uni幣價格喂進協議后,那這些債務肯定要被清算,并且還清算不干凈,即使清算者拿走所有的抵押品,也還會留下大量的uni債務。這就是壞賬。
compound為什么會出現uni價格喂價錯誤?
目前compound已經發起了修正這個bug的投票。
因為compound對uni幣的價格設定是采用了雙重保險,一個是采用chainlink的oracle喂價,另外同時還采用了Uniswap TWAP(時間加權平均價格)。但這兩個喂價具體是怎么取舍我沒去查。但從現在的結果來看,這兩者必須同時正常,compound才能正常喂價。
在uni價格瞬間爆漲時,chainlink的喂價是正常的,但UniswapTWAP的價格出現了問題,compound的協議給出了錯誤的價格。