Files
smom-dbis-138/docs/WETH_CREATE2_DEPLOYMENT.md
defiQUG e254f81a83
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m4s
CI/CD Pipeline / Security Scanning (push) Successful in 2m13s
CI/CD Pipeline / Lint and Format (push) Failing after 34s
CI/CD Pipeline / Terraform Validation (push) Failing after 21s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 22s
Validation / validate-genesis (push) Successful in 26s
Validation / validate-terraform (push) Failing after 24s
Validation / validate-kubernetes (push) Failing after 8s
Validation / validate-smart-contracts (push) Failing after 8s
Validation / validate-security (push) Failing after 1m10s
Validation / validate-documentation (push) Failing after 15s
Complete archive manual merge follow-ups and secure relay env handling
Apply clean archive patches (WETH CREATE2 doc, DeployKeeper script),
restore emoney unit tests from .bak, add keeper npm scripts without
replacing the Hardhat package.json, untrack relay lane secret env files,
and document superseded patch hunks in SIBLING_WIP_IMPORT.md.
2026-06-02 06:40:12 -07:00

14 KiB

WETH9 and WETH10 CREATE2 Deployment Guide

Last Updated: 2025-01-27
Network: ChainID 138 (DeFi Oracle Meta Mainnet)

Overview

This guide explains how to deploy WETH9 and WETH10 contracts to the exact addresses specified in genesis.json using CREATE2. Important: These contracts are already pre-deployed in the genesis block with bytecode, so CREATE2 deployment may not be necessary unless you need to update or redeploy them.

Target Addresses

From config/genesis.json:

  • WETH9: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
  • WETH10: 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f

⚠️ Important: Genesis Pre-deployment Status

Both contracts are already pre-deployed in the genesis block with bytecode:

  • WETH9 (0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2): Has bytecode in genesis.json (field: "code")
  • WETH10 (0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f): Has bytecode in genesis.json (field: "code")

This means:

  • Contracts are already available at these addresses when the chain starts
  • No CREATE2 deployment needed unless you want to update/redeploy
  • Contracts can be used immediately after genesis block

When CREATE2 Deployment is Needed

CREATE2 deployment is only necessary if:

  1. You need to update the contract bytecode
  2. The genesis pre-deployment failed or was removed
  3. You're deploying to a different network that doesn't have genesis pre-deployment
  4. You want to verify the contracts match your compiled bytecode

CREATE2 Address Calculation

The CREATE2 address is calculated using:

address = keccak256(0xff ++ deployer ++ salt ++ keccak256(bytecode))[12:]

To deploy to the exact target addresses, we need:

  1. Contract Bytecode: Must match exactly (we compile our contracts)
  2. Deployer Address: Must match the address used when calculating the genesis addresses
  3. Salt: Must match the salt used when calculating the genesis addresses

Deployment Scripts

1. script/DeployWETH9ToExactAddress.s.sol

  • Purpose: Deploy WETH9 to exact address using CREATE2
  • Features:
    • Attempts to find the salt that produces the WETH9 target address
    • Uses CREATE2Factory to deploy
    • Tries common salts first, then brute forces if needed (up to 10,000 iterations)
    • Checks if contract already exists before deploying
    • Tries multiple deployer addresses (current deployer, CREATE2Factory, standard CREATE2 deployer, genesis addresses)
  • Status: Available
  • Location: script/DeployWETH9ToExactAddress.s.sol

2. script/DeployWETH10ToExactAddress.s.sol

  • Purpose: Deploy WETH10 to exact address using CREATE2
  • Features:
    • Attempts to find the salt that produces the WETH10 target address
    • Uses CREATE2Factory to deploy
    • Tries common salts first, then brute forces if needed (up to 10,000 iterations)
    • Checks if contract already exists before deploying
    • Tries multiple deployer addresses
  • Status: Available
  • Location: script/DeployWETH10ToExactAddress.s.sol

3. scripts/deployment/calculate-create2-salt.js

  • Purpose: Node.js utility to calculate CREATE2 salt
  • Features:
    • Can be used to find the salt that produces a target address
    • Supports brute-force search (default: 1,000,000 iterations)
    • Tries common salts first (zero, one, chain ID, contract name hashes)
    • Loads bytecode from Foundry artifacts
  • Status: Available
  • Location: scripts/deployment/calculate-create2-salt.js
  • Usage: node scripts/deployment/calculate-create2-salt.js WETH <deployer-address>

4. scripts/deployment/deploy-weth-create2.sh

  • Purpose: Main automated deployment script
  • Features:
    • Compiles contracts using forge build
    • Checks if contracts already exist at target addresses
    • Deploys WETH9 and WETH10 sequentially
    • Verifies deployments after completion
    • Skips deployment if contracts already exist
  • Status: Available
  • Location: scripts/deployment/deploy-weth-create2.sh

5. script/DeployWETH.s.sol

  • Purpose: Standard WETH deployment (not CREATE2)
  • Features: Deploys WETH to a new address (not to genesis addresses)
  • Status: Available
  • Location: script/DeployWETH.s.sol
  • Note: This deploys to a new address, not the genesis addresses

6. contracts/utils/CREATE2Factory.sol

  • Purpose: Factory contract for CREATE2 deployments
  • Features:
    • deploy(bytes memory bytecode, uint256 salt): Deploy contract using CREATE2
    • computeAddress(bytes memory bytecode, uint256 salt): Compute CREATE2 address
    • computeAddressWithDeployer(address deployer, bytes memory bytecode, uint256 salt): Compute with custom deployer
  • Status: Available
  • Location: contracts/utils/CREATE2Factory.sol

Deployment Process

Prerequisites

  1. Environment Variables (in .env):

    PRIVATE_KEY=0x...
    RPC_URL=http://localhost:8545  # ChainID 138 RPC endpoint
    
  2. Compiled Contracts:

    forge build
    
  3. Verify Genesis Status (Recommended):

    # Check if contracts already exist (they should from genesis)
    cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL
    cast code 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f --rpc-url $RPC_URL
    

Step 1: Verify Current Status

Before deploying, check if contracts already exist:

# Check WETH9
cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL

# Check WETH10
cast code 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f --rpc-url $RPC_URL

# If contracts exist, verify they work
cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 "name()" --rpc-url $RPC_URL
cast call 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f "name()" --rpc-url $RPC_URL

If contracts already exist and work correctly, CREATE2 deployment is NOT needed.

Step 2: Calculate Salt (Optional - Only if Redeploying)

If you need to redeploy and know the deployer address used when creating genesis.json:

# For WETH9
node scripts/deployment/calculate-create2-salt.js WETH <deployer-address>

# For WETH10
node scripts/deployment/calculate-create2-salt.js WETH10 <deployer-address>

Common deployer addresses to try:

  • 0x4e59b44847b379578588920cA78FbF26c0B4956C (Standard CREATE2 deployer)
  • 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb (Genesis address)
  • 0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882 (Genesis address with high balance)

Step 3: Deploy Contracts (Only if Needed)

Option A: Use the automated script

./scripts/deployment/deploy-weth-create2.sh

The script will:

  1. Check if contracts already exist
  2. Skip deployment if they exist
  3. Deploy only if contracts are missing

Option B: Deploy manually using Foundry

# Deploy WETH9
forge script script/DeployWETH9ToExactAddress.s.sol:DeployWETH9ToExactAddress \
    --rpc-url $RPC_URL \
    --broadcast \
    --private-key $PRIVATE_KEY \
    --legacy

# Deploy WETH10
forge script script/DeployWETH10ToExactAddress.s.sol:DeployWETH10ToExactAddress \
    --rpc-url $RPC_URL \
    --broadcast \
    --private-key $PRIVATE_KEY \
    --legacy

Option C: Standard Deployment (New Address)

If you don't need the exact genesis addresses, use standard deployment:

forge script script/DeployWETH.s.sol:DeployWETH \
    --rpc-url $RPC_URL \
    --broadcast \
    --private-key $PRIVATE_KEY

This will deploy to a new address (not the genesis addresses).

Troubleshooting

Issue: Contracts Already Exist (Expected)

If contracts already exist at target addresses:

This is expected and correct! The contracts are pre-deployed in genesis.json.

Verification:

# Check if contracts exist
cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL
cast code 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f --rpc-url $RPC_URL

# Verify functionality
cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 "name()" --rpc-url $RPC_URL
# Should return: "Wrapped Ether"

Action: No deployment needed. Contracts are ready to use.

Issue: Salt not found

If the scripts cannot find a salt that produces the target address:

  1. Check Deployer Address: The deployer address must match the one used when calculating the genesis addresses
  2. Verify Bytecode: Ensure the compiled bytecode matches what was used in genesis.json
    # Compare bytecode
    cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL > deployed-bytecode.txt
    # Check compiled bytecode in out/WETH/WETH.sol/WETH.json
    
  3. Try Different Deployer: If genesis.json used a different deployer, you may need to use that address
  4. Increase Search Range: Modify the brute-force limit in the scripts (currently 10,000 iterations)

Issue: Address mismatch

If the deployed address doesn't match the target:

  1. Verify Salt: Double-check the salt calculation
  2. Check Factory Address: If using CREATE2Factory, ensure the factory address matches
  3. Review Genesis: Confirm the target addresses in genesis.json are correct
  4. Check Bytecode Hash: Ensure the bytecode hash matches what was used in genesis

Issue: Contract deployment fails

If CREATE2 deployment fails:

  1. Check Factory Deployment: Ensure CREATE2Factory is deployed first
  2. Verify Gas: Ensure deployer has sufficient balance for gas
  3. Check Network: Verify you're on ChainID 138
  4. Review Logs: Check deployment logs in /tmp/weth9-deploy.log and /tmp/weth10-deploy.log

Issue: Contract exists but bytecode differs

If contract exists but bytecode doesn't match your compiled version:

  1. This is normal if genesis.json used different bytecode
  2. Verify functionality: Test the contract to ensure it works
  3. If update needed: You'll need to deploy a new version to a different address, or update genesis.json

Alternative Approaches

Approach 1: Use Genesis Pre-deployment (Current Status)

Status: Already Implemented

The contracts are already pre-deployed in config/genesis.json with bytecode in the "code" field. This is the recommended approach for ChainID 138.

Advantages:

  • Contracts available immediately at genesis
  • No deployment transaction needed
  • No gas costs
  • Deterministic addresses

Disadvantages:

  • ⚠️ Bytecode is fixed in genesis (harder to update)
  • ⚠️ Requires genesis file modification for updates

Approach 2: Standard Deployment (New Address)

Deploy contracts to new addresses (not the genesis addresses):

forge script script/DeployWETH.s.sol:DeployWETH \
    --rpc-url $RPC_URL \
    --broadcast \
    --private-key $PRIVATE_KEY

Use when:

  • You don't need the exact genesis addresses
  • You want to deploy updated bytecode
  • You're testing on a different network

Approach 3: CREATE2 Deployment (For Updates)

Use CREATE2 to deploy updated contracts to the same addresses:

Use when:

  • Genesis pre-deployment failed
  • You need to update contract bytecode
  • You want to verify contracts match your compiled version

Approach 4: Use Known CREATE2 Deployer

Use a well-known CREATE2 deployer (like 0x4e59b44847b379578588920cA78FbF26c0B4956C) and calculate the appropriate salt.

Standard CREATE2 Deployer: 0x4e59b44847b379578588920cA78FbF26c0B4956C

Verification

After deployment, verify the contracts:

# Check WETH9
cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL

# Check WETH10
cast code 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f --rpc-url $RPC_URL

# Interact with contracts
cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 "name()" --rpc-url $RPC_URL
cast call 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f "name()" --rpc-url $RPC_URL

Important Notes

  1. Genesis Pre-deployment: Contracts are already pre-deployed in genesis.json. CREATE2 deployment is only needed if you want to update/redeploy.

  2. Gas Costs: CREATE2 deployment with salt finding can be gas-intensive, especially if brute-force is needed (up to 10,000 iterations in scripts).

  3. Deployer Balance: Ensure the deployer account has sufficient balance for deployment (recommended: at least 0.1 ETH).

  4. Network: Make sure you're deploying to the correct network (ChainID 138 - DeFi Oracle Meta Mainnet).

  5. Genesis Alignment: The addresses in genesis.json must match the CREATE2 calculation for deployment to work.

  6. Bytecode Matching: The compiled bytecode must match exactly what was used in genesis.json for CREATE2 to work.

  7. Contract Verification: Always verify contracts exist and work before attempting CREATE2 deployment.

  8. Salt Finding: Finding the correct salt can be time-consuming. The scripts try common salts first, then brute-force up to 10,000 iterations.

Current Deployment Status

Contract Address Genesis Status CREATE2 Needed
WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 Pre-deployed with bytecode Not needed
WETH10 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f Pre-deployed with bytecode Not needed

Recommendation: Verify contracts exist and work correctly. CREATE2 deployment is only needed if contracts are missing or need updates.

  • Genesis Configuration: config/genesis.json
  • WETH9 Contract: contracts/tokens/WETH.sol
  • WETH10 Contract: contracts/tokens/WETH10.sol
  • CREATE2Factory: contracts/utils/CREATE2Factory.sol
  • Deployment Scripts: script/DeployWETH*.s.sol
  • Deployment Scripts: scripts/deployment/deploy-weth-create2.sh
  • Salt Calculator: scripts/deployment/calculate-create2-salt.js

References

Summary

Key Takeaway: WETH9 and WETH10 are already pre-deployed in the genesis block with bytecode. CREATE2 deployment is not required unless you need to update or redeploy the contracts. Always verify contracts exist before attempting deployment.

Quick Start:

  1. Verify contracts exist: cast code <address> --rpc-url $RPC_URL
  2. Test contracts: cast call <address> "name()" --rpc-url $RPC_URL
  3. If contracts work, no deployment needed
  4. ⚠️ Only deploy if contracts are missing or need updates

Last Updated: 2025-01-27