Summary
FWSS proxy ownership is a Safe multisig, and our current flow deploys implementations via GitHub Actions but requires manual Safe UI steps for announcePlannedUpgrade / upgradeToAndCall (CALLDATA_ONLY=true scripts + copy/paste).
We should automate creation of Safe transaction proposals using a Safe proposer wallet so upgrades are proposed directly from CI.
Context
- Current runbook:
service_contracts/tools/UPGRADE-PROCESS.md
- Current deploy workflow:
.github/workflows/deploy-contract.yml
- Current scripts generate Safe calldata only:
service_contracts/tools/warm-storage-announce-upgrade.sh
service_contracts/tools/warm-storage-execute-upgrade.sh
Problem
Manual proposal in Safe UI is slow and error-prone (wrong target/data/chain/nonce risk), and creates unnecessary operational overhead during upgrade rollouts.
Goal
After implementation deployment in GitHub Actions, automatically create a Safe transaction proposal (not execute) for the upgrade step using a Safe proposer wallet.
Proposed Approach
- Add a CI step/script that:
- Builds calldata for
announcePlannedUpgrade((address,uint96)) (and optionally upgradeToAndCall(address,bytes) in a later phase).
- Submits a Safe transaction proposal via Safe Transaction Service/API using proposer credentials.
- Outputs proposal URL/tx hash in workflow summary.
- Keep multisig signing/execution manual in Safe (owners still review/sign).
- Support both Calibnet (
314159) and Mainnet (314).
Scope (Phase 1)
- Automate announce proposal creation only.
- Keep execute proposal manual for now.
- FWSS contract path only (registry/stateview out of scope initially).
Implementation Tasks
- Add new script (e.g.
.github/scripts/propose-safe-upgrade.js) to submit Safe proposals.
- Add required GitHub secrets/vars:
- proposer private key (or API credential, depending on integration)
- Safe address per network
- RPC + Safe service endpoint config
- Update
deploy-contract.yml to optionally run proposal step when:
contract == FWSS Implementation
dry_run == false
- Add clear logs and workflow summary:
- Safe address
- target contract
- function
- calldata hash
- proposal link / identifier
- Update
UPGRADE-PROCESS.md with the new automated proposer flow and fallback manual path.
Acceptance Criteria
- Running deploy workflow for FWSS implementation on Calibnet/Mainnet creates a Safe proposal automatically.
- Proposal payload matches expected target + calldata from current scripts.
- No transaction is auto-executed by CI.
- Workflow summary includes a clickable Safe proposal link (or equivalent identifier).
- On failure, workflow surfaces actionable error messages and falls back to manual instructions.
Security / Ops Requirements
- Proposer key stored only in GitHub encrypted secrets.
- Least-privilege proposer wallet (propose-only role; not owner signer).
- Do not print private key/signature material in logs.
- Network/chain ID validation before proposal submission.
Open Questions
- Confirm Safe Transaction Service support/endpoints for chain IDs
314 and 314159.
- Decide if we also want automatic execute-proposal creation after
AFTER_EPOCH in a follow-up issue.
Summary
FWSS proxy ownership is a Safe multisig, and our current flow deploys implementations via GitHub Actions but requires manual Safe UI steps for
announcePlannedUpgrade/upgradeToAndCall(CALLDATA_ONLY=truescripts + copy/paste).We should automate creation of Safe transaction proposals using a Safe proposer wallet so upgrades are proposed directly from CI.
Context
service_contracts/tools/UPGRADE-PROCESS.md.github/workflows/deploy-contract.ymlservice_contracts/tools/warm-storage-announce-upgrade.shservice_contracts/tools/warm-storage-execute-upgrade.shProblem
Manual proposal in Safe UI is slow and error-prone (wrong target/data/chain/nonce risk), and creates unnecessary operational overhead during upgrade rollouts.
Goal
After implementation deployment in GitHub Actions, automatically create a Safe transaction proposal (not execute) for the upgrade step using a Safe proposer wallet.
Proposed Approach
announcePlannedUpgrade((address,uint96))(and optionallyupgradeToAndCall(address,bytes)in a later phase).314159) and Mainnet (314).Scope (Phase 1)
Implementation Tasks
.github/scripts/propose-safe-upgrade.js) to submit Safe proposals.deploy-contract.ymlto optionally run proposal step when:contract == FWSS Implementationdry_run == falseUPGRADE-PROCESS.mdwith the new automated proposer flow and fallback manual path.Acceptance Criteria
Security / Ops Requirements
Open Questions
314and314159.AFTER_EPOCHin a follow-up issue.