Skip to content

How to verify a CREATE2 contract address

CREATE2 predicts an address from a deployer, salt and init-code hash, but verification still requires chain-specific factory, bytecode, deployment, proxy and ownership evidence.

Updated

For educational purposes only; not investment or security advice. A predicted address, empty account, checksum or factory label does not prove deployment, code, control, ownership or safety.

Direct answer

CREATE2 predicts the address created by a specific deployer contract from a 32-byte salt and the hash of its exact init_code. The protocol formula is address = keccak256(0xff || deployer(20 bytes) || salt(32 bytes) || keccak256(init_code))[12:]: hash an 85-byte preimage and keep the last 20 bytes. The deployer is the factory executing CREATE2, not necessarily the wallet that called the factory.

init_code is creation bytecode plus ABI-encoded constructor arguments; it runs once and produces runtime bytecode. A compiler version, optimizer setting, linked library, metadata, constructor argument or factory entry point can change the hash. Runtime code is an output, not the CREATE2 input. The same address is comparable only with the same deployer, salt, init code, EVM rules and chain state.

A counterfactual address may receive funds before code exists, but it has no verified control logic yet. Prediction is not deployment, ownership, authorization, finality or safety. Verify the factory bytecode and calldata, receipt and events, eth_getCode, nonce, storage, balance, proxy implementation, initializer and owner on the intended chain and block.

How it works

Freeze the chain or domain, fork rules, RPC and block, factory address and runtime hash, raw salt, exact init bytes, constructor encoding, compiler and linked libraries. Recompute the keccak256(init_code) and the 85-byte preimage; normalize ABI padding, endianness, checksum and the last-20-byte extraction.

Then decode the factory call and value. Confirm that the intended factory, entry point, salt domain, constructor, owner and initializer are bound. For a minimal proxy, hash the clone creation bytecode containing the implementation address, not the implementation’s runtime bytecode. For a proxy, separately verify implementation, admin, storage slots and upgrade policy.

EIP-684 makes creation revert when the destination nonce is nonzero or code is nonempty. A failed constructor also leaves no successful deployment. Later SELFDESTRUCT and redeployment assumptions depend on the fork rules; never rely on the old claim that code can always be replaced at will.

Deployment evidence has layers: transaction inclusion and status, emitted events, code and nonce, storage and balances, then safe or finalized chain state. A successful RPC response or predicted checksum cannot replace receipt and state verification. Cross-chain copies of an address can have different code, owners, storage and assets.

Use this workflow:

  1. Pin chain, fork, RPC and block; factory or deployer address and runtime hash; salt bytes; init code, constructor arguments, compiler and linked libraries.
  2. Compute the init-code hash and exact CREATE2 preimage, checking widths, padding, 0xff, the last 20 bytes and checksum.
  3. Decode factory calldata and value; compare predicted address, owner, initializer, proxy target and intended permissions.
  4. Verify receipt, status, events, eth_getCode, nonce, balance and storage on the correct chain; record not-deployed and collision states.
  5. Inspect factory, proxy, implementation, admin, initializer, upgrade and singleton-factory assumptions, including ERC-1167 targets.
  6. Test constructor failure, nonce/code collision, fork-sensitive redeployment, nested factories and chain-domain or replay assumptions.
  7. Before funding or signing, reconcile human and raw amounts; after deployment monitor code hash, owner, implementation, roles, events and finality.

Examples

  • EIP-1014 vector: deployer 0x0000000000000000000000000000000000000000, all-zero salt, init 0x00 yields 0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38.
  • Constructor binding: with deployer and salt fixed, changing one ABI-encoded constructor argument changes keccak256(init_code) and therefore the predicted address; hashing runtime bytecode would verify the wrong object.
  • Collision: if the destination nonce is greater than 0 or its code is nonempty, CREATE2 must revert under EIP-684. A zero-code, zero-nonce, funded address is only counterfactual and remains unverified.
  • Minimal proxy: an ERC-1167 clone address hashes the clone creation bytecode containing the implementation address. Hashing the implementation runtime bytecode instead produces an unrelated prediction.

Risks

  • Wrong factory or deployer is used.
  • Salt width, padding, endian or domain encoding is wrong.
  • Init code is confused with runtime bytecode.
  • Constructor arguments are omitted or misordered.
  • Factory entry point, value or calldata differs.
  • Proxy or delegate target is not the intended implementation.
  • Chain, fork or EVM domain differs.
  • Existing nonce causes a collision.
  • Existing code causes a collision.
  • Obsolete SELFDESTRUCT redeployment assumptions are used.
  • Nested CREATE2 changes the effective deployer.
  • CREATE and CREATE2 formulas are mixed.
  • ERC-1167 implementation target is unchecked.
  • Singleton-factory address or deployment assumptions are unverified.
  • Implementation upgrade or admin control changes behavior.
  • Compiler, metadata, library or source artifact differs.
  • Receipt, mempool, failure and finality states are confused.
  • Checksum or UI poisoning hides a wrong address.
  • Prefunded counterfactual funds have no ownership proof.
  • EIP-7702, replay, gas, denial-of-service or stale monitoring assumptions are wrong.

Common misconceptions

  • “An empty address is safe or owned.” It may have no code or verified controller.
  • “The salt alone determines the address.” Deployer and init-code hash are equally binding.
  • “CREATE2 hashes runtime bytecode.” It hashes creation code including constructor arguments.
  • “The same address on two chains means the same code and control.” Chain state and deployments must be checked independently.
  • “A successful prediction proves deployment and security.” Only receipt, code, state, permissions and finality establish what exists.

Sources

Navigation

Search the wiki...