在Solidity定點庫上進行差異模糊測試
BlockBeats 律動財經 2023-07-02 01:30
介紹
安全是編寫智能合約的最重要的方面之一。開發人員可能熟悉傳統的單元測試來測試他們的代碼,但這隻提供了基本的覆蓋範圍來測試代碼的功能和業務邏輯。然而,它們是在假設智能合約在給定條件下的表現符合預期的基礎上運行的。為了進一步增強安全性,我們需要採用更高級的測試方法,如差異模糊測試(differential fuzzing)。
差異模糊測試是一種測試類型,它涉及執行相同功能或函數的不同實現,並比較結果。這種測試允許我們驗證不同實現之間是否是等價的,並且在提供無效或隨機輸入時表現一致。這與普通模糊測試不同,後者通常通過為單個實現提供廣泛的隨機輸入範圍並監控意外行為、崩潰或安全漏洞來進行測試。
在這個項目中,我們使用 Foundry 對不同的定點庫(OpenZeppelin、Solmate、Solady 和 Prbmath)進行差異模糊測試。請注意,在 Solmate 庫的幾個主要版本中,我們使用了最新的(v6)的代碼庫,因為我們認為大多數選擇 Solmate 庫的新項目會選擇這個版本。我們希望檢查不同代碼庫對於相同的函數實現是否有顯著差異。在跑了一千萬次測試後,我們發現這些庫之間具有廣泛的兼容性,但是在處理邊緣情況和燃氣費消耗方面存在一些差異。
具體差異 我們將通過以下示例來說明這些庫實現上的差異。 在 Log2 函數(返回以 2 為底的對數)中,如果輸入為 0,OpenZeppelin 和 Solady 的實現會返回不同的結果。OpenZeppelin 將直接返回 0,而 Solady 將返回 0x5be3aa5c(即 Log2Undefined() 的簽名)。
因此,我們在測試用例中添加 if (num != 0) 來避免這種差異。 在 mulDiv() 函數中也出現了類似的差異。我們需要確保除數不為零且沒有溢出。否則,OZ 和 solady 會報錯。例如,Solady 將返回 0xad251c27,這是 MulDivFailed() 的簽名,所以我們也添加了 if 語句。 如果你想要在測試中重現錯誤情況,請注釋掉 if 語句,然後使用特定測試用例。
並請參考庫實現來了解為什麼他們會這樣處理。
Gas 報告
由於這些庫中的函數大多相互兼容,我們對它們的燃氣費消耗進行了比較,來檢測哪一個數據庫是最省燃氣費的。 燃氣費快照可以在.gas-snapshot 文件中找到。為了更好的閱讀性,我們附上了簡化的燃氣費報告(每個函數調用的平均燃氣費消耗)。
或者你可以運行這個命令來獲取它。
我們發現 OpenZeppelin 的燃氣費消耗要遠高於其他代碼庫的函數。特別是,像 OzLog2、OzLog2Up、OzMulDivDown、OzMulDivUp 和 OzSqrt 這樣的函數消耗的燃氣費比其他庫中的對應函數更多。 在其餘的庫中,solady 是燃氣費最優的一個。
solady 庫中所有比較的函數的燃氣費消耗相對較低,而且它提供了最全面的功能,這使得它成為高級開發人員的首選。但是,值得注意的是,只有 OpenZeppelin 和 Solmate 經過了外部安全團隊的審計。
即使是 Solmate 也並不是設計之初就簡單易用的,所以在你搬起石頭砸了自己的腳之前,應該徹底閱讀文檔並理解代碼庫。 好消息是,Cantina 決定將 Solady 庫作為公共項目進行審計,你可以在這裡監控他們的審計狀態。
足夠的模糊測試
為了確保模糊測試的正確性,我們進行了 9999999 次的模糊測試。通常,在開發過程中沒有必要運行這麼多次,但作為安全研究人員,我們希望覆蓋儘可能多的隨機輸入。 你可以在 [foundry.toml]中更改運行次數。更多的運行次數意味著有更多的隨機輸入輸入到函數中。如果你想要運行快速測試,例如用於持續集成,請根據你的需求調整配置。
建立在我們的基礎上
在龐大的 Solidity 庫中,定點算術只是其中一個方面。為了擴大這項研究的範圍,我們可以比較處理不同功能的庫,使用不同的 pragma 版本。這將為我們提供跨不同用例和 Solidity 版本的安全的更廣泛理解。 此外,我們還可以記錄 Foundry 使用的隨機輸入並進行分析。這將使我們能夠判斷這些輸入是否真的隨機,並確保對庫進行公平和全面的評估。
結論
我們進行差異模糊測試的主要目的是揭示 OpenZeppelin、Solmate、Solady 和 PRB-Math 的 Solidity 定點庫在輸出結果方面的顯著差異。雖然這些庫在兼容性方面表現良好,但我們的測試發現它們在處理邊緣情況時存在細微差別,尤其是在 Log2 和 mulDiv 函數中。
雖然這些差異可能看似微小,但它們可能導致智能合約出現意外行為,因此具有重要意義。 通過這項工作,我們希望為開發人員提供詳細的見解,以指導他們在為智能合約應用程序選擇庫時做出決策。我們的研究沒有發現這些庫之間存在重大偏差。
然而,我們觀察到的細微差異提醒人們充分測試和理解所使用代碼的重要性。 在區塊鏈世界裡,代碼就是法律,確保代碼的安全性至關重要。對 Solidity 庫進行差異模糊測試是實現這一目標的一步,它提供了比單元測試更高級別的保證。我們期待看到一個更安全的加密生態。
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與虛擬貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 加入鉅亨買幣LINE官方帳號索取免費課程
- 掌握全球財經資訊點我下載APP
文章標籤
上一篇
下一篇