Fantom 生態穩定幣收益優化器OneRing Finance 遭到閃電貸攻擊,黑客竊取逾145萬美元。前言
北京時間2022 年3 月22 日,知道創宇區塊鏈安全實驗室監測到Fantom 生態穩定幣收益優化器OneRing Finance 遭到閃電貸攻擊,黑客竊取逾145萬美元。
分析
攻擊事件如下圖所示,該次攻擊事件的問題點在於OneRing Finance 直接使用交易對中的reserves 來實時進行OShare 的價格計算,攻擊者通過Swap 操作提高reserves 的量,最終拉升OShare 的價格,獲取更多的資金。
基礎信息
攻擊合約: 0x6A6d593ED7458B8213fa71F1adc4A9E5fD0B5A58(已自我銷毀)
攻擊者地址: 0x12EfeD3512EA7b76F79BcdE4a387216C7bcE905e
攻擊tx: 0xca8dd33850e29cf138c8382e17a19e77d7331b57c7a8451648788bbb26a70145
漏洞合約: 0xc06826f52f29b34c5d8b2c61abf844cebcf78abf
流程
攻擊者的核心攻擊流程如下:
- 攻擊者從USDC/MIM 交易對中閃電貸借出8000W 的USDC到攻擊合約中。
2.攻擊者使用swap 把1 USDC 兌換成1.001 miMATIC。
3.使用depositSafe 存入79999997 的USDC。
4.合約mint 給攻擊者41965509 OShare,此時攻擊者還有2 USDC 和1.001 miMATIC。
5.攻擊者將2 USDC 和0.326 miMATIC 添加流動性,獲得7.82 x 10-7 spLP。
6.將41965509 的OShare withdraw 兌換成81534750 的USDC。
7.移除流動性獲取0.790 USDC 和0.862 miMATIC。
8.把1.501 miMATIC 兌換成1.433 USDC。
9.歸還8000W USDC 和80080 USDC 的手續費,最淨獲得1534750 – 80080 = 1454670 USDC
細節
攻擊者在攻擊之前通過Celer Network 的cBridge 跨鏈獲得了發起攻擊所需的gas。
通過流程第二步我們可以看出當時USDC 和miMATIC 的兌換率為約1:1.001,而通過流程第三步和第四步的swap 後可以在第五步中看到USDC 和miMATIC 的兌換率變成了約1:0.163,所以我們需要重點分析deposit 函數和withdraw 中計算價格的問題。
分析交易的Debugger,可以看到調用的是depositSafe 函數。
查看depositSafe 函數,其內部會調用_deposit 函數,繼續跟進,發現在_deposit 函數中又調用了_doHardWorkAll 函數,最後mint OShare 給攻擊者。
而在_doHardWorkAll 函數中使用了for 循環將部分存入的USDC 全部兌換成其他的代幣。
執行此次depositSafe 函數時getSharePrice 計算的OShare 價格為1062758591235248117。
接下來我們看下getSharePrice 函數的代碼,在getSharePrice 函數中調用了balanceWithInvested 函數,而在balanceWithInvested 函數中又調用了investedBalanceInUSD 函數。
繼續跟進,investedBalanceInUSD 函數是在合約MasterChefBaseStrategy 中,其合約地址為:https://ftmscan.com/address/0xdbc07e219ba0cb5fddcd0fa0c5cc1eddfb77e082#code
investedBalanceInUSD 函數返回的是getUSDBalanceFromUnderlyingBalance 函數,在getUSDBalanceFromUnderlyingBalance 函數中可以發現合約使用兩個代幣的數量進行計算,而前面攻擊者由於閃電貸存入了大量的USDC,從而使得最終的_amount 的值也變大了。再次回到getSharePrice 函數中就可以發現,_sharePrice 也會相應變大。
流程第六步使用了withdraw 函數。
在withdraw 函數中我們發現同樣調用了getSharePrice 計算OShare 價格,在該階段為1136563707735425848,OShare 的價格的確變大了,而最終的取款數量是通過內部調用_withdraw 函數計算得到的。
_withdraw 函數中最終取款的值為_realWithdraw,而_realWithdraw = _toWithdraw.mul(uint256(10)**uint256(ERC20(_underlying).decimals())).div(uint256(10)**uint256(decimals()));,所以我們再看到_toWithdraw,發現其值同樣是由balanceWithInvested 計算得到的,所以這就會導致最終將OShare 兌換成USDC 變多。
總結一下:
USDC↑->_amount↑->getUSDBalanceFromUnderlyingBalance(_underlyingBal)↑->investedBalanceInUSD()↑->balanceWithInvested()↑->_sharePrice↑
USDC↑->_amount↑->getUSDBalanceFromUnderlyingBalance(_underlyingBal)↑->investedBalanceInUSD()↑->balanceWithInvested()↑->_toWithdraw()↑->_realWithdraw()↑
後續處理
針對此次攻擊,OneRing Finance 團隊採取了四種補救措施,包括暫停保險庫,分析、調試、修復漏洞,通過財政庫還款,以及提供漏洞賞金。
- 保險庫狀態:保險庫已暫停,OneRing Finance 團隊正在努力重新設置。
- 分析、調試、修復:OneRing Finance 團隊已工作了很多小時,來修復允許黑客執行這次攻擊的問題,團隊已與許多合格開發者、協議合作,以查漏協議中所有的代碼,協議有漏洞是完全出乎意料的,甚至對一些高級開發人員來說也是如此,因為他們以前審查過OneRing Finance 的代碼。
- 通過協議財政部還款:該團隊正在製定一項計劃,為受影響的人提供具體的中長期還款計劃。
- 賞金:團隊將提供被盜資金的15% 以及100 萬RING 代幣,作為黑客返還資金的賞金。
總結
該次攻擊事件是由於項目使用實時儲備量來計算價格導致攻擊者通過閃電貸借出大量USDC 並存入使得儲備量增大拉升OShare 價格造成差值從而獲利。
展開全文打開碳鏈價值APP 查看更多精彩資訊