#!/usr/bin/env bash # After a singleton (EIP-2470) deploy tx, verify the **predicted** address — not the signer. # 1) Non-empty runtime code on RPC (default: 2103 Thirdweb admin) # 2) Optional: owner() if the contract implements it (otherwise note proxy/custom initcode) # # Usage: RPC_URL_2103=... ./scripts/verify/verify-singleton-post-deploy-2103.sh 0xPredictedAddr # Optional: DEPLOY_TX_SIGNER=0x... (display only: gas payer need not be admin/owner in Thirdweb/AA) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # shellcheck disable=SC1091 source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" 2>/dev/null || true ADDR="${1:-}" RPC_2103="${RPC_URL_2103:-http://192.168.11.217:8545}" if [[ ! "$ADDR" =~ ^0x[0-9a-fA-F]{40}$ ]]; then echo "Usage: $0 0xPredictedContractAddress" >&2 exit 2 fi if ! command -v cast &>/dev/null; then echo "ERROR: cast not in PATH" >&2 exit 1 fi code=$(cast code -r "$RPC_2103" "$ADDR" 2>/dev/null || true) if [[ -z "$code" || "$code" == "0x" || "$code" == "0x0" ]]; then echo "FAIL: no runtime code at $ADDR on $RPC_2103 (not deployed or wrong chain/RPC)" >&2 exit 1 fi blen=$(((${#code} - 2) / 2)) echo "OK: code at $ADDR: $blen byte(s) on 2103" # Optional: compare signer to owner — informational only if [[ -n "${DEPLOY_TX_SIGNER:-}" && "$DEPLOY_TX_SIGNER" =~ ^0x[0-9a-fA-F]{40}$ ]]; then echo " (tx signer: $DEPLOY_TX_SIGNER — not necessarily the contract admin/owner in Thirdweb/AA initcode.)" fi # Prefer typed return; fall back to plain "owner()" o1="$(cast call -r "$RPC_2103" "$ADDR" "owner()(address)" 2>/dev/null | tr -d ' \n\r' || true)" o2="$(cast call -r "$RPC_2103" "$ADDR" "owner()" 2>/dev/null | tr -d ' \n\r' || true)" if [[ -n "$o1" && "$o1" == 0x* && ${#o1} -ge 42 ]]; then own="$o1" else own="$o2" fi if [[ -n "$own" && "$own" == 0x* && ${#own} -ge 42 ]]; then echo "owner() -> $own" echo " Compare to your intended admin; the deployer/signer and owner() are independent here." else echo "owner() n/a (revert) — verify admin via Blockscout, proxy storage, or initcode/roles; do not assume signer == owner" fi exit 0