Analysis & Solution to the Attack on Optimism by Fairyproof
On May 27, when the Optimism team was sending 20 million OP tokens to Wintermute, it mistakenly sent the assets to the address of…
On May 27, when the Optimism team was sending 20 million OP tokens to Wintermute, it mistakenly sent the assets to the address of 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Layer 2 (Optimism).
However, this address was inactivated and was not used by Wintermute. The expected receiving address that was provided by Wintermute should be 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Layer 1 (Ethereum). And this address was a Gonsis Proxy’s multi-sig contract address.
So, the next expected step for the Optimism team to do would be to withdraw the tokens sent to 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Layer 2 (Optimism).
There is a mature and feasible solution to this. The trick is to call “create2” to deploy the same multi-sig contract at 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Optimism.
When calling “create2”, we can manipulate the generated contract address by inputting a salt and an init_code values that are specifically designed. This way we can generate a contract address on Optimism that is exactly the same as the one on Ethereum.
Basically, we can do it in two steps:
Step 1, using the same deployer address and same nonce to deploy a Gnosis Safe: Proxy Factory 1.1.1 contract on Optimism,
Step 2, calling “createProxy” with the same nonce (as the salt value) and same init_code that were used on Ethereum to deploy a Proxy contract at an address on Optimism that is the same as the one on Ethereum.
Unfortunately, someone (the attacker of the later attack on Optimism) was acquainted with this solution as well and has been closely watching the Optimism team’s subsequent operations.
Right after a Gnosis Safe: Proxy Factory 1.1.1 contract was deployed on June 5, the attacker from 0x60B28637879B5a09D21B68040020FFbf7dbA5107 on Optimism promptly called “createProxy” to deploy a Proxy contract at 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Optimism and withdrew all the 20 million OP tokens. The attacker successfully completed all these operations before the Optimism team and the Wintermute team.
The attacker exchanged the exploited 20 million OP tokens for ETHs and cash out 729 ETHs valued at around $17 million via Tornado Cash on Ethereum.
This is a new kind of attack and Fairyproof would name it “contract hijacking”. Then how can we prevent this attack from happening especially in this case?
The key is in the second step: that is, we need to make sure all the operations that we call “createProxy” to generate the same nonce and deploy the multi-sig contract at 0x4f3a120E72C76c22ae802D129F599BFDbc31cb81 on Optimism should be completed in ONE single transaction.