Potential security implications of CREATE2? (EIP-1014)

How is the audit of any contract that can be changed at-will useful?

An audit can tell you if a contract can have its code changed, who can change the code, how they can change it, and what the code can be changed to.

Contracts being able to have their code change has always been possible, and this just provides a new way to do it.

Can you link me your explanation? I cannot find it. I would like to see a real world scenario where somehow you cannot prove that redeployments are not possible.

Can you explain this a little better? I was under the impression that CREATE2 was the opcode to redeploy a contract at a specific address with “upgraded code”. If you cannot have any code changed, the all CREATE2 is good for is redeploying the same smart contract to the same address … ?
Thanks in advance!

create2 contracts can also have their code changed, if the init code permits it.

Yes, you can safely interact with a CREATE2 contract, you just need to validate some new things:

  • Prove that there is no way to destroy the contract, then nothing is different from an audit with a CREATEd contract
  • OR, prove that the init code always produces the exact same bytecode. This should be possible for many/most “honest” use cases. You still need to determine if “zombie contracts” are a problem in your scenario (where the same contract pops up after it has been destroyed).
1 Like

This is like talking to a brick wall.

“Prove that there is no way to destroy the contract” What if that’s not true?

“OR, prove that the init code always produces the exact same bytecode.” What if that’s not true either?

“This should be possible for many/most “honest” use cases.” WTF? We’re not talking about “honest” use cases, we’re talking about people pulling a fast one, which this makes 1000x more likely.

This is full-blown Twilight Zone territory.

Gladly. It goes like this:

  • Company XYZ: Announcing the $50MM Ethereum killer app!

  • Ethereum community: Killer App! But wait a tick; you forgot to guard against CREATE2 exploits

  • Company XYZ: Ah, shoot, you’re right. Well, it would be cost prohibitive to redo it now; You’ll just have to trust us

  • Ethereum community: Okie dokie, then.

  • (months or years pass)

  • Company XYZ: Ooops! Turns out I was a scoundrel. Contract replaced. Money stolen, or whatever I want.

Eliminating the double negatives, you want me to prove redeployments are possible? Your very own CREATE2 does that, friend.

OK, I’m going to stop beating this dead horse because it’s getting me nowhere. I’ll just reiterate this:

People don’t trust the network because they verified some bytecode. That is not how the real world works. People trust the network because a lot of horrible shit that could’ve happened didn’t. That’s it.

This is inviting another DAO-like disaster. You really think we’ll get away with it twice?

I’ve gone ahead and implemented a factory contract for creating what I’m calling metamorphic contracts, or contracts that can be redeployed with new bytecode to the same address. It does so by first deploying an implementation contract, then deploying a transient contract with fixed, non-deterministic initialization code via CREATE2. The transient contract clones the bytecode of the implementation contract and uses it to deploy the metamorphic contract via CREATE, then immediately self-destructs. There’s also an immutable create2 factory contract for preventing metamorphism in any contracts it deploys, which operates similarly to the one by @jochem-brouwer, but with a different mechanism for preventing address collisions / frontrunning.

Use this feature / bug responsibly, try to educate as many people as possible, and stay vigilant against mutable villainy!

3 Likes

Revised the metamorphic contract factory so that it no longer requires an intermediate transient contract. Here’s an explanation of the current initialization code used to deploy the metamorphic contracts: https://gist.github.com/0age/9a4541cce380a1b2c7e477af06ba6376

Here’s another use-case for metamorphic contracts: you can use their runtime code as dynamic storage to save gas in certain applications https://medium.com/coinmonks/on-efficient-ethereum-storage-c76869591add

I’ve updated my own written material about EIP-1014 to reflect Rajeev’s (and this thread’s) concerns about the proposal. https://blog.cotten.io/ethereums-eip-1014-create-2-d17b1a184498

Until I read this thread I had not realized how trivial EIP-1014 made it to create mutable contracts, but can now fully grasp the attack vectors described and the danger of doing this. I strongly agree with those who say we can’t rely on external block explorers for safety: this is an on-chain problem.

pereztechseattle This is inviting another DAO-like disaster. You really think we’ll get away with it twice?

Unfortunately right now we will have to rely on external block explorers to perform this function. Given the apparent severity of potential issues with Create2, there have not been any reported problems.

Bleh. Does an EIP not exist for determining whether an address contains a contract or not? I’ve seen the code relying on EXTCODESIZE but as has been pointed out can be hacked when being checked within a constructor (https://ethereum.stackexchange.com/questions/15641/how-does-a-contract-find-out-if-another-address-is-a-contract/64340#64340).

It’d be nice to have an OPCODE that can definitely state: Account, Contract (CREATE), Contract (CREATE2).

I’m not aware of such an EIP, although I can’t keep up with the number of them being created.

Following along with https://medium.com/coinmonks/why-create2-e99b6afcc28c there’s some really interesting work about the ability to replicate the utility of CREATE2 with standard CREATE.

That’s very interesting, but will only be of use if there is general consensus that CREATE2 should not be used, or if somehow CREATE2 is removed again.

I just released an article on another application for redeployable contracts - using them to create a wallet contract, or “home address”, that supports repeated deployment of arbitrary “transaction scripts” (and a utility for working with home addresses called HomeWork): https://medium.com/@0age/on-efficient-ethereum-transactions-introducing-homework-6ae4f21801ed

How to generate different contract bytecode in the same address? if the address is the same, so the init_code must be the same, and then the bytecode is the same(without using delegatecall and so on), so can you give a solidity example to generate different contract bytecode in the same address JUST using create2 ? it confuses me a lot of time. anyone can help me ? thank you very much !

How to generate different contract bytecode in the same address? if the address is the same, so the init_code must be the same, and then the bytecode is the same(without using delegatecall and so on), so can you give a solidity example to generate different contract bytecode in the same address JUST using create2 ? it confuses me a lot of time. anyone can help me ? thank you very much !