There is a widely known misconception that all contracts are immutable, that their ABIs are firm and we can always rely on the ABI we have to decode the contract logic. We can also trust that the contract is safe for us to interact with as it’s been audited… Well, the truth is far from that, at least for how the EVM stands as of now! There are proposals attempting to alter this behaviour.
I came about this realization whilst trying to create a contract_creations table. More specifically after I realized that there is something called a self_destruct call (here). This specific call destroys* the contract and sends all remaining tokens stored in the contract to a designated address. This is not a problem at all if one could not redeploy bytecode (contract code) on top of the same address, but they actually can! That’s the problem!
https://tenor.com/view/frustrated-ugh-headache-gif-7532429">Frustrated
How can they do that you might ask? Well, it’s because of create2 the more deterministic functionality, allowing developers to re-deploy on top of the same address. But don’t take my word for it, let’s read about it.
CREATE vs CREATE2CREATE a new address is created as such:
new_address = hash(sender, nonce)
sender the wallet address creating the new address.nonce is something that increases with each transaction the sender address does on-chain, so it basically establishes that each address created will be different since sender + nonce combination is unique.bytecode and that it is not deterministic. In the sense that:
0xlead420690000000000000000000000000000000 I would have to compute which sender + nonce would create this, which is a pretty hefty computation if even feasible.CREATE2 a new address is created as such:
new_address = hash(0xFF, sender, salt, bytecode)
sender the wallet address creating the new address.salt is an arbitrary value provided by the sender.bytecode the contract code to be deployed.0xFF is a constant that prevents collisions with CREATE.bytecode using CREATE2 which of course can lead to potential security vulnerabilities.Let’s look at contracts that have been redeployed on the Ethereum mainnet. I will also provide the code one can use on BigQuery to follow along with this investigation.
The following code snippet, when sorted by count_times_created descending yields the following results:

to_address in creation traces designates the new_address that is created.
We can notice a few things from just looking at the top 10 by count_times_created:
to_address is null???
rpc endpoint BigQuery is using does not have a fallback for fetching the new_address in some cases. Or something completely different. I do not believe that this is an EVM flaw, but just to be absolutely certain, let’s verify instead of believe (deep dive below):
null InvestigationWe’ve updated our priors and we have seen that different contracts can be redeployed on top of the same address which is the side-effect or intended effect of the CREATE2 + self_destruct implementations.


To address duplicates with different bytecodes, use the first code snippet found here.