2025-12-12 14:57:48 -08:00
# WETH9 and WETH10 CREATE2 Deployment Guide
2026-06-02 06:40:12 -07:00
**Last Updated**: 2025-01-27
**Network**: ChainID 138 (DeFi Oracle Meta Mainnet)
2025-12-12 14:57:48 -08:00
## Overview
2026-06-02 06:40:12 -07:00
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.
2025-12-12 14:57:48 -08:00
## Target Addresses
2026-06-02 06:40:12 -07:00
From `config/genesis.json` :
2025-12-12 14:57:48 -08:00
- **WETH9**: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`
- **WETH10**: `0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f`
2026-06-02 06:40:12 -07:00
## ⚠️ 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
2025-12-12 14:57:48 -08:00
## 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`
2026-06-02 06:40:12 -07:00
- **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`
2025-12-12 14:57:48 -08:00
### 2. `script/DeployWETH10ToExactAddress.s.sol`
2026-06-02 06:40:12 -07:00
- **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`
2025-12-12 14:57:48 -08:00
### 3. `scripts/deployment/calculate-create2-salt.js`
2026-06-02 06:40:12 -07:00
- **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>`
2025-12-12 14:57:48 -08:00
### 4. `scripts/deployment/deploy-weth-create2.sh`
2026-06-02 06:40:12 -07:00
- **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`
2025-12-12 14:57:48 -08:00
## Deployment Process
### Prerequisites
1. **Environment Variables ** (in `.env` ):
```bash
PRIVATE_KEY=0x...
2026-06-02 06:40:12 -07:00
RPC_URL=http://localhost:8545 # ChainID 138 RPC endpoint
2025-12-12 14:57:48 -08:00
```
2. **Compiled Contracts ** :
```bash
forge build
```
2026-06-02 06:40:12 -07:00
3. **Verify Genesis Status ** (Recommended):
```bash
# 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
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
**Before deploying, check if contracts already exist:**
2025-12-12 14:57:48 -08:00
```bash
2026-06-02 06:40:12 -07:00
# 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:
```bash
# For WETH9
2025-12-12 14:57:48 -08:00
node scripts/deployment/calculate-create2-salt.js WETH <deployer-address>
2026-06-02 06:40:12 -07:00
# For WETH10
2025-12-12 14:57:48 -08:00
node scripts/deployment/calculate-create2-salt.js WETH10 <deployer-address>
```
2026-06-02 06:40:12 -07:00
**Common deployer addresses to try:**
- `0x4e59b44847b379578588920cA78FbF26c0B4956C` (Standard CREATE2 deployer)
- `0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb` (Genesis address)
- `0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882` (Genesis address with high balance)
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
### Step 3: Deploy Contracts (Only if Needed)
2025-12-12 14:57:48 -08:00
**Option A: Use the automated script**
```bash
./scripts/deployment/deploy-weth-create2.sh
```
2026-06-02 06:40:12 -07:00
The script will:
1. Check if contracts already exist
2. Skip deployment if they exist
3. Deploy only if contracts are missing
2025-12-12 14:57:48 -08:00
**Option B: Deploy manually using Foundry**
```bash
# 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
```
2026-06-02 06:40:12 -07:00
**Option C: Standard Deployment (New Address)**
If you don't need the exact genesis addresses, use standard deployment:
```bash
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).
2025-12-12 14:57:48 -08:00
## Troubleshooting
2026-06-02 06:40:12 -07:00
### 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:**
```bash
# 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.
2025-12-12 14:57:48 -08:00
### 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
2026-06-02 06:40:12 -07:00
```bash
# Compare bytecode
cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url $RPC_URL > deployed-bytecode.txt
# Check compiled bytecode in out/WETH/WETH.sol/WETH.json
```
2025-12-12 14:57:48 -08:00
3. **Try Different Deployer ** : If genesis.json used a different deployer, you may need to use that address
2026-06-02 06:40:12 -07:00
4. **Increase Search Range ** : Modify the brute-force limit in the scripts (currently 10,000 iterations)
2025-12-12 14:57:48 -08:00
### 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
2026-06-02 06:40:12 -07:00
4. **Check Bytecode Hash ** : Ensure the bytecode hash matches what was used in genesis
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
### Issue: Contract deployment fails
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
If CREATE2 deployment fails:
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
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
2025-12-12 14:57:48 -08:00
## Alternative Approaches
2026-06-02 06:40:12 -07:00
### Approach 1: Use Genesis Pre-deployment (Current Status) ✅
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
**Status**: ✅ **Already Implemented **
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
The contracts are already pre-deployed in `config/genesis.json` with bytecode in the `"code"` field. This is the recommended approach for ChainID 138.
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
**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):
```bash
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:
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
**Use when**:
- Genesis pre-deployment failed
- You need to update contract bytecode
- You want to verify contracts match your compiled version
2025-12-12 14:57:48 -08:00
2026-06-02 06:40:12 -07:00
### Approach 4: Use Known CREATE2 Deployer
Use a well-known CREATE2 deployer (like `0x4e59b44847b379578588920cA78FbF26c0B4956C` ) and calculate the appropriate salt.
**Standard CREATE2 Deployer**: `0x4e59b44847b379578588920cA78FbF26c0B4956C`
2025-12-12 14:57:48 -08:00
## Verification
After deployment, verify the contracts:
```bash
# 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
2026-06-02 06:40:12 -07:00
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.
## Related Files
- **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`
2025-12-12 14:57:48 -08:00
## References
- [EIP-1014: CREATE2 ](https://eips.ethereum.org/EIPS/eip-1014 )
- [Foundry CREATE2 Guide ](https://getfoundry.sh/guides/deterministic-deployments-using-create2 )
- [Alchemy CREATE2 Guide ](https://www.alchemy.com/docs/create2-an-alternative-to-deriving-contract-addresses )
2026-06-02 06:40:12 -07:00
- [Genesis File Documentation ](https://besu.hyperledger.org/en/stable/private-networks/how-to/configure/genesis-file/ )
## 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
2025-12-12 14:57:48 -08:00