從 The Saudis NFT 事件淺析 EIP-2535 鑽石協議

— 導讀/ 原用標題

作者:九九 @慢霧安全團隊

背景信息

2022 年 7 月 10 號,一個火熱的 NFT 項目 TheSaudis 開啟了 freemint 活動(白名單用戶可以免費鑄造其 NFT)。而就在 mint 活動結束後,一位名叫 RIGHTBLOCK 的用戶在市場上大量地拋售該 NFT,項目方發現後迅速鎖定到了該用戶並對合約進行改動以此來將該用戶手裡的大量 NFT 轉移回來,他們之後承諾會將這些 NFT 回饋給社區用戶。

圖片

那麼為什麼項目方可以將該用戶手裡的 NFT 轉移呢?經過我們的分析發現該 NFT 項目的合約採用了 EIP-2535 協議也叫做鑽石協議,項目方利用該協議重寫了合約的功能,以此來實現這些 NFT 的轉移。接下來慢霧安全團隊將會為大家介紹下這個鑽石協議(EIP-2535)的細節。

鑽石協議介紹

EIP-2535 是以太坊上一個將合約進行代碼模塊化組合的提案,其目的是為了讓大型的智能合約突破 24kb 大小的最大限制,並且讓合約更方便地更新功能。

要理解鑽石協議,首先有幾個相關的概念定義需要知道:

  • 鑽石(diamond) : 鑽石可以理解為代理合約(Proxy),也是與用戶進行交互的主合約
  • 切面(facet) : 正如真正的鑽石有不同的側面一樣,一個鑽石合約也有著不同的面,鑽石合約的每個功能所需要調用的合約對應一個切面,所以也可以理解為實現合約(Implementation)
  • 鑽石切割(diamondCut) : 鑽石協議標準擴展了一種叫鑽石切割的功能,其主要作用從鑽石中增加、替換或刪除切面和功能,可以理解為合約的升級(Upgrade)
  • 放大鏡(The Loupe) : 鑽石協議標準中的放大鏡功能主要是返回關於切面的信息和鑽石存在的功能,這些信息是保存在鑽石合約內部的存儲結構——DiamondStorage 中

整個鑽石模型類似下圖:

圖片

通過使用鑽石標準規範去創建鑽石合約,這個合約可以像使用當前合約的代碼一樣使用任何數量的其他切面合約的代碼。

在該鑽石合約中不同的函數功能需要調用對應的不同的切面合約的代碼來實現,並且可以利用鑽石切割的功能來對鑽石合約中的函數功能進行修改(添加、替換或刪除)。

這與市面上大多數使用一個代理合約和一個實現合約來實現交互與升級的方式有所區別。

圖片

事件分析

接下來回頭分析下 The Saudis 這次事件中的一些細節,在該項目的 DiamondCutFacet.sol 合約中,可以看到實現了 diamondCut 功能的函數。

圖片

該函數首先會調用 LibDiamond 庫的 enforceIsContractOwner 函數來判斷調用者是否是合約的 owner,如果是 owner 調用的話會調用 LibDiamond 庫的 diamondCut 函數來實現鑽石合約的功能更新。

圖片

跟進到該函數我們發現鑽石切割會根據傳入的不同的 action 來判斷進行添加、替換或刪除功能,故接下來跟進看看項目方調用該函數的交易。

圖片

我們發現傳入了新的切面合約 0x70d8ccaf6b50b051ab1e8fa238626163e45a8b03(未開源),傳入的 action 設置為 1 則應該是調用了 replaceFunctions 來實現替換功能。

圖片

從 replaceFunctions 函數中可以分析出該函數首先會為傳入的地址新增一個切面,接著從存儲中循環讀取傳入的每個函數選擇器對應的舊的切面進行刪除,並為這些函數的切面添加為傳入的新的切面地址。

至此可得知 The Saudis 項目方就是利用了鑽石切割函數來重寫了轉賬功能,以此來將用戶 RIGHTBLOCK 手中的 NFT 轉移回自己的賬戶。

相關信息

The Saudis 合約地址:

0xe21ebcd28d37a67757b9bc7b290f4c4928a430b1

用戶 Rightblock 地址:

0x80266b1e3f0C2cAdAE65A4Ef5Df20f3DF3707FfB

項目方更新合約的交易:

0xbc559a72f73e6c9a53416fd13a3ebaaa76dca5855ff8b79511585f514eaf2390

免責聲明:作為區塊鏈信息平台,本站所發布文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。本文內容僅用於信息分享,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。