|
| 1 | +#!/bin/bash |
| 2 | +# Runs RoleMigration.s.sol on every chain that has a LayerZeroReceiver, EnsoCCIPReceiver, |
| 3 | +# or flashloan adapter deployment recorded under broadcast/. Only the most recent |
| 4 | +# deployment per chain (run-latest.json) is targeted — older superseded deployments |
| 5 | +# are ignored. |
| 6 | +# |
| 7 | +# Dry-run (simulation only) by default. Pass "broadcast" to send transactions. |
| 8 | +# |
| 9 | +# New owners are hardcoded per chain in RoleMigration.s.sol (_newOwnerFor). |
| 10 | +# |
| 11 | +# Required env (.env is sourced): PRIVATE_KEY (deployer key) and the per-chain |
| 12 | +# *_RPC_URL vars. Chains with an unset RPC var are skipped. |
| 13 | +# |
| 14 | +# e.g. migrate-roles.sh # simulate everywhere |
| 15 | +# migrate-roles.sh broadcast # execute everywhere |
| 16 | + |
| 17 | +set -uo pipefail |
| 18 | +cd "$(dirname "$0")/.." |
| 19 | + |
| 20 | +source .env |
| 21 | + |
| 22 | +: "${PRIVATE_KEY:?PRIVATE_KEY must be set (deployer key)}" |
| 23 | + |
| 24 | +broadcast=${1:-} |
| 25 | + |
| 26 | +# --tempo.fee-token is only available in newer foundry builds (matches deploy.sh usage) |
| 27 | +tempo_supported="" |
| 28 | +if forge script --help 2>/dev/null | grep -q 'tempo.fee-token'; then |
| 29 | + tempo_supported="yes" |
| 30 | +fi |
| 31 | + |
| 32 | +declare -A NETWORK=( |
| 33 | + [1]=ETHEREUM |
| 34 | + [10]=OPTIMISM |
| 35 | + [56]=BSC |
| 36 | + [100]=GNOSIS |
| 37 | + [130]=UNICHAIN |
| 38 | + [137]=POLYGON |
| 39 | + [143]=MONAD |
| 40 | + [146]=SONIC |
| 41 | + [324]=ZKSYNC |
| 42 | + [480]=WORLD |
| 43 | + [999]=HYPER |
| 44 | + [1329]=SEI |
| 45 | + [1868]=SONEIUM |
| 46 | + [4217]=TEMPO |
| 47 | + [4326]=MEGAETH |
| 48 | + [8453]=BASE |
| 49 | + [9745]=PLASMA |
| 50 | + [42161]=ARBITRUM |
| 51 | + [42793]=ETHERLINK |
| 52 | + [43114]=AVALANCHE |
| 53 | + [57073]=INK |
| 54 | + [59144]=LINEA |
| 55 | + [80094]=BERACHAIN |
| 56 | + [98866]=PLUME |
| 57 | + [747474]=KATANA |
| 58 | +) |
| 59 | + |
| 60 | +# Union of chains across all relevant deployer broadcasts |
| 61 | +chains=$(ls broadcast/LayerZeroDeployer.s.sol broadcast/EnsoCCIPReceiverDeployer.s.sol broadcast/FlashloanAdapterDeployer.s.sol 2>/dev/null \ |
| 62 | + | grep -E '^[0-9]+$' | sort -nu) |
| 63 | + |
| 64 | +failed=() |
| 65 | +for chain in $chains; do |
| 66 | + network="${NETWORK[$chain]:-}" |
| 67 | + if [[ -z "$network" ]]; then |
| 68 | + echo "!! chain $chain: no network mapping, skipping" |
| 69 | + continue |
| 70 | + fi |
| 71 | + rpc="${network}_RPC_URL" |
| 72 | + url="${!rpc:-}" |
| 73 | + if [[ -z "$url" ]]; then |
| 74 | + echo "!! chain $chain: $rpc not set, skipping" |
| 75 | + continue |
| 76 | + fi |
| 77 | + |
| 78 | + params=() |
| 79 | + if [[ $network == "ZKSYNC" ]]; then |
| 80 | + params+=(--zksync --slow) |
| 81 | + fi |
| 82 | + if [[ $network == "POLYGON" ]]; then |
| 83 | + params+=(--gas-estimate-multiplier 300) |
| 84 | + fi |
| 85 | + if [[ $network == "TEMPO" ]]; then |
| 86 | + if [[ -z "$tempo_supported" ]]; then |
| 87 | + echo "!! chain $chain: forge $(forge --version | head -1) lacks --tempo.fee-token, skipping (update foundry to migrate Tempo)" |
| 88 | + continue |
| 89 | + fi |
| 90 | + params+=(--tempo.fee-token "0x20c000000000000000000000b9537d11c60e8b50") |
| 91 | + fi |
| 92 | + if [[ $broadcast == "broadcast" ]]; then |
| 93 | + params+=(--broadcast) |
| 94 | + fi |
| 95 | + |
| 96 | + echo "" |
| 97 | + echo "===== chain $chain ($network) =====" |
| 98 | + if ! PRIVATE_KEY="$PRIVATE_KEY" \ |
| 99 | + forge script script/RoleMigration.s.sol --rpc-url "$url" "${params[@]}" -vvv; then |
| 100 | + echo "!! chain $chain FAILED" |
| 101 | + failed+=("$chain") |
| 102 | + fi |
| 103 | +done |
| 104 | + |
| 105 | +echo "" |
| 106 | +if [[ ${#failed[@]} -gt 0 ]]; then |
| 107 | + echo "Failed chains: ${failed[*]}" |
| 108 | + exit 1 |
| 109 | +fi |
| 110 | +echo "All chains processed." |
0 commit comments