ccryptoo 1 1637835246
新聞

DeFi 乾貨|Dinosaur Eggs 的流動性池漏洞解析 – Amber 安全團隊

MasterChef 智能合約可能是在 DeFi 最早一波狂潮時,被重新部署最多次的一個合約,很多的 DeFi 項目都會修改該合約來實現自己的流動性挖礦功能。本文 Amber Group 將分享並解析 10 月團隊發現的失誤項目  Dinosaur Egg 其流動性池漏洞案例。

 

(本文由  Amber Group 研究團隊撰著、提供,不代表動區立場。)


2020 年夏天, SushiSwap 創辦人 Chef Nomi(@NomiChef)[1] 所發布的 MasterChef 智能合約 [2] 可能是最早的一波 DeFi 狂潮中被重新部署最多次的一個合約。很多 DeFi 項目會略為修改 MasterChef 合約來實現他們流動性挖礦的功能。

然而,過去一年多的時間內,有幾個項目在修改 Nomi 主廚的食譜過程中犯了錯誤,造成無法挽救的損失 [3][4][5]。2021 年 10 月 6 日,我們也發現了一個失誤的項目,所幸在還沒造成損失之前便成功修復了漏洞並且完成升級。

0x00: Dinosaur Eggs

這次事件的主角 Dinosaur Eggs 項目的 LiquidityPool 智能合約 [6] 也是一個『加強版』的 MasterChef 合約,其主要修改的部分是新增了「addtionalRate」功能。這個功能是為了讓特定的 NFT 持有者在存入 LP tokens 時可以獲得額外的獎勵,最高可達 10%,條件是存入 LP tokens 之前必須『燒掉』特定的 NFT 資產。

ccryptoo 1 1637835249

從上面的程式碼片段 327-328 行可以看到(_amount*user.addtionalRate)會被加到 user.addtionalAmount 裡頭,而這個 addtionalAmount 會在計算獎勵時被加入計算。

0x01: 漏洞細節

ccryptoo 1 1637835250

漏洞出現在從 MasterChef 繼承而來的緊急逃生出口 — emergencyWithdraw() 函數。這個函數是用來讓 user 可以在緊急情況把所有存入的 LP tokens 一次取出來,不考慮獎勵計算。

然而,前面提到的 user.addtionalAmount 在這個函數裡沒有被 reset,也就是說下一次的 harvest() call 會出現 user 沒有存入任何 LP tokens 的狀態下仍然可以領取獎勵的情況。

ccryptoo 1 1637835251從 harvest() 函數的第 342 行可以看到 pendingAmount 的計算是 [(user.amount+user.additionalAmount)*pool.accRewardPerShare – user.rewardDebt]。

由於之前的 emergencyWithdraw() 已經 reset 了 user.amount 以及 user.rewardDebt,pendingAmount 就變成了 (user.addtionalAmount*pool.accRewardPerShare)。

因此,攻擊者可以在沒有任何 LP tokens 存入的狀態下,不停的來回利用 harvest() 跟 emergencyWithdraw() 把所有的 reward tokens 取出。

0x02: 漏洞利用

ccryptoo 1 1637835253

上面的攻擊合約程式碼驗證了上述的想法,在 prepare() 函數裡,我們刻意鑄造了一個 NFT (第 36 行)並且透過第 40 行的 additionalNft() 函數啟動了前面提到的 addtionalRate 機制,隨後我們 deposit() 了一部分 LP tokens 到 LiquidityPool。

為了獲得額外的獎勵,我們在 trigger() 函數裡利用迴圈多次調用 emergencyWithdraw() 與 harvest() 函數(第 48 – 51 行)。

ccryptoo 1 1637835254

從上面的 eth-brownie 截圖可以看到,我們只用了 30 個 LP tokens(DsgLP)就能獲取上千個 reward tokens(DSG)。在同樣的情況如果只是單純的 harvest() 沒有刻意 emergencyWithdraw(),只有不到一個的 DSG 獎勵 。假設攻擊者利用閃電貸款生成大量 LP tokens,還能更進一步擴大獲利。

0x04: 後續發展

在我們向 DSG 團隊通報這個漏洞之後,他們很快的確認問題並且展開了修補工作。

新版的 LiquidityPool 合約部署上線後,DSG 團隊通知了用戶將資產從舊版取出後遷移到新版,同時也將舊版的流動性挖礦暫停。

幸運的是,在完成遷移之前,並沒有真正的攻擊發生,DSG 團隊也根據漏洞賞金計畫給了我們 $10,000 等值的 DSG tokens 獎勵 [7] 。這部分獎金 [8] 隨後將被用來捐助開放文化基金會,支持開源軟體發展

ccryptoo 1 1637835256
– 圖源:由 Amber Group –

📍