Wintermute 於 Layer 2 遭攻擊損失 20M $OP
今天要分享的是前陣子兩千萬枚 $OP 代幣被攻擊者盜取的事件。這個事件源自於 Wintermute 造市商提供錯誤的地址給 Optimism,導致代幣轉入沒有人擁有的地址,後來卻被攻擊者搶先擁有這個地址。這篇內容我們將以這個事件為背景,介紹 create 和 create2 的概念。
事件
起初,Optimism 基金會聘請 Wintermute 為其在中心化交易所上市的 OP 代幣提供流動性,協議的一部分是 Wintermute 獲得兩千萬枚 OP 代幣作為貸款(Wintermute 也提供 $50M USDC 作為抵押品)。這筆貸款應該是要轉入 Wintermute 在 Optimism 鏈上的地址,但他們卻提供已經部署在以太坊上許久的多簽(multi-sig)Gnosis 金庫地址: 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81。當 Optimism 團隊分別轉移 1 OP 和 1M OP 作為測試時,Wintermute 卻沒有確認真的收到那些代幣就和 Optimism 團隊確認了,所以剩下的 19M 代幣就又在 5/27 轉入了這個錢包地址。
Wintermute 提供的地址和普通的錢包地址(EOA, externally owned account)不同,他是一個合約地址,因此擁有在以太坊上這個合約的所有權不代表擁有其他 EVM-compatible 鏈上相同地址的所有權。而這個地址當時在 Optimism 鏈上還沒有所有人。5/30 Wintermute 發現了這個錯誤,並通知了 Gnosis 金庫和 Optimism。經過諮詢後他們宣稱只有他們自己能夠復原那些資金,並計劃在 6/7 將資金取回。
Wintermute 的 Gnosis 金庫地址是 2020 年 由 ProxyFactory 合約(0x76E2)的 createProxy 這個 function 創造的。這個 ProxyFactory 合約在部署時沒有指定的 chainId,因此這個 ProxyFactory 合約在每一條鏈上的合約地址都一樣。此外創建 proxy 合約時,創建出的 proxy 合約其地址只受 sender, nonce 這兩個變數影響,所以在不同的鏈上只要用一樣的 sender 和 nonce 就能得到相同地址的合約。
攻擊者(0x8BcF)在 Optimism 鏈上也創立一個合約(0xE714)去呼叫 Optimism 鏈上的 ProxyFactory(0x76E2)的 createProxy 創造地址直到找到 0x4f3a 的那個地址。下圖可以看到攻擊者在一筆交易一次創建 162 個地址,不斷的重複這樣的交易直到找到符合的地址,最後在這筆交易中創建了與 Wintermute 在以太坊上一模一樣的地址(0x4f3a)。
攻擊者將 1M OP 代幣轉入自己的地址,賣掉後獲得大約 720 ETH。幾天後又將 1M 代幣轉入 Vitalik 的錢包地址(0x8da6)。最後將 17M 代幣以一次 1M 的方式歸還到 Wintermute 指定的地址(0x2501),剩餘的 1M Optimism 團隊也同意將總共 2M 的 OP 代幣留給攻擊者作為賞金。
技術點 create/create2
這邊可以介紹兩個以太坊在創建合約時可以用到的 opcode — create 和 create2。
- create: new_address = hash(sender, nonce)
- create2: new_address = hash(0xFF, sender, salt, bytecode)
create2 可以說是 create 的升級版,在 EIP-1014 時被提出。create 的缺點是下一個被創建的合約地址是可以被預測的,因為 nonce 會照順序增加。而 create2 則是使部署的地址獨立於未來事件,可以在預先計算出的地址上部署合約。create2 確保如果 sender 用這個 opcode 部署 bytecode 和提供的 salt,它將存儲在 new_address。
上述事件的 ProxyFactory 用的就是 create 而不是 create2,導致攻擊者只要用相同的地址(0x76E2)作為 input 去反覆創建地址就能找到與當初再以太坊上創建給 Wintermute 一樣的合約地址(0x4f3a)。如果這個 ProxyFactory 用的是 create2 的話則需要被部署的合約 bytecode,而因為被部署的是多簽金庫合約,合約內容會有這些共同擁有者(進行多簽的地址們)的地址,因此攻擊者產出的 bytecode 自然會因為與原先的不同,也就無法用 createProxy 去產出相同的地址。
以上的介紹希望有幫助大家了解這個 OP 代幣損失的事件,以及 create 和 create2 這兩個 opcode 的不同。喜歡我們的內容可以幫我們「拍手」,並持續關注我們!