首發 | PancakeBunny閃崩事件最全技術細節剖析
5月20日,CertiK安全技術團隊發現幣安智能鏈DeFi收益聚合器PancakeBunny(BUNNY)遭到閃電貸攻擊,發生代幣閃崩事件。
此次事件共損失114,631枚BNB和697,245枚BUNNY,按當時價格計算約合約4200萬美元。
經CertiK安全團隊調查得出,由於該協議是使用PancakeSwap AMM來進行資產價格計算的,因此黑客惡意利用了閃電貸來操縱AMM池的價格,並利用Bunny在鑄造代幣的時候計算上的問題成功完成攻擊。
攻擊是如何發生的?
本次攻擊,攻擊者總共進行了8筆閃電貸。其中7筆閃電貸來自PancakeSwap 流動性池的BNB,另外一筆則來自ForTube Bank的USDT。
技術細節分析
在文中,CertiK安全專家添加了地址標籤(如下圖所示),使代幣的流向更加清晰。
攻擊者的地址:https://bscscan.com/address/0xa0acc61547f6bd066f7c9663c17a312b6ad7e187
攻擊者使用的合約地址:https://bscscan.com/address/0xcc598232a75fb1b361510bce4ca39d7bc39cf498
交易一:
https://bscscan.com/tx/0x88fcffc3256faac76cde4bbd0df6ea3603b1438a5a0409b2e2b91e7c2ba3371a
在第一筆交易中,攻擊者完成了兩件事:
①將BNB轉換成 "USDT-BNB FLIP"。
②將 "USDT-BNB FLIP "存入BUNNY的池子。
攻擊者將FLIP存入資金池,這樣當其在後期調用VaultFlipToFlip合約中的Withdraw()或getReward()函數時,資金池將鑄造BUNNY代幣。
①"Zap"所做的是將所提供的代幣的一半換成一對中的另一個代幣,並將兩個代幣提供給相應的PancakeSwap池。這也可以通過BUNNY的Dapp前端來完成。
②將USDT-BNB FLIP存入池中。
交易二:
https://bscscan.com/tx/0x897c2de73dd55d7701e1b69ffb3a17b0f4801ced88b0c75fe1551c5fcce6a979
在完成第一筆交易將"USDT-BNB FLIP "存入BUNNY資金池之後,攻擊者進行了第二筆交易,這也是大多數人最關注的交易。
接下來把第二筆交易中的發生的所有代幣的轉移分解成多個部分:
①攻擊者從7個不同的PancakeSwap流動性池中利用閃電貸共借了232萬BNB,從ForTube用閃電貸款借了296萬USDT。
然後攻擊者向 "USDT-BNB''池提供了7700枚BNB和296萬USDT的流動性,獲得了14.4萬LP代幣。
②攻擊者將從閃電貸中獲得的232萬BNB在PancakeSwap V1池中換取了383萬USDT。
由於V1池的BNB和USDT儲備遠少於V2池,V1池的價格更容易被操縱,在將BNB換成USDT後,BNB價格急劇下降。
③上文提到攻擊者在 "交易一 "中把 "USDT-BNB FLIP "存到BUNNY池,現在攻擊者可以調用 "getReward() "函數來鑄造BUNNY。
在調用"VaultFlipToFlip "合約中的 "getReward() "函數時產生了大量代幣轉移記錄,如截圖所示。
上圖中這個函數發生的細節如下:
❷BUNNYMinterV2從USDT-BNB v2池中取出流動性——從池中取出296萬USDT和7744枚BNB。
❸將USDT換成BNB。在ZapBSC合約中使用的是V1 PancakeSwap Router 而不是V2。
由於V1池的價格已經被操縱(見步驟②),攻擊者能夠將296萬USDT換成231萬BNB。
然後,一半的BNB(115.6萬)被換成BUNNY,另一半的BNB(115.6萬)和換來的BUNNY被添加到BNB-BUNNY池中。
現在,大量的BNB被加入到BNB-BUNNY池中,這增加了BNB(reserve0)的數量。
當之後計算要鑄造的BUNNY數量時,這將被用來操縱 "valueInBNB "變量。
ZapBSC 合約地址 https://bscscan.com/address/0xf4c17e321a8c566d21cf8a9f090ef38f727913d5#code
❹把標記❷中移除流動性獲得的7700BNB交換一半到BUNNY,並將另一半BNB與BUNNY配對,以提供 "BNB-BUNNY "池中的流動性。
注意標記❷、❸和❹發生在 "BUNNYMinterV2 "合約的 "mintForV2 "函數中的"_zapAssetsToBUNNYBNB "函數調用。
BunnyMinterV2合約地址:https://bscscan.com/address/0x819eea71d3f93bb604816f1797d4828c90219b5d#code
❺從標記❸和❹產生的所有LP代幣都被送到PancakeSwap的BUNNY池中,這是BunnyMinterV2合約中 "mintForV2 "函數中的這行代碼所執行的結果:
"IBEP20(BUNNY_BNB).safeTransfer(BUNNY_POOL, bunnyBNBAmount);"
如標記❺所示,該合約繼續執行,鑄造了700萬的BUNNY(基於之前的BUNNY價格價值可達約10億美元)。
那么,是什么原因導致合約鑄造了這么多的BUNNY?呢?
在bunnyMinterV2合約中,要鑄造的BUNNY數量與 "valueInBNB "變量有關,該變量是通過`priceCalculator.valueOfAsset(BUNNY_BNB, bunnyBNBAmount)`函數計算得出的。
在函數`valueOfAsset`中,valueInBNB的計算方法是:`valueInBNB = amount.mul(reserve0).mul(2).div(IPancakePair(asset).totalSupply())`
因為在BNB-BUNNY池中有大量的BNB(正如上圖標記❸、❹中解釋的那樣),變量 "reserve0"是一個非常大的值,使 "valueInBNB "變得很大,所以它最終會增加鑄造的BUNNY數量。
④在收到700萬的BUNNY後,攻擊者在PancakeSwap BNB-BUNNY V1池和V2池中將BUNNY換成BNB。
⑤最後,攻擊者向ForTube和PancakeSwap的7個流動性池償還閃電貸,並將69.7萬枚BUNNY和11.4萬枚BNB轉移到攻擊者的地址。
這種攻擊奏效的原因之一是"ZapBSC "合約(https://bscscan.com/address/0xf4c17e321a8c566d21cf8a9f090ef38f727913d5#code)使用PancakeSwap V1流動性池,通過V1 PancakeSwap Router進行代幣交換。
很多DeFi項目無法從PancakeSwap V1過渡到V2,因為它們在合約中把PancakeSwap Router和池子的地址寫死為V1的地址。
由於V1流動性池已經被放棄,它們的池子中代幣的儲備量很低,這使得攻擊者更容易操縱其中的代幣價格。
寫在最後
當前的加密世界中,這樣的閃電貸攻擊和惡意價格操縱必然不會是最後一次。
CertiK建議DeFi項目將其PancakeSwap集成從V1遷移到V2。
同時也可使用時間加權平均價格(TWAP)來避免價格異常波動所帶來的損失,以此防範黑客利用閃電貸攻擊價格預言機。
迄今為止,CertiK已進行了超過700次的審計,保護了超過300億美元的數字資產與軟件系統免受安全損失。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
Solana基金會Matt Sorg&OKX Web3:Solana帶來巨大創新|开發者物語04
Solana 網絡以及其生態交易工具,成為推動本輪「Memecoin 超級周期」的重要基礎。Sol...
專訪頂級交易員Nachi:大選前夜,Binance排名前10的交易大師如何看待加密後市?
許多人渴望成為職業交易員,然而大多數交易者往往因交易心態失控、倉位管理不當而最終滿盤皆輸。在盈虧不...
CertiK中文社區
文章數量
71粉絲數
0