Skip to content

Commit 9c7e095

Browse files
committed
feat: update upgrade process documentation and scripts
- Added new parameters to .env.example for Safe upgrade proposals. - Modified package.json to streamline the upgrade submission script. - Expanded MULTISIG_UPGRADE_GUIDE.md with detailed steps for proposing upgrades. - Enhanced submit-upgrade-to-safe.mjs to load env and improve error messaging. Made-with: Cursor
1 parent b5196d5 commit 9c7e095

File tree

5 files changed

+3326
-29
lines changed

5 files changed

+3326
-29
lines changed

.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ CELO_RPC=
1111
OPTIMISM_RPC=
1212
POLYGON_RPC=
1313

14-
# For auto-proposing upgrade to Safe (proposer must be a Safe owner)
14+
# For upgrade:submit-to-safe (proposer must be a Safe owner)
1515
SAFE_ADDRESS=
16+
PROXY_ADMIN_ADDRESS=
17+
PROXY_ADDRESS=
18+
NEW_IMPLEMENTATION_ADDRESS=
1619
PROPOSER_PRIVATE_KEY=
20+
SAFE_API_KEY= # required: get at https://developer.safe.global
1721

1822
ETHERSCAN_API_KEY=

docs/MULTISIG_UPGRADE_GUIDE.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,71 @@ This guide is for signers of the **ProxyAdmin** multisig. It explains how to run
44

55
---
66

7+
## Steps to propose the transaction
8+
9+
Choose one of two ways: **A) Submit from your machine** (script posts to Safe) or **B) Generate payload** then create the tx in the Safe UI.
10+
11+
### Parameters and inputs you need
12+
13+
| Parameter | Where to set | Description |
14+
|-----------|----------------|--------------|
15+
| **SAFE_ADDRESS** | `.env` or CLI | The multisig Safe address (owner of ProxyAdmin). |
16+
| **PROXY_ADMIN_ADDRESS** | `.env` or CLI | The ProxyAdmin contract address. |
17+
| **PROXY_ADDRESS** | `.env` or CLI | The DonationHandler proxy to upgrade. |
18+
| **NEW_IMPLEMENTATION_ADDRESS** | `.env` or CLI | The new implementation contract address (from `yarn deploy:implementation <chain>`). |
19+
| **PROPOSER_PRIVATE_KEY** (or **PROPOSER_PK**) | `.env` only | Private key of a Safe **owner** (used only for **Option A**). |
20+
| **&lt;CHAIN&gt;_RPC** | `.env` | RPC URL for the chain, e.g. `BASE_RPC`, `MAINNET_RPC`. |
21+
| **CHAIN** | CLI argument or `.env` | Chain name: `mainnet`, `base`, `arbitrum`, `optimism`, `polygon`, `gnosis`, `celo`, `sepolia`. |
22+
| **SAFE_API_KEY** | `.env` (optional) | Safe API key if you hit rate limits. |
23+
24+
---
25+
26+
### Option A — Submit proposal from your machine (recommended if you have proposer key)
27+
28+
1. **Set in `.env`:**
29+
- `SAFE_ADDRESS` = your multisig address
30+
- `PROXY_ADMIN_ADDRESS` = ProxyAdmin contract
31+
- `PROXY_ADDRESS` = DonationHandler proxy
32+
- `NEW_IMPLEMENTATION_ADDRESS` = new implementation (from deploy)
33+
- `PROPOSER_PRIVATE_KEY` or `PROPOSER_PK` = private key of **one Safe owner**
34+
- `<CHAIN>_RPC` = RPC URL (e.g. `BASE_RPC`, `MAINNET_RPC`)
35+
36+
2. **Run (from repo root):**
37+
```bash
38+
yarn upgrade:submit-to-safe base
39+
```
40+
Use the correct chain instead of `base` if needed (e.g. `mainnet`, `arbitrum`).
41+
42+
3. The script will create the upgrade tx, sign it with the proposer key, and submit it to the Safe Transaction Service. Other signers see it in the Safe UI and can confirm/execute.
43+
44+
---
45+
46+
### Option B — Generate payload, then create the tx in Safe UI
47+
48+
1. **Set in `.env` (or pass as CLI args):**
49+
- `PROXY_ADMIN_ADDRESS`
50+
- `PROXY_ADDRESS`
51+
- `NEW_IMPLEMENTATION_ADDRESS`
52+
Optional: `SAFE_ADDRESS`, `CHAIN` (for the printed Safe link).
53+
54+
2. **Generate the payload:**
55+
```bash
56+
yarn upgrade:generate-payload 0x<ProxyAdmin> 0x<Proxy> 0x<NewImplementation>
57+
# Or with env set: yarn upgrade:generate-payload
58+
```
59+
60+
3. **Use the output:**
61+
- Open the printed Safe link (or [app.safe.global](https://app.safe.global)).
62+
- **New transaction****Contract interaction** (or **Apps****Transaction Builder**).
63+
- **To:** paste `PROXY_ADMIN_ADDRESS`.
64+
- **Data:** paste the hex **Data (calldata)** from the script output, or use the function `upgrade(address,address)` with `proxy` = `PROXY_ADDRESS` and `implementation` = `NEW_IMPLEMENTATION_ADDRESS`.
65+
- **Value:** 0.
66+
- **Create transaction** so other signers can sign and execute.
67+
68+
Alternatively, in Safe go to **Apps****Transaction Builder****Import** and select the generated `upgrade-payload.json`.
69+
70+
---
71+
772
## Proposing the transaction (for the proposer)
873

974
If you have the three addresses (ProxyAdmin, proxy, new implementation), you can **generate** the exact transaction payload and a Safe Transaction Builder–ready JSON:

package.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,13 @@
1010
"license": "MIT",
1111
"author": "Wonderland",
1212
"scripts": {
13+
"addresses": "./scripts/get-proxy-addresses.sh",
1314
"build": "forge build",
1415
"build:optimized": "FOUNDRY_PROFILE=optimized forge build",
1516
"coverage": "forge coverage --ir-minimum --report summary --report lcov --match-path 'test/unit/*'",
17+
"deploy:implementation": "./scripts/deploy-implementation.sh",
1618
"deploy:mainnet": "bash -c 'source .env && forge script Deploy --rpc-url $MAINNET_RPC --account $MAINNET_DEPLOYER_NAME --broadcast --verify --chain mainnet -vvvvv'",
1719
"deploy:sepolia": "bash -c 'source .env && forge script script/DeployDonationHandler.s.sol:DeployDonationHandler --rpc-url $SEPOLIA_RPC --broadcast --verify -vvvv'",
18-
"addresses": "./scripts/get-proxy-addresses.sh",
19-
"upgrade:mainnet": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --rpc-url $MAINNET_RPC --broadcast --verify -vvvv'",
20-
"upgrade:mainnet:simulate": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --fork-url $MAINNET_RPC -vvvv'",
21-
"upgrade:sepolia": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --rpc-url $SEPOLIA_RPC --broadcast --verify -vvvv'",
22-
"deploy:implementation": "./scripts/deploy-implementation.sh",
23-
"upgrade:generate-payload": "./scripts/generate-upgrade-payload.sh",
24-
"upgrade:submit-to-safe": "bash -c 'source .env && node scripts/submit-upgrade-to-safe.mjs \"$@\"' bash",
2520
"lint:check": "yarn lint:sol && forge fmt --check",
2621
"lint:fix": "sort-package-json && forge fmt && yarn lint:sol --fix",
2722
"lint:natspec": "npx @defi-wonderland/natspec-smells --config natspec-smells.config.js",
@@ -32,26 +27,32 @@
3227
"test:integration": "forge test --match-contract Integration -vvv",
3328
"test:symbolic": "halmos",
3429
"test:unit": "forge test --match-contract Unit -vvv",
35-
"test:unit:deep": "FOUNDRY_FUZZ_RUNS=5000 yarn test:unit"
30+
"test:unit:deep": "FOUNDRY_FUZZ_RUNS=5000 yarn test:unit",
31+
"upgrade:generate-payload": "./scripts/generate-upgrade-payload.sh",
32+
"upgrade:mainnet": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --rpc-url $MAINNET_RPC --broadcast --verify -vvvv'",
33+
"upgrade:mainnet:simulate": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --fork-url $MAINNET_RPC -vvvv'",
34+
"upgrade:sepolia": "bash -c 'source .env && forge script script/UpgradeDonationHandler.s.sol:UpgradeDonationHandler --rpc-url $SEPOLIA_RPC --broadcast --verify -vvvv'",
35+
"upgrade:submit-to-safe": "node scripts/submit-upgrade-to-safe.mjs"
3636
},
3737
"lint-staged": {
3838
"*.{js,css,md,ts,sol}": "forge fmt",
3939
"(src|test|script)/**/*.sol": "yarn lint:sol",
4040
"package.json": "sort-package-json"
4141
},
4242
"devDependencies": {
43-
"@safe-global/api-kit": "^4.0.0",
44-
"@safe-global/protocol-kit": "^4.0.0",
45-
"@safe-global/types-kit": "^4.0.0",
4643
"@commitlint/cli": "19.3.0",
4744
"@commitlint/config-conventional": "19.2.2",
4845
"@defi-wonderland/natspec-smells": "1.1.6",
49-
"forge-std": "github:foundry-rs/forge-std#1.9.2",
46+
"@safe-global/api-kit": "^4.0.0",
47+
"@safe-global/protocol-kit": "^4.0.0",
48+
"@safe-global/types-kit": "^3.0.0",
49+
"dotenv": "^16.4.5",
50+
"ethers": "^6.13.0",
51+
"forge-std": "github:foundry-rs/forge-std#v1.9.2",
5052
"halmos-cheatcodes": "github:a16z/halmos-cheatcodes#c0d8655",
5153
"husky": ">=9",
5254
"lint-staged": ">=10",
5355
"solhint-community": "4.0.1",
54-
"sort-package-json": "2.10.0",
55-
"ethers": "^6.13.0"
56+
"sort-package-json": "2.10.0"
5657
}
5758
}

0 commit comments

Comments
 (0)