# op代币丢失始末

By [yang](https://paragraph.com/@yang-7) · 2022-06-10

---

5月8号早上看到很多关于op 2000万代币丢失的消息。两天过去了 很多大佬已经对整件事有了非常明了的梳理了。我自己再整理一遍给自己看。

涉及地址：

Gnosis Safe: Deployer 3（

0x1aa7451DD11b8cb16AC089ED7fE05eFa00100A6A

）

Gnosis Safe: Proxy Factory（

0x76E2cFc1F5Fa8F6a5b3fC4c8F4788F0116861F9B

）

masterCopy

(0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F)

攻击者钱包地址（

0x60B28637879B5a09D21B68040020FFbf7dbA5107

）

攻击者批量创建多签钱包地址（

0xE7145dd6287AE53326347f3A6694fCf2954bcD8A

）

Wintermute Exploiter Multisig（

0x4f3a120E72C76c22ae802D129F599BFDbc31cb81

）

攻击者的另一个地址（

0x8bcfe4f1358e50a1db10025d731c8b3b17f04dbb

）

先回顾一下 op 项目方给 Wintermute 2000万个op 去做市商 Wintermute 给op项目方提供了Multisig合约地址，op项目方先测试了两笔 地址收到了 就给转了2000万枚。这个过程中Wintermute 并没有在测试的时候检查是否有Multisig合约地址的控制权。那为什么Wintermute 会提供给op项目方Multisig这个地址呢？其实Multisig是Wintermute 在eth上的多签钱包地址，至于为什么他要提供这个地址，是疏忽还是别的什么原因就不得而知。

我们知道合约地址在为创建时就是一个普通eoa地址 只是我们谁也不知道私钥。在Multisig收到2000万op时 它在op链上还是一个没有私钥的普通EOA地址。但是它在eth链上已经是一个合约地址了 由于op链与eth链都是evm兼容的链。很多实现都是一模一样的。于是一个大胆的想法就产出了 是不是可以在op链上创建出这个合约地址来？

在eth链上创建合约 有两个方法 ，分别时create2 与 create

![](https://storage.googleapis.com/papyrus_images/b8960ec1077ad726f55f4b910a842201346638d2eca299b2282cc9a4762a7513.png)

![](https://storage.googleapis.com/papyrus_images/9a6a327a33332f75bb5dcc564d4259094444281fe2a141a15c23ba9c5e0e8d64.png)

那我们就先去看看eth这个Multisig是怎么创建的吧

创建交易

0xd705178d68551a6a6f65ca74363264b32150857a26dd62c27f3f96b8ec69ca01

![](https://storage.googleapis.com/papyrus_images/b6fffa8c0852a07edb86098186e07d844154eb61aafddeb2573367d0775b208a.png)

Multisig是由一个EOA地址调用了Proxy Factory合约的

createProxy(address masterCopy, bytes data)方法以masterCopy 与data为参数创建的

由于createProxy是在区块浏览器验证的地址 我们就可以去看看它的具体实现

![](https://storage.googleapis.com/papyrus_images/753b17b4e4fc4b6f8fb55da14efa1faad762fbe6f6c06f0ff11c84a71f10d15b.png)

显然它是用create创建的

也就是说我们要创建出与eth链上地址相同的Multisig合约 我们只需要用op链上Proxy Factory不断去创建多签钱包 op链上Proxy Factory的nonce值与eth链上创建Multisig的nonce值相等的时候创建出来的Multisig合约地址就会与eth链上的合约地址相同。

实际上攻击者也确实是这样做的

他首先创建了批量调用op链上Proxy Factory创建多签钱包的合约（0xE7145dd6287AE53326347f3A6694fCf2954bcD8A）

然后批量去创建（eth链上创建出Multisig地址的nonce我们是可以知道的）

![](https://storage.googleapis.com/papyrus_images/7b36b1df19e828ffdc1bf5161f954beb2aaa7cca739cc4bac4dc4f984af902cf.png)

终于在交易

0x53ce65948fd07bb012142578fe399ddfe0a0cfab3a941ef56b33cde706ad9b24给创建出来了

到此攻击者就创建出接受2000万op的Multisig合约了 也拥有了合约的看控制权。

拥有控制权后 他通过交易

0x230e17117986f0dc7259db824de1d00c6cf455c925c0c8c6b89bf0b6756a7b7e

给地址0x60B28637879B5a09D21B68040020FFbf7dbA5107转了100万op并立马在inch上获利720个eth。

在9号是我以为这就是事件的整个过程没有想到忽略了最关键的部分。

在攻击者攻击之前Proxy Factory合约在op链上是没有创建的。

那就必须得先创建出Proxy Factory。

那我们再去看看eth上得Proxy Factory合约是如何创建得

![0x75a42f240d229518979199f56cd7c82e4fc1f1a20ad9a4864c635354b4a34261](https://storage.googleapis.com/papyrus_images/2806f5727ca4df161256e61e9a565cb4f73664def064eaea4adc91651f373a3f.png)

0x75a42f240d229518979199f56cd7c82e4fc1f1a20ad9a4864c635354b4a34261

而Proxy Factory得创建这是一个EOA（ Gnosis Safe: Deployer 3）地址，整个地址应该是属于Wintermute 的。怎么办？

那就先去op上看看这个地址（ Gnosis Safe: Deployer 3）

此时在op上是没有任何交易的

再看个前置知识。

![](https://storage.googleapis.com/papyrus_images/e1d0015d1ba305f5b6cd81ff3a0cec636c07866b6c9c8ded896cda7c65ed9ea0.png)

现在我们知道如果eth链上的Gnosis Safe: Deployer 3 创建Proxy Factory的前几笔交易都是不符合eip155标准我们就可以再op链上重放这些交易 从而再op链上创建出Proxy Factory合约。

重放的过程就直接贴上慢雾的文章了 （不太想写了）

![](https://storage.googleapis.com/papyrus_images/d502f2f46c28d56d26fa747ea07f46eb31560af2f2a4c86f6a13dccc4443787b.png)

![](https://storage.googleapis.com/papyrus_images/6aeb8f6e4e70ace637607f2ac5e44873ff6be538574425297c6ee5c38e5447bd.png)

![](https://storage.googleapis.com/papyrus_images/98167658a1b230ed783e3646e7b9cacbec7b38bad22f2c652c9983c10301af90.png)

再对比一下两条链的这几笔交易

eth

![](https://storage.googleapis.com/papyrus_images/5a5c5317a4d36970294ad76b0e1d1da96e067ea032b690929fe16766b1b21826.png)

op

![](https://storage.googleapis.com/papyrus_images/4c806bfb15165d10c3ce9254953ef97b1362d46ce255ac06abc86f357feabbff.png)

是不是发现交易hash都是一样的啊

第一笔创建了创建Implementation（masterCopy）

第二笔 调用了 0x34F5c67D50d7539B69B743F45B7e24ebBE7202cA 合约的

Function: setImplementation(string contractName, address implementation) 方法

implementation为第一步创建的masterCopy

第三笔 创建了Proxy Factory，后面创建Multisig 传的masterCopy 就是第一步创建的合约是具体的逻辑合约。到此 对上前面就是整个过程

---

*Originally published on [yang](https://paragraph.com/@yang-7/op)*
