Skip to content
On this page

S2C10: CREATE2 Double Constraint

1. Problem

It is necessary to deploy a contract whose address must simultaneously satisfy two constraint conditions (such as address prefix matching certain bytes). Use CREATE2 salt grinding to find the right salt.

2. Cause

The contract uses address constraints as access control — only functions called from specific addresses can execute. Through CREATE2's deterministic deployment, the attacker can "choose" the deployment address.

3. Solution

  1. Analyze the address constraint conditions in the contract (which bytes must match)
  2. Write the attack contract
  3. Use salt grinding to find a salt satisfying both constraints
  4. Deploy the attack contract to the target address
  5. Call mintFlag from that address
solidity
// Salt grinding in Foundry
function findSalt() external {
    bytes32 salt = 0;
    while (true) {
        address predicted = address(uint160(uint256(
            keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initCodeHash))
        )));
        if (checkConstraint1(predicted) && checkConstraint2(predicted)) {
            break; // Found!
        }
        salt = bytes32(uint256(salt) + 1);
    }
}

4. Pitfalls Encountered

Double constraint grinding time: When two constraint conditions are combined, the search space can be large. Efficient computation methods are required.

5. Pitfall Causes

Each additional byte constraint shrinks the search space by a factor of 256. Two constraints combined mean a 256^2 = 65536 times larger search space (worst case).

6. How to Resolve

Use a Rust script or optimized Foundry test for grinding. For 2-3 byte constraint combinations, it can typically be found within < 10 million iterations.

7. Key Technical Points

PointDescription
CREATE2 address calculationLast 20 bytes of keccak256(0xff + deployer + salt + keccak256(initCode))
Multi-constraint grindingCombining multiple address match conditions increases search complexity
initCode hashSame contract code produces the same hash; varying initCode (e.g., constructor parameters) changes the address

Built with AiAda