Sign up to get this newsletter every week: https://tinyletter.com/smart-contract-security/
This week was a little bit slow in the sense that there were no “major incidents”. Though there has been a lot of chatter about
CREATE2 (EIP-1014) this week.
So, what is all this stuff about CREATE2?
I thought I’d try to distill that down a bit, and an FAQ format felt like the right way to do it.
It’s a new opcode for deploying smart contracts. Similar to
CREATE2 is called in a contract (which I’ll refer to as the ‘factory’) it will run some
init_code. Whatever that
init_codereturns will be the code in the new contract. In Solidity, this
init_code is defined by a
How is it different from
The important difference is in how the address of the new contract is determined.
CREATE the address is determined by the factory contract’s
CREATE is called in the factory, it’s
nonce increases by 1.
CREATE2, the address is determined by an arbitrary
salt value, and the
Why do we need it?
The big advantage of
CREATE2 is that the destination address is not dependent on the exact state (ie. the nonce) of the factory when it’s called. This allows for the result of a transaction to be simulated off-chain, which is an important part of many state channel based approaches to scaling.
So what is everybody so worked up about?
Recalling two things I wrote above:
- Whatever that
init_codereturns will be the code in the new contract.
CREATE2, the address is a function of an arbitrary
saltvalue, and the
So here’s the key detail: if
CREATE2 is run twice in the same factory contract, with the same
salt, and the same
init_code, it will result in a second contract being deployed to the same address as the first contract!
OK, so… then what happens?
If the first contract is still at the address when
CREATE2 tries to put a new contract there, the operation will simply
REVERT; which is fine.
But a few other facts complicate the story:
- Another infamous opcode,
SELFDESTRUCT, is also lurking within the EVM.
- The same
init_codecan return different values at different times.
How could an attacker make use of this?
An example attack that this would enable goes like this:
CREATE2, deploy a safe looking contract.
- Convince some people to deposit their ETH, Tokens, Kittens, etc.
SELFDESTRUCTon that safe looking contract, and it will be removed from state.
CREATE2again, replace it with a malicious contract that sends all the funds to you.
My god that’s horrible
What can we do about it?
Even if a contract was deployed by
CREATE2, the attack would not be possible if it doesn’t contain a
That kind of analysis could technically be run by wallets and block explorers to warn users, but this is quite a burden to place on them.
(Interestingly, Etherscan shows a “reinit” warning on the Ropsten testnet (where
CREATE2 is live), although if you’re seeing that warning it’s already too late. )
Why weren’t people talking about this earlier?
This to me is one of the more interesting things, ie. the pattern of bugs not being found, or possible issues not being discussed until the last minute.
The Constantinople fork was postponed with 48 hours notice before due to a potential vulnerability completely unrelated to
CREATE2. So, this public conversation very easily may not have happened before the change was made permanent.
The ENS launch was the same; two serious bugs were discovered the day of it’s launch.
What should we do to get more attention on these things?
Some advocate bug bounties, which worked recently for Gnosis’ dxDAO. But bounties often see very little activity, and because of the economics, bounty hunters tend to look broadly for easy to find bugs.
In order to ensure the security of protocol changes, both a deep and holistic review is required. The audit being done on ProgPOW is a good start in that direction.
What do I think about
Well… scaling is essential, and state channels are extremely promising, so I want the improvements it brings. But I’m starting to think the side effects are excessively dangerous. A suggestion I find compelling was put forward by Nick Johnson:
I honestly think the simplest solution to all of this would have been to modify self destruct to leave an account’s nonce intact. Selfdestruct is already an ineffective way to encourage freeing state, and this would solve the issues.
Other Good Links
- Poison block explorer byte code: A rather clever attack devised by my teammate Daniel Luca
- New Parity Ethereum update fixes several vulnerabilities: There were some more bugs. Update yer Paritys.
- smartcontractaudits.com: A listing of audit providers
- “Etherelime”: A new debugger
- Modern alternatives to PGP: warning, nothing whatsover to do with blockchains
Want to help make this newsletter better? Join the #maurelians-newsletter channel in the MythXdiscord chat.
This newsletter is supported by ConsenSys Diligence, where I work. We can help with all things smart contract security; auditing, secure development guidance, and training.
Developer — Security Analysis Tools
Frontend and Dapp Engineer, MythX
Marketing and Brand Manager, MythX
Security Engineer and Auditor — Smart Contracts
Senior Technical Recruiter
Smart Contract Security Business Development Lead
Technical Product Manager, MythX