en un clic
upgrade-l2
// Upgrade L2 sovereign chain contracts (bridge and/or GER). Helps configure parameters, choose the right script, and run the upgrade.
// Upgrade L2 sovereign chain contracts (bridge and/or GER). Helps configure parameters, choose the right script, and run the upgrade.
| name | upgrade-l2 |
| description | Upgrade L2 sovereign chain contracts (bridge and/or GER). Helps configure parameters, choose the right script, and run the upgrade. |
| user-invocable | true |
| allowed-tools | Read, Edit, Write, Bash, Grep, Glob, AskUserQuestion |
| argument-hint | [network-name or chain-rpc-url] |
You are helping the user upgrade L2 (sovereign chain) contracts. There are exactly 2 active upgrade scripts -- all others in upgrade/ are deprecated.
Ask the user (or determine from context) which situation applies:
upgradeSovereignBridge (simpler)v1.0.0, v1.1.0, v1.2.0, or legacy v10.1.2)BridgeL2SovereignChain -> AgglayerBridgeL2upgrade/upgradeSovereignBridge/upgradeSovereignBridge.tsupgrade/upgradeSovereignBridge/README.mdupgradeEtrogSovereign (more complex)PolygonZkEVMBridgeV2 (Etrog) -> AgglayerBridgeL2FromEtrogPolygonZkEVMGlobalExitRootL2 (Etrog) -> AgglayerGERL2upgrade/upgradeEtrogSovereign/upgradeEtrogToSovereign.tsupgrade/upgradeEtrogSovereign/upgrade_etrog_to_sovereign.shupgrade/upgradeEtrogSovereign/README.mdUse $ARGUMENTS if provided (network name or RPC URL). Otherwise ask.
Cardona (Agglayer testnet, on Sepolia):
0x32d33D5137a7cFFb54c5Bf8371172bcEc5f310ff0x528e26b25a34a4A5d0dbDa1d57D318153d2ED5820xAd1490c248c5d3CbAE399Fd529b79B42984277DF0xaA8103640A6C92af48A97D720168011E9f3Ec697Mainnet (Ethereum L1):
0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB20x2a3DD3EB832aF982ec71669E178424b10Dca2EDe0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb0x046Bb8bb98Db4ceCbB2929542686B74b516274b3Important: These are L1 addresses. The upgrade targets L2 contracts (on the sovereign chain itself). The bridgeL2Address in the config is the bridge address on L2, which is often the same address as L1 bridge (e.g. 0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe) but deployed on the L2 network.
You MUST ask the user for anything you cannot determine automatically:
.env. Never ask for the actual key.upgradeEtrogSovereign only:bridgeManagerproxiedTokensManagerAddressemergencyBridgePauserAddressemergencyBridgeUnpauserAddressglobalExitRootUpdaterglobalExitRootRemoverv4.0.0-fork.7). Ask: "Which git tag should be used for the OZ manifest? (default: v4.0.0-fork.7)"Write the config to the appropriate path:
upgrade/upgradeSovereignBridge/upgrade_parameters.json for Option Aupgrade/upgradeEtrogSovereign/upgrade_parameters.json for Option B{
"bridgeL2Address": "<bridge-proxy-address-on-L2>",
"forceImport": false,
"unsafeMode": true,
"forkParams": {
"rpc": "<L2-RPC-URL>",
"timelockAdminAddress": "<address-with-proposer-and-executor-role>"
}
}
Notes:
forceImport: true if contract was deployed in L2 genesis (no OZ manifest exists)unsafeMode is always true (bypasses git tag check, which we don't need){
"unsafeMode": true,
"bridgeL2Address": "<bridge-proxy-address-on-L2>",
"bridge_initParams": {
"bridgeManager": "<address>",
"proxiedTokensManagerAddress": "<address>",
"emergencyBridgePauserAddress": "<address>",
"emergencyBridgeUnpauserAddress": "<address>"
},
"ger_initParams": {
"globalExitRootUpdater": "<address>",
"globalExitRootRemover": "<address>"
},
"pathTokensJson": "",
"forkParams": {
"rpc": "<L2-RPC-URL>",
"timelockAdminAddress": "<address>"
}
}
Notes:
pathTokensJson empty to auto-fetch token data from the bridge contractCheck that .env exists and remind the user to set:
DEPLOYER_PRIVATE_KEY (or MNEMONIC)CUSTOM_PROVIDER = the L2 RPC URL (for custom network)npx hardhat run ./upgrade/upgradeSovereignBridge/upgradeSovereignBridge.ts --network custom
./upgrade/upgradeEtrogSovereign/upgrade_etrog_to_sovereign.sh --old-tag <git-tag> --url <L2-RPC-URL>
Or step by step:
./tools/importOZInfoFromTag/import_oz_info_from_tag.sh --tag <tag> --url <rpc>.openzeppelin/npx hardhat run ./upgrade/upgradeEtrogSovereign/upgradeEtrogToSovereign.ts --network customAfter the script runs, upgrade_output.json is created with:
scheduleData: Transaction data to schedule the upgrade in the timelockexecuteData: Transaction data to execute the upgrade after delayRemind the user:
scheduleData to the timelock (requires PROPOSER_ROLE)executeData to the timelock (requires EXECUTOR_ROLE)Run the shadow fork test before executing on mainnet:
npx hardhat run ./upgrade/upgradeSovereignBridge/test/shadowForkUpgrade.test.ts
npx hardhat run ./upgrade/upgradeEtrogSovereign/test/shadowForkUpgrade.test.ts
This forks the network, simulates the full timelock schedule/execute flow, and validates version + storage preservation.