#!/usr/bin/env bash # Calculate CREATE2 deployment parameters given target address and bytecode # This script uses Python to reverse-calculate or find the salt/deployer combination set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" # Load environment source .env 2>/dev/null || true TARGET_WETH9="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" TARGET_WETH10="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F" # Standard CREATE2 deployer CREATE2_DEPLOYER="0x4e59b44847b379578588920cA78FbF26c0B4956C" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "🔍 Calculate CREATE2 Parameters" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" # Check if contracts are compiled if [ ! -d "out/WETH.sol" ] || [ ! -d "out/WETH10.sol" ]; then echo "📦 Compiling contracts..." forge build --force > /dev/null 2>&1 fi echo "📋 Target Addresses:" echo " WETH9: $TARGET_WETH9" echo " WETH10: $TARGET_WETH10" echo "" echo "🔍 Calculating CREATE2 parameters..." echo "" echo "Since CREATE2 is a one-way function, we need to:" echo " 1. Try common deployers (standard CREATE2 deployer, genesis addresses)" echo " 2. Try common salts (0, 1, chain ID, contract name, etc.)" echo " 3. Calculate forward and see if we get the target address" echo "" python3 << 'EOF' import json import hashlib from eth_utils import to_checksum_address, keccak, encode_hex # Target addresses TARGET_WETH9 = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" TARGET_WETH10 = "0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9F" # Known deployers to try DEPLOYERS = [ "0x4e59b44847b379578588920cA78FbF26c0B4956C", # Standard CREATE2 deployer "0x0742D35CC6634c0532925A3b844bc9E7595f0Beb", # Genesis address "0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882", # Genesis address ] def calculate_create2_address(deployer, salt, bytecode_hash): """Calculate CREATE2 address: keccak256(0xff ++ deployer ++ salt ++ bytecode_hash)[12:]""" deployer_bytes = bytes.fromhex(deployer[2:]) if isinstance(salt, int): salt_bytes = salt.to_bytes(32, 'big') else: salt_bytes = bytes.fromhex(salt[2:]) if salt.startswith('0x') else salt.encode() if isinstance(bytecode_hash, str): bytecode_hash_bytes = bytes.fromhex(bytecode_hash[2:] if bytecode_hash.startswith('0x') else bytecode_hash) else: bytecode_hash_bytes = bytecode_hash data = b'\xff' + deployer_bytes + salt_bytes + bytecode_hash_bytes hash_result = keccak(data) address = '0x' + hash_result.hex()[-40:] return to_checksum_address(address) def load_bytecode_hash(contract_name): """Load bytecode hash from compiled artifacts""" import os artifacts_path = f"out/{contract_name}.sol/{contract_name}.json" if not os.path.exists(artifacts_path): # Try alternative path artifacts_path = f"out/{contract_name}/{contract_name}.sol/{contract_name}.json" if os.path.exists(artifacts_path): with open(artifacts_path, 'r') as f: artifact = json.load(f) bytecode = artifact.get('bytecode', {}).get('object', '') if bytecode: # Calculate hash of bytecode bytecode_bytes = bytes.fromhex(bytecode[2:]) return keccak(bytecode_bytes) return None def find_salt_for_target(target_address, contract_name, deployers): """Try to find salt that produces target address""" print(f"\n🔍 Finding salt for {contract_name} at {target_address}...") bytecode_hash = load_bytecode_hash(contract_name) if not bytecode_hash: print(f" ⚠️ Could not load bytecode for {contract_name}") return None, None print(f" 📦 Bytecode hash: {encode_hex(bytecode_hash)}") # Common salts to try common_salts = [ (0, "Zero"), (1, "One"), (138, "Chain ID"), ("WETH9" if "WETH" in contract_name else "WETH10", "Contract name"), ("WETH", "WETH"), ("Wrapped Ether", "Full name"), ] # Add keccak hashes of strings import hashlib for i in range(10): salt_str = f"{contract_name}{i}" salt_bytes = hashlib.sha3_256(salt_str.encode()).digest() salt_int = int.from_bytes(salt_bytes, 'big') common_salts.append((salt_int, f"Keccak256('{salt_str}')")) for deployer in deployers: print(f"\n 🎯 Trying deployer: {deployer}") # Try common salts for salt_value, salt_desc in common_salts: try: if isinstance(salt_value, int): salt_bytes = salt_value.to_bytes(32, 'big') else: salt_bytes = hashlib.sha3_256(salt_value.encode()).digest() computed = calculate_create2_address(deployer, salt_bytes, bytecode_hash) if computed.lower() == target_address.lower(): print(f" ✅ FOUND! Salt: {salt_desc} = {salt_value}") print(f" Deployer: {deployer}") print(f" Computed: {computed}") return deployer, salt_bytes.hex() except Exception as e: continue # Try sequential salts (first 1000) print(f" 🔍 Brute-forcing first 1000 sequential salts...") for i in range(1000): salt_bytes = i.to_bytes(32, 'big') try: computed = calculate_create2_address(deployer, salt_bytes, bytecode_hash) if computed.lower() == target_address.lower(): print(f" ✅ FOUND! Salt: {i}") print(f" Deployer: {deployer}") print(f" Computed: {computed}") return deployer, salt_bytes.hex() except: continue if i % 100 == 0 and i > 0: print(f" Checked {i} salts...", end='\r') print(f" Checked 1000 salts - not found") return None, None # Find parameters for WETH9 deployer9, salt9 = find_salt_for_target(TARGET_WETH9, "WETH", DEPLOYERS) if deployer9 and salt9: print(f"\n✅ WETH9 Parameters Found:") print(f" Deployer: {deployer9}") print(f" Salt: 0x{salt9}") print(f" Use these in your deployment script!") else: print(f"\n❌ Could not find WETH9 parameters") print(f" You may need to:") print(f" 1. Check if a different deployer was used") print(f" 2. Try more salt values") print(f" 3. Verify the bytecode matches what was used in genesis.json") # Find parameters for WETH10 print("\n" + "="*60) deployer10, salt10 = find_salt_for_target(TARGET_WETH10, "WETH10", DEPLOYERS) if deployer10 and salt10: print(f"\n✅ WETH10 Parameters Found:") print(f" Deployer: {deployer10}") print(f" Salt: 0x{salt10}") print(f" Use these in your deployment script!") else: print(f"\n❌ Could not find WETH10 parameters") print(f" You may need to:") print(f" 1. Check if a different deployer was used") print(f" 2. Try more salt values") print(f" 3. Verify the bytecode matches what was used in genesis.json") EOF echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "✅ Calculation Complete" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" echo "💡 Note: If parameters were found, use them with vm.startPrank" echo " or vm.startBroadcast to impersonate the deployer address." echo ""