🔴 How did a hacker steal OP?

Wintermute had their mainnet safe deployed from a Proxy Factory 1.1.1, which is older than the earliest official Optimism deployment of 1.3.0.

Luckily for our hacker, Safe deliberately utilizes non-EIP-155-compliant deployment transactions, which can be replayed on any network which doesn’t enforce EIP-155.

They did exactly that, replaying the deployment of Proxy Factory 1.1.1 on Optimism.

Similar to externally owned accounts, contracts on Ethereum maintain a nonce, which is increased when they spawn new contracts with either CREATE or CREATE2. Both addresses can be predicted from either (address, nonce) or (address, salt, initcode).

This safe was created using createProxy(masterCopy, data) which uses CREATE that only depends on the Factory address and its nonce value. The attacker can manipulate both the master copy and data parameters, assigning themselves as the owner. This is not possible for safes created with CREATE2 since they use the initializer (which includes the owner set) as a salt which affects the resulting address.

We can calculate that Wintermute’s safe was created at nonce 8884, and since it’s a fresh Factory, the attacker had to create all the preceding safes first. To pull this off, they created a contract which initializes 162 safes at a time, which they called 62 times, increasing the Factory’s nonce to 10,054.

This has allowed them to grab Optimism addresses for a lot of safes existing on mainnet, including a safe matching Wintermute’s address.

Subscribe to banteg
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.