📈 Get daily crypto insights that make you smarter about your money

Advanced Smart Contract Security: Detecting and Preventing CREATE2 Address Collision Attacks in DAO Governance

The Tornado Cash governance exploit of May 20, 2023, introduced many in the cryptocurrency community to a class of attack that, while known in security research circles, had not been demonstrated at scale in a live governance context. The attacker’s use of CREATE2 deterministic deployment to replace a governance proposal contract at the same address represents a sophisticated technique that demands advanced defensive measures. This tutorial provides a technical deep dive into the CREATE2 address collision attack vector and walks through practical countermeasures that smart contract developers and DAO architects can implement. At the time of writing, Bitcoin trades at approximately $26,750 and Ethereum at $1,805.

The Objective

This tutorial aims to equip experienced smart contract developers with the knowledge and tools to detect, prevent, and mitigate CREATE2-based address collision attacks in governance systems. By the end of this walkthrough, you will understand the mathematical basis for deterministic address generation, how attackers exploit the interaction between CREATE and CREATE2 opcodes, and how to build governance systems that are resilient against this class of attack.

Prerequisites

This tutorial assumes familiarity with Solidity development, the Ethereum Virtual Machine’s contract creation opcodes, and basic DAO governance patterns. You should be comfortable reading Solidity code and understanding concepts like delegatecall, storage layouts, and contract deployment mechanisms. Familiarity with tools like Foundry, Hardhat, or Brownie for testing smart contracts is recommended but not required.

Step-by-Step Walkthrough

Step 1: Understanding Deterministic Address Generation

The Ethereum Virtual Machine supports two opcodes for creating new contracts: CREATE and CREATE2. The address generated by each is calculated differently. For CREATE, the new address is computed as the rightmost 160 bits of the Keccak-256 hash of the sender’s address and their nonce. For CREATE2, the address is computed as the rightmost 160 bits of the Keccak-256 hash of 0xFF, the sender’s address, a user-provided salt, and the contract’s creation bytecode.

The critical insight is that CREATE generates addresses based on the sender and nonce, regardless of the bytecode being deployed. This means if a contract at address X with nonce N deploys a child contract, the child’s address depends only on X and N — not on what code is being deployed. An attacker can exploit this by first deploying a benign contract using a factory, then destroying the factory, redeploying the factory at the same address using CREATE2, and deploying a malicious child contract that resolves to the same address as the original benign contract.

Step 2: Analyzing the Tornado Cash Attack

In the Tornado Cash attack, the attacker deployed a factory contract at address 0x7dc8 using CREATE2. This factory then deployed Proposal 20 at address 0xc503 using CREATE. The proposal appeared legitimate and the community voted for it. After the vote passed, the attacker called a hidden emergencyStop function that executed SELFDESTRUCT on both the proposal and its factory. The attacker then redeployed the factory at the same address 0x7dc8 using CREATE2 with the same sender, salt, and initial factory bytecode. When the redeployed factory used CREATE to deploy a new contract, the sender (0x7dc8) and nonce (1) were identical to the original deployment, so the child contract resolved to the same address 0xc503 — but this time with completely different, malicious code.

The governance contract then called execute on the proposal, which used delegatecall to execute the malicious proposal code in the governance contract’s context, granting the attacker control over the DAO.

Step 3: Implementing Bytecode Verification

The most direct defense against address collision attacks is to verify the bytecode at the proposal address before execution. Implement a governance contract that stores the expected bytecode hash of each proposal at the time it is submitted. Before executing any proposal, the contract verifies that the bytecode currently residing at the proposal address matches the stored hash.

mapping(uint256 => bytes32) public proposalCodeHash;

function submitProposal(address target) external {
    bytes32 codeHash;
    assembly { codeHash := extcodehash(target) }
    proposals[proposalCount] = Proposal({
        target: target,
        codeHash: codeHash
    });
}

function executeProposal(uint256 proposalId) external {
    Proposal storage p = proposals[proposalId];
    bytes32 currentHash;
    assembly { currentHash := extcodehash(p.target) }
    require(currentHash == p.codeHash, "Code hash mismatch");
    // proceed with execution
}

This approach ensures that if an attacker replaces the contract at the proposal address, the bytecode hash will differ and execution will revert.

Step 4: Preventing Self-Destruct in Governance

Since the attack requires the ability to destroy and redeploy contracts, preventing self-destruct functionality in proposal contracts eliminates the attack vector entirely. Use a proxy pattern where governance proposals are deployed behind immutable proxies that cannot be self-destructed. Alternatively, scan submitted proposal bytecode for the SELFDESTRUCT opcode (0xFF at the EVM level) and reject any proposal that contains it.

Step 5: Implementing Execution Delay with Verification

Combine a time lock with automated bytecode verification. After a proposal passes the vote, enforce a minimum delay of 48-72 hours. During this delay period, an automated verification script checks that the proposal contract’s bytecode hash has not changed since the vote began. If any change is detected, the proposal is automatically cancelled and an alert is raised.

Troubleshooting

Issue: Bytecode hash check fails for legitimate proposals. Some governance patterns involve proposals that legitimately modify their own code, such as upgradeable contracts. In these cases, implement a whitelist of approved code transition patterns that the verification system will accept, rather than requiring an exact hash match at execution time.

Issue: Gas costs for bytecode verification are too high. The extcodehash operation is relatively cheap at 700 gas, but if your governance system processes many proposals, consider batch verification where all pending proposals are verified in a single transaction before the execution window opens.

Issue: CREATE2 is needed for legitimate purposes. Some protocols use CREATE2 for predictable address generation in factory patterns. This is fine — the vulnerability is not CREATE2 itself but the combination of self-destruct and redeployment. Focus on preventing the self-destruct step rather than banning CREATE2 entirely.

Mastering the Skill

To deepen your understanding of governance security, study the OpenZeppelin Governor framework, which implements many of the protective patterns discussed in this tutorial. Practice deploying and attacking a vulnerable governance contract in a local test environment using Foundry. Review the audit reports from major DeFi protocols — many publicly disclose governance-related findings that provide real-world learning material. The Ethereum security community maintains resources at ethereum.org/en/developers/docs/security that cover additional attack vectors beyond CREATE2 collisions. As governance systems continue to manage increasingly large treasuries, the developers who master these defensive techniques will be in high demand across the Web3 ecosystem.

Disclaimer: This article is for informational purposes only and does not constitute financial or investment advice. Always conduct your own research before making any financial decisions.

🌱 FOR BUSINESSES BitcoinsNews.com
Reach 100K+ Crypto Readers
Sponsored content, press releases, banner ads, and newsletter placements. Put your brand in front of Bitcoin's most engaged audience.

9 thoughts on “Advanced Smart Contract Security: Detecting and Preventing CREATE2 Address Collision Attacks in DAO Governance”

  1. the CREATE2 collision trick is genuinely clever from an exploit perspective. deploying a benign contract, self-destructing it, then redeploying malicious code at the same address. brutal

    1. clever is one word for it. the EVM allowing self-destruct + CREATE2 at the same address is the real bug here, not the attacker

      1. the EVM allowing selfdestruct + CREATE2 at the same address is a design flaw not a feature. this was documented in 2017 and nobody fixed it

        1. EIP-6780 in the dendrum upgrade basically killed selfdestruct. the attack vector described here is now patched at the protocol level. important writeup but mostly historical now

    2. tornado cash governance was the wake up call. deploy benign, self destruct, redeploy malicious at the same address. elegant and terrifying

  2. been waiting for someone to write this up properly. the math behind deterministic address generation gets handwaved in most blog posts. glad to see the full breakdown

    1. agreed. most coverage just says governance attack without explaining the CREATE vs CREATE2 opcode interaction. this actually explains the mechanism

      1. Chen is right. most coverage just says governance attack and moves on. the actual CREATE vs CREATE2 interaction is worth understanding if you build on evm

  3. this attack influenced every DAO security audit since mid 2023. the pattern of deploy benign, selfdestruct, redeploy malicious is now a standard checklist item for auditors. valuable reference even post-EIP-6780

Leave a Comment

Your email address will not be published. Required fields are marked *

BTC$66,610.00+4.5%ETH$1,823.11+9.5%SOL$75.15+11.3%BNB$620.48+2.9%XRP$1.27+12.3%ADA$0.1859+12.0%DOGE$0.0889+3.0%DOT$1.02+7.2%AVAX$6.90+7.4%LINK$8.41+7.6%UNI$2.68+8.3%ATOM$1.96-1.0%LTC$45.61+3.3%ARB$0.0872+6.1%NEAR$2.48+18.1%FIL$0.8017+5.7%SUI$0.8011+6.9%BTC$66,610.00+4.5%ETH$1,823.11+9.5%SOL$75.15+11.3%BNB$620.48+2.9%XRP$1.27+12.3%ADA$0.1859+12.0%DOGE$0.0889+3.0%DOT$1.02+7.2%AVAX$6.90+7.4%LINK$8.41+7.6%UNI$2.68+8.3%ATOM$1.96-1.0%LTC$45.61+3.3%ARB$0.0872+6.1%NEAR$2.48+18.1%FIL$0.8017+5.7%SUI$0.8011+6.9%
Scroll to Top