# 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 ` ### 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`): ```bash PRIVATE_KEY=0x... RPC_URL=http://localhost:8545 # ChainID 138 RPC endpoint ``` 2. **Compiled Contracts**: ```bash forge build ``` 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 **Before deploying, check if contracts already exist:** ```bash # 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 node scripts/deployment/calculate-create2-salt.js WETH # For WETH10 node scripts/deployment/calculate-create2-salt.js WETH10 ``` **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** ```bash ./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** ```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 ``` **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). ## 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:** ```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. ### 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 ```bash # 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): ```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: **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: ```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 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` ## 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) - [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
--rpc-url $RPC_URL` 2. ✅ Test contracts: `cast call
"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