#!/usr/bin/env bash # Verify CCIPWETH9Bridge contract on Etherscan # Usage: ./verify-contract-etherscan.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SOURCE_PROJECT="/home/intlc/projects/smom-dbis-138" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Load environment if [ -f "$SOURCE_PROJECT/.env" ]; then source "$SOURCE_PROJECT/.env" else log_error ".env file not found in $SOURCE_PROJECT" exit 1 fi # Contract details CONTRACT="0x89dd12025bfCD38A168455A44B400e913ED33BE2" CONTRACT_NAME="CCIPWETH9Bridge" CONTRACT_PATH="contracts/ccip/CCIPWETH9Bridge.sol" # Check if contract exists on Ethereum Mainnet MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-}" if [ -z "$MAINNET_RPC" ]; then log_error "ETHEREUM_MAINNET_RPC not set in .env" exit 1 fi log_info "=== Verifying Contract on Etherscan ===" log_info "" log_info "Contract: $CONTRACT" log_info "Name: $CONTRACT_NAME" log_info "" # Check if contract exists log_info "1. Checking if contract exists on Ethereum Mainnet..." CODE=$(cast code "$CONTRACT" --rpc-url "$MAINNET_RPC" 2>/dev/null || echo "") if [ -z "$CODE" ] || [ "$CODE" = "0x" ]; then log_error "Contract not found on Ethereum Mainnet at $CONTRACT" exit 1 fi log_success "Contract exists on Ethereum Mainnet" # Get constructor arguments from Chain 138 log_info "" log_info "2. Getting constructor arguments from Chain 138 contract..." RPC_URL_138="${RPC_URL_138:-http://192.168.11.250:8545}" # Get full addresses (cast returns padded addresses) CCIP_ROUTER_RAW=$(cast call "$CONTRACT" "ccipRouter()" --rpc-url "$RPC_URL_138" 2>/dev/null || echo "") WETH9_RAW=$(cast call "$CONTRACT" "weth9()" --rpc-url "$RPC_URL_138" 2>/dev/null || echo "") FEE_TOKEN_RAW=$(cast call "$CONTRACT" "feeToken()" --rpc-url "$RPC_URL_138" 2>/dev/null || echo "") # Extract addresses (last 40 hex chars) CCIP_ROUTER=$(echo "$CCIP_ROUTER_RAW" | grep -oE "0x[a-fA-F0-9]{40}" | tail -1 || echo "$CCIP_ROUTER_RAW" | sed 's/0x//' | tail -c 41 | sed 's/^/0x/') WETH9=$(echo "$WETH9_RAW" | grep -oE "0x[a-fA-F0-9]{40}" | tail -1 || echo "$WETH9_RAW" | sed 's/0x//' | tail -c 41 | sed 's/^/0x/') FEE_TOKEN=$(echo "$FEE_TOKEN_RAW" | grep -oE "0x[a-fA-F0-9]{40}" | tail -1 || echo "$FEE_TOKEN_RAW" | sed 's/0x//' | tail -c 41 | sed 's/^/0x/') # If extraction failed, try alternative method if [ ${#CCIP_ROUTER} -lt 42 ] || [ ${#WETH9} -lt 42 ] || [ ${#FEE_TOKEN} -lt 42 ]; then log_warn "Could not extract full addresses, trying alternative method..." # Use known addresses from deployment CCIP_ROUTER="0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D" WETH9="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" FEE_TOKEN="0x514910771AF9Ca656af840dff83E8264EcF986CA" log_info "Using known deployment addresses" fi log_info " CCIP Router: $CCIP_ROUTER" log_info " WETH9: $WETH9" log_info " Fee Token: $FEE_TOKEN" # Compiler settings log_info "" log_info "3. Compiler settings:" log_info " Solidity: 0.8.20" log_info " Optimizer: Enabled (runs: 200)" log_info " Via IR: false (Etherscan may not support via-ir)" # Verify contract log_info "" log_info "4. Verifying contract on Etherscan..." cd "$SOURCE_PROJECT" # Check if Etherscan API key is set if [ -z "${ETHERSCAN_API_KEY:-}" ]; then log_error "ETHERSCAN_API_KEY not set in .env" exit 1 fi # Verify using forge log_info "Running forge verify-contract..." # Encode constructor arguments CONSTRUCTOR_ARGS=$(cast abi-encode "constructor(address,address,address)" "$CCIP_ROUTER" "$WETH9" "$FEE_TOKEN") log_info " Constructor args: $CONSTRUCTOR_ARGS" # Try verification without via-ir first (Etherscan may not support it) log_info "Attempting verification (without via-ir flag - Etherscan handles this)..." if forge verify-contract \ "$CONTRACT" \ "$CONTRACT_PATH:$CONTRACT_NAME" \ --chain-id 1 \ --etherscan-api-key "$ETHERSCAN_API_KEY" \ --constructor-args "$CONSTRUCTOR_ARGS" \ --compiler-version "0.8.20" \ --num-of-optimizations 200 \ --watch; then log_success "✓ Contract verified successfully!" log_info "" log_info "View on Etherscan:" log_info " https://etherscan.io/address/$CONTRACT#code" else log_error "Contract verification failed" log_info "" log_info "Troubleshooting:" log_info " 1. Check constructor arguments match deployment" log_info " 2. Verify compiler settings (0.8.20, optimizer: 200, via-ir: true)" log_info " 3. Ensure contract source matches deployed bytecode" exit 1 fi