2025-12-12 14:57:48 -08:00
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
# Verify contract ownership for all deployed contracts
|
|
|
|
|
|
# This script checks ownership of all deployed contracts across all chains
|
|
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
|
|
cd "$PROJECT_ROOT"
|
2026-03-27 19:02:30 -07:00
|
|
|
|
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
|
|
|
|
|
|
if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then
|
|
|
|
|
|
# shellcheck disable=SC1090
|
|
|
|
|
|
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
|
|
|
|
|
|
load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}"
|
|
|
|
|
|
elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then
|
|
|
|
|
|
set -a
|
|
|
|
|
|
# shellcheck disable=SC1090
|
|
|
|
|
|
source "$PROJECT_ROOT/.env"
|
|
|
|
|
|
set +a
|
|
|
|
|
|
elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then
|
|
|
|
|
|
set -a
|
|
|
|
|
|
# shellcheck disable=SC1090
|
|
|
|
|
|
source "$REPO_ROOT/.env"
|
|
|
|
|
|
set +a
|
|
|
|
|
|
fi
|
2025-12-12 14:57:48 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Get deployer address
|
2026-04-22 14:47:28 -07:00
|
|
|
|
DEPLOYER="$(require_deployer_address || true)"
|
|
|
|
|
|
if [[ -z "$DEPLOYER" ]]; then
|
2025-12-12 14:57:48 -08:00
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=========================================="
|
|
|
|
|
|
echo "Contract Ownership Verification"
|
|
|
|
|
|
echo "=========================================="
|
|
|
|
|
|
echo "Deployer Address: $DEPLOYER"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
# Function to check ownership
|
|
|
|
|
|
check_ownership() {
|
|
|
|
|
|
local chain_name=$1
|
|
|
|
|
|
local rpc_url=$2
|
|
|
|
|
|
local contract_name=$3
|
|
|
|
|
|
local contract_address=$4
|
|
|
|
|
|
|
|
|
|
|
|
echo "Checking $chain_name - $contract_name ($contract_address)..."
|
|
|
|
|
|
|
|
|
|
|
|
# Try different ownership functions
|
|
|
|
|
|
local owner=""
|
|
|
|
|
|
|
|
|
|
|
|
# Try admin() function (for CCIP bridges)
|
|
|
|
|
|
owner=$(cast call "$contract_address" "admin()" --rpc-url "$rpc_url" 2>/dev/null | head -1 || echo "")
|
|
|
|
|
|
if [ -n "$owner" ] && [ "$owner" != "0x" ] && [ "$owner" != "0x0000000000000000000000000000000000000000" ]; then
|
|
|
|
|
|
# Extract address from padded result (remove leading zeros)
|
|
|
|
|
|
owner=$(echo "$owner" | sed 's/^0x000000000000000000000000/0x/' | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
|
owner=$(cast --to-checksum-address "$owner" 2>/dev/null || echo "$owner")
|
|
|
|
|
|
deployer_lower=$(echo "$DEPLOYER" | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
|
owner_lower=$(echo "$owner" | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
|
echo " Admin: $owner"
|
|
|
|
|
|
if [ "$owner_lower" == "$deployer_lower" ]; then
|
|
|
|
|
|
echo " ✅ Ownership verified: Deployer is admin"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo " ⚠️ Admin differs: Expected $DEPLOYER, Got $owner"
|
|
|
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Try owner() function
|
|
|
|
|
|
owner=$(cast call "$contract_address" "owner()" --rpc-url "$rpc_url" 2>/dev/null | head -1 || echo "")
|
|
|
|
|
|
if [ -n "$owner" ] && [ "$owner" != "0x" ] && [ "$owner" != "0x0000000000000000000000000000000000000000" ]; then
|
|
|
|
|
|
owner=$(cast --to-checksum-address "$owner" 2>/dev/null || echo "$owner")
|
|
|
|
|
|
echo " Owner: $owner"
|
|
|
|
|
|
if [ "${owner,,}" == "${DEPLOYER,,}" ]; then
|
|
|
|
|
|
echo " ✅ Ownership verified: Deployer owns contract"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo " ⚠️ Ownership differs: Expected $DEPLOYER"
|
|
|
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Try getOwner() function
|
|
|
|
|
|
owner=$(cast call "$contract_address" "getOwner()" --rpc-url "$rpc_url" 2>/dev/null | head -1 || echo "")
|
|
|
|
|
|
if [ -n "$owner" ] && [ "$owner" != "0x" ] && [ "$owner" != "0x0000000000000000000000000000000000000000" ]; then
|
|
|
|
|
|
owner=$(cast --to-checksum-address "$owner" 2>/dev/null || echo "$owner")
|
|
|
|
|
|
echo " Owner: $owner"
|
|
|
|
|
|
if [ "${owner,,}" == "${DEPLOYER,,}" ]; then
|
|
|
|
|
|
echo " ✅ Ownership verified: Deployer owns contract"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo " ⚠️ Ownership differs: Expected $DEPLOYER"
|
|
|
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Try owner() view function with different signature
|
|
|
|
|
|
owner=$(cast call "$contract_address" "owner()(address)" --rpc-url "$rpc_url" 2>/dev/null | head -1 || echo "")
|
|
|
|
|
|
if [ -n "$owner" ] && [ "$owner" != "0x" ] && [ "$owner" != "0x0000000000000000000000000000000000000000" ]; then
|
|
|
|
|
|
owner=$(cast --to-checksum-address "$owner" 2>/dev/null || echo "$owner")
|
|
|
|
|
|
echo " Owner: $owner"
|
|
|
|
|
|
if [ "${owner,,}" == "${DEPLOYER,,}" ]; then
|
|
|
|
|
|
echo " ✅ Ownership verified: Deployer owns contract"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo " ⚠️ Ownership differs: Expected $DEPLOYER"
|
|
|
|
|
|
fi
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Check if contract has any ownership-related functions
|
|
|
|
|
|
local code=$(cast code "$contract_address" --rpc-url "$rpc_url" 2>/dev/null || echo "")
|
|
|
|
|
|
if [ -z "$code" ] || [ "$code" == "0x" ]; then
|
|
|
|
|
|
echo " ❌ Contract not found or has no code"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo " ℹ️ No owner() function found (may not have ownership)"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Verify all chains
|
|
|
|
|
|
echo "=== BSC ==="
|
|
|
|
|
|
if [ -n "${WETH9_BSC:-}" ] && [ -n "${BSC_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "BSC" "$BSC_RPC_URL" "WETH9" "$WETH9_BSC"
|
|
|
|
|
|
check_ownership "BSC" "$BSC_RPC_URL" "WETH10" "$WETH10_BSC"
|
|
|
|
|
|
check_ownership "BSC" "$BSC_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_BSC"
|
|
|
|
|
|
check_ownership "BSC" "$BSC_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_BSC"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Polygon ==="
|
|
|
|
|
|
if [ -n "${WETH9_POLYGON:-}" ] && [ -n "${POLYGON_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Polygon" "$POLYGON_RPC_URL" "WETH9" "$WETH9_POLYGON"
|
|
|
|
|
|
check_ownership "Polygon" "$POLYGON_RPC_URL" "WETH10" "$WETH10_POLYGON"
|
|
|
|
|
|
check_ownership "Polygon" "$POLYGON_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_POLYGON"
|
|
|
|
|
|
check_ownership "Polygon" "$POLYGON_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_POLYGON"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Avalanche ==="
|
|
|
|
|
|
if [ -n "${WETH9_AVALANCHE:-}" ] && [ -n "${AVALANCHE_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Avalanche" "$AVALANCHE_RPC_URL" "WETH9" "$WETH9_AVALANCHE"
|
|
|
|
|
|
check_ownership "Avalanche" "$AVALANCHE_RPC_URL" "WETH10" "$WETH10_AVALANCHE"
|
|
|
|
|
|
check_ownership "Avalanche" "$AVALANCHE_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_AVALANCHE"
|
|
|
|
|
|
check_ownership "Avalanche" "$AVALANCHE_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_AVALANCHE"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Base ==="
|
|
|
|
|
|
if [ -n "${WETH9_BASE:-}" ] && [ -n "${BASE_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Base" "$BASE_RPC_URL" "WETH9" "$WETH9_BASE"
|
|
|
|
|
|
check_ownership "Base" "$BASE_RPC_URL" "WETH10" "$WETH10_BASE"
|
|
|
|
|
|
check_ownership "Base" "$BASE_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_BASE"
|
|
|
|
|
|
check_ownership "Base" "$BASE_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_BASE"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Arbitrum ==="
|
|
|
|
|
|
if [ -n "${WETH9_ARBITRUM:-}" ] && [ -n "${ARBITRUM_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Arbitrum" "$ARBITRUM_RPC_URL" "WETH9" "$WETH9_ARBITRUM"
|
|
|
|
|
|
check_ownership "Arbitrum" "$ARBITRUM_RPC_URL" "WETH10" "$WETH10_ARBITRUM"
|
|
|
|
|
|
check_ownership "Arbitrum" "$ARBITRUM_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_ARBITRUM"
|
|
|
|
|
|
check_ownership "Arbitrum" "$ARBITRUM_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_ARBITRUM"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Optimism ==="
|
|
|
|
|
|
if [ -n "${WETH9_OPTIMISM:-}" ] && [ -n "${OPTIMISM_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Optimism" "$OPTIMISM_RPC_URL" "WETH9" "$WETH9_OPTIMISM"
|
|
|
|
|
|
check_ownership "Optimism" "$OPTIMISM_RPC_URL" "WETH10" "$WETH10_OPTIMISM"
|
|
|
|
|
|
check_ownership "Optimism" "$OPTIMISM_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_OPTIMISM"
|
|
|
|
|
|
check_ownership "Optimism" "$OPTIMISM_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_OPTIMISM"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=== Ethereum Mainnet ==="
|
|
|
|
|
|
if [ -n "${CCIPWETH9BRIDGE_MAINNET:-}" ] && [ -n "${ETH_MAINNET_RPC_URL:-}" ]; then
|
|
|
|
|
|
check_ownership "Ethereum Mainnet" "$ETH_MAINNET_RPC_URL" "CCIPWETH9Bridge" "$CCIPWETH9BRIDGE_MAINNET"
|
|
|
|
|
|
check_ownership "Ethereum Mainnet" "$ETH_MAINNET_RPC_URL" "CCIPWETH10Bridge" "$CCIPWETH10BRIDGE_MAINNET"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
echo "=========================================="
|
|
|
|
|
|
echo "Ownership Verification Complete"
|
|
|
|
|
|
echo "=========================================="
|