Rust智能合約養成日記(10-2)
BlockSec
2022-04-03 04:13
本文约4501字,阅读全文需要约18分钟
本文為大家帶來Sputnik_DAOv2::Factory Contract的合約解讀。

前文1. Sputnik-DAO 工廠合約

Sputnik-DAO 採用創建型工廠設計模式(Factory Pattern)實現了該平台下去中心化自治組織(DAO)的統一創建與管理。

本文將詳細介紹Sputnik-DAO 平台工廠模式(sputnikdao-factory)的設計實現。

一級標題

一級標題

2. DAPP 模塊功能介紹

打開Sputnik DAO 平台的DAPP頁面,可見已經有不少去中心化自治組織在該平台中創建並定制了屬於自己的DAO實例對象(Sputnikdaov2合約)。

截止2022年03月,該平台下所創建最活躍的DAO為news.sputnik-dao.near,其中已有3051個提案(proposals)正在公開投票中或狀態已結。

📄為方便讀者理解,以上提供了該合約的架構示意圖供參考。

即所有基於Sputnik DAO 平台創建的DAO實例合約分別被部署在該NEAR賬戶的子賬戶下,例如:

有關NEAR Protocol 中的子賬戶定義,可以在https://docs.near.org/docs/concepts/account#subaccounts 🔗 獲得參考。

如下圖所示,去中心化組織可在NEAR主網中公開發起交易,通過調用sputnikdao-factory合約所提供的create()方法,創建新的DAO實例。

3. sputnikdao-factory 合約代碼解讀

為幫助大家更好地了解Rust工廠模式合約的編寫方法,本文將深入解讀sputnikdao-factory的合約代碼。

3.1 創建DAO

sputnikdao-factory合約狀態主要由如下兩個部分組成:

其中args參數Base64解碼後具體的內容為:

該內容正是部署multicall.sputnik-dao.near合約時,執行合約初始化方法new()時所需的合約配置信息。

下面本文將詳細剖析factory_manager.create_contract的具體實現:

該函數的參數具體說明如下:

由去中心化自治組織所提供的DAO基本信息:Config

5. callback_method:指定了create_contract()方法執行完畢後的回調函數,用於維護處理新建DAO實例合約在本工廠合約中的信息。

6. callback_args:回調函數的函數參數。

該函數的執行主要分為如下幾個步驟:

最終DAO實例合約部署完畢後,將在factory_manager.create_contract()執行的末尾代碼32-53行回調on_create()函數。

如下是回調函數on_create的內部代碼實現:

該函數具體的處理邏輯為:

正文

正文

正文

代碼位於:sputnikdao-factory2/src/lib.rs # Line136-149

值得一提的是:

值得一提的是:

BlockSec在對Sputnik-DAO 代碼進行解析的過程中發現其Factory 合約中存在著一個嚴重的安全問題,會影響所有使用了Sputnik-DAO的合約。經與項目方聯繫後,最終該Issue被確認並及時修復。

💡該安全漏洞具體描述為:

在先前版本的代碼中,sputinikdao工廠合約所提供的public update()方法缺少瞭如下一個關鍵的斷言檢查。這導致了該方法可以被任何人調用。

而巧合的是,DAO實例合約(Sputnikdaov2合約)默認允許了可由Sputnik-DAO Factory通過跨合約調用實現本合約的升級。

DAO實例合約中實現的update()方法如下,代碼位於sputnikdao2/src/upgrade.rs # Line 62

上述代碼的第9行中,factory_info.auto_update該值在DAO實例合約部署調用new()方法進行初始化時被默認設置為True。

DAO實例合約new()方法實現如下:代碼位於sputnikdao2/src/lib.rs # Line 83-104

綜上,一位普通用戶(非Factory合約以及DAO合約本身)即可通過Factory合約所提供的pub fn update()方法實現對任意DAO合約的代碼升級(篡改),這會給Sputnik-DAO 平台以及所有依賴於Sputnik-DAO 平台的合約項目帶來極大的安全隱患。

🪴 好在,發現此問題時該版本代碼暫未上線NEAR主網,因此沒有造成損失。

正文

一級標題

正文

上述發現並已修復的漏洞之外,Sputnik-DAO Factory合約的安全性主要還從如下幾個方面進行保證:

以下函數均未修改狀態變量:

由於項目方響應迅速,目前該漏洞通過增加合理的白名單校驗機制已被正確修復😊

詳見此Fixing Commit: 518ad1d97614fff4b945aba75b6c8bd2483187a2🔗

BlockSec
作者文库