How 20 Million $OP Was Stolen from the Multisig Wallet (Not Yet) Owned by Wintermute
Wintermute was engaged by the Optimism Foundation for liquidity provisioning services on the $OP launch. On May 27, 2022, 20 million $OP was allocated to Wintermute from the Foundation’s Partner Fund. However, Wintermute later found that they could not access these tokens because they had provided an Ethereum (L1) multisig address that they had not yet deployed to Optimism (L2). Unfortunately, an attacker found this and deploy the multisig contract with the same address to L2 before Wintermute.
After the incident, the following announcements were made by both teams:
- A Message to the Community from the Optimism Foundation:
- Message to Optimism community from Wintermute: https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595
We’ll walk through how the attacker was able to take control of these 20 million $OP.
- Wintermute Multisig Wallet Contract on Ethereum (L1):
- Attacker Multisig Wallet Contract on Optimism (L2): https://optimistic.etherscan.io/address/0x4f3a120e72c76c22ae802d129f599bfdbc31cb81
- Attacker Wallet #1:
- Attacker Wallet #2:
- Attacker Contract:
- Gnosis Safe Proxy Factory Contract on Ethereum (L1):
- Gnosis Safe Proxy Factory Contract on Optimism (L2):
- Gnosis Safe Deployer on Ethereum (L1): https://etherscan.io/address/0x1aa7451dd11b8cb16ac089ed7fe05efa00100a6a
- Gnosis Safe Deployer on Optimism (L2): https://optimistic.etherscan.io/address/0x1aa7451dd11b8cb16ac089ed7fe05efa00100a6a
Summarized Attack Steps
- The attacker used Attacker Wallet #2 to send gas to the address of Gnosis Safe Deployer in two transactions:
- The attacker replayed the transactions of Gnosis Safe Deployer to deploy Proxy Factory contract:
- The attacker used Attacker Wallet #1 to deploy an attacking contract.
- The attacker used Attacker Wallet #2 to execute 62 transactions for creating the Gnosis Safe multisig contracts (162 contracts were created per transaction).
- The address (0x4f3a120e72c76c22ae802d129f599bfdbc31cb81) that holds 20 million $OP was created on the 55th attempt.
Root Cause Analysis
The 20 million $OP on Optimism (L2) was transferred to “0x4f3a120e72c76c22ae802d129f599bfdbc31cb81”, an address that is owned by Wintermute on Ethereum (L1), but “not yet” owned by anyone on Optimism (L2). This was done in two transactions:
The Wintermute multisig wallet on L1 was created with the
createProxy() function of the Gnosis Safe Proxy Factory contract. The proxy contract was created with the
new keyword, which uses the
CREATE opcode behind the scenes.
The address of the smart contract deployed with the
CREATE opcode will be computed by the
keccak256(senderAddress, nonce). In this case, the
senderAddress which creates this contract is the Gnosis Safe Proxy Factory contract itself (0x76e2cfc1f5fa8f6a5b3fc4c8f4788f0116861f9b) and the
nonce is the number of the contract created by this factory (increased on every proxy contract created).
This means that if the
senderAddress and the
nonce on L2 is the same as L1, the deployed address on L2 will be the same.
In order to attack, the Gnosis Safe Proxy Factory contract must be deployed on L2 with the same address as on L1. However, before the attack, the
ProxyFactory contract had not been created yet. So, at the first glance, it looks like it will be impossible unless the attacker can force the deployer to deploy the contract using the same nonce.
Deployer of the ProxyFactory
We have found that the Gnosis Safe Proxy Factory contract on Optimism (0x76e2cfc1f5fa8f6a5b3fc4c8f4788f0116861f9b) was deployed by an address that is tagged as “Gnosis Safe: Deployer 3” on Ethereum (0x1aa7451dd11b8cb16ac089ed7fe05efa00100a6a).
This happened just right before the deployment of the ProxyFactory on Optimism (L2) contract in this transaction:
In order to deploy the
ProxyFactory using the address of “Gnosis Safe: Deployer 3”, the generally accepted fact is that the attacker needs to have the private key of that address; however, that may not be true in this case.
Replay Attack on Non EIP-155 Transaction
Before EIP-155, the signature on transactions only requires the hashing of only six rlp encoded elements:
(nonce, gasprice, startgas, to, value, data) . This means that the transaction can be directly replayed on other EVM-based chains, including Optimism. EIP-155 prevents this by suggesting that the hash should come from nine rlp encoded elements:
(nonce, gasprice, startgas, to, value, data, chainid, 0, 0) . The added
chainid prevents the same transaction from being replayed on other chains.
Since the creation of the
ProxyFactory contract on Ethereum was not complying with this EIP, the attacker was able to replay the transactions in order to deploy the
ProxyFactory contract on the same address as on Ethereum.
ProxyFactory contract available, the attacker was able to
CREATE a massive amount of multisig contracts until the same nonce is reached, getting hold of the multisig contract with the same address as the Wintermute multisig wallet on L1 and taking control of the address that holds 20 million $OP.
On EVM-based chains, the access to the externally owned account (EOA) is held by the owner of the private key. However, when an address is created from a contract, it is not guaranteed that the ownership defined in the smart contract will be the same on all chains. By having 20 million $OP transferred to an address not yet owned by anyone, an attacker used a replay attack to deploy the factory contract, and deployed 10,044 multisig wallet contracts in total through the newly created factory in order to take control of the address that is holding those tokens.
Update #1 (Jun 9, 2022, 11.30 UTC): Added “Deployer of the ProxyFactory” Section
Update #2 (Jun 11, 2022, 13.00 UTC): Added information about replay attack
Inspex is formed by a team of cybersecurity experts highly experienced in various fields of cybersecurity. We provide blockchain and smart contract professional services at the highest quality to enhance the security of our clients and the overall blockchain ecosystem.