昨天晚上(2024.2.23)uni瞬間拉盤(pán),價(jià)格從7美元,一瞬間漲到了11美元。
compound這個(gè)借貸協(xié)議是允許用戶(hù)抵押其他幣(如usdc)借uni,就在這個(gè)uni瞬間拉盤(pán)之后的一小段時(shí)間里,compound沒(méi)有及時(shí)更新uni的價(jià)格,導(dǎo)致在協(xié)議里可以用低uni價(jià)值的抵押品去借走uni。
這被極少數(shù)幾個(gè)人發(fā)現(xiàn)后抵押usdc借走了大量的uni,然后賣(mài)掉uni變成usdc,然后你會(huì)發(fā)現(xiàn),它獲得的usdc數(shù)量竟然多于他抵押進(jìn)compound的數(shù)量。
我來(lái)認(rèn)真分析一下這次對(duì)借貸協(xié)議的攻擊,數(shù)據(jù)來(lái)源https://bad-debt.riskdao.org/。
攻擊獲利的地址有下面四個(gè)
0x6980a47bee930a4584b09ee79ebe46484fbdbdd0
0x5968ada261a84e19a6c85830e655647752585ed4
0x49bc3cec1fb7978746f742a4e485d0d601831cea
0x2f99fb66ea797e7fa2d07262402ab38bd5e53b12
現(xiàn)在在debank上去查看這四個(gè)地址的余額,你會(huì)發(fā)現(xiàn)在compound這個(gè)協(xié)議里,這四個(gè)地址都有一筆債務(wù),但抵押品幾乎為零,如下面:

這個(gè)截圖顯示,這個(gè)地址0x2f99fb66ea797e7fa2d07262402ab38bd5e53b12在compound抵押了1.1503Dai和0.051715usdc,但借走了28702.7973uni 。
抵押品幾乎為0,但借走的uni價(jià)值高達(dá) 33萬(wàn)U。這種情況下,這個(gè)地址肯定是不會(huì)去還這筆uni債務(wù)的。
其他三個(gè)地址都一樣,使用了幾乎為零的抵押品,借走了十幾萬(wàn)U的uni幣。
這四個(gè)地址累計(jì)借走了 55,565.9001uni,目前按12U一個(gè)計(jì)算,總價(jià)值是 55565.9*12=666790.8 usdt,66萬(wàn)U虧損。
為什么會(huì)發(fā)生可以使用幾乎為0抵押品,卻能借賣(mài)幾十萬(wàn)U的uni幣?
整個(gè)攻擊邏輯是下面這樣的:
1.假設(shè)現(xiàn)在是T0時(shí)間點(diǎn),uni在市場(chǎng)上的價(jià)格是7U/uni,compound對(duì)uni的喂價(jià)正常,也是7U/uni
2.然后在T1時(shí)間點(diǎn),uni在市場(chǎng)上的價(jià)格突然爆漲,瞬間漲到了11U/uni。但compound里對(duì)uni的喂價(jià)出現(xiàn)錯(cuò)誤,還是停留在7U/uni。
3.然后有人發(fā)現(xiàn)了compound對(duì)uni的喂價(jià)錯(cuò)誤,立刻抵押了20萬(wàn)usdc進(jìn)去compound充當(dāng)?shù)盅浩罚㈨敻窠枳吡藆ni幣,按compound的喂價(jià)(7u/uni,和85%的借貸率),可以借走 20*0.85=17 萬(wàn)U的uni, 170000/7=24285.7143 uni,即可以借走 2.4萬(wàn)uni。
4.然后將這2.4萬(wàn)uni在市場(chǎng)上(比如uniswap v3)賣(mài)掉換成usdc,因?yàn)槭袌?chǎng)上的價(jià)格是 11U/uni,因此可以賣(mài)到 2.4*11=26.4 wUsdc,比抵押品多了? 6.4萬(wàn)Usdc,這就是利潤(rùn)。
下面這筆交易 https://etherscan.io/tx/0xaee0f8d1235584a3212f233b655f87b89f22f1d4890782447c4ef742b37af58d 可以非常清晰地看到上面的邏輯

它抵押了 193020usdc,借出了19748uni,并且將uni賣(mài)成了ETH然后ETH又賣(mài)成了usdc,最終收到195461usdc,比抵押品多了195461-193020=2441 usdc。
5.等compound將正確的uni幣價(jià)格喂進(jìn)協(xié)議后,那這些債務(wù)肯定要被清算,并且還清算不干凈,即使清算者拿走所有的抵押品,也還會(huì)留下大量的uni債務(wù)。這就是壞賬。
compound為什么會(huì)出現(xiàn)uni價(jià)格喂價(jià)錯(cuò)誤?
目前compound已經(jīng)發(fā)起了修正這個(gè)bug的投票。
因?yàn)閏ompound對(duì)uni幣的價(jià)格設(shè)定是采用了雙重保險(xiǎn),一個(gè)是采用chainlink的oracle喂價(jià),另外同時(shí)還采用了Uniswap TWAP(時(shí)間加權(quán)平均價(jià)格)。但這兩個(gè)喂價(jià)具體是怎么取舍我沒(méi)去查。但從現(xiàn)在的結(jié)果來(lái)看,這兩者必須同時(shí)正常,compound才能正常喂價(jià)。
在uni價(jià)格瞬間爆漲時(shí),chainlink的喂價(jià)是正常的,但UniswapTWAP的價(jià)格出現(xiàn)了問(wèn)題,compound的協(xié)議給出了錯(cuò)誤的價(jià)格。