Deploys a new PayerReportManager proxy and implementation pair using DeployPayerReportManager.s.sol.
Before you begin: Complete all environment and prerequisite setup in README.md - Environment and Prerequisites, then return here.
Dependencies managed by this deployment:
| Method | Parameter Registry Key | Updated Contract | Update Function |
|---|---|---|---|
| 3a | xmtp.payerRegistry.settler |
PayerRegistry | updateSettler() |
| 3b | — | DistributionManager | Upgrade (immutable payerReportManagerProxy) |
-
Edit
payerReportManagerProxySaltinconfig/<environment>.jsonto a new unique value. -
Run the prediction script:
forge script DeployPayerReportManagerScript --rpc-url base_sepolia --sig "predictAddresses()" -
Copy the predicted
ImplementationandProxyaddresses intoconfig/<environment>.jsonaspayerReportManagerImplementationandpayerReportManagerProxy. -
Run the script again to confirm
Predicted proxy matches payerReportManagerProxy in config JSON.
The implementation address depends only on bytecode, so it may be unchanged. The Code already exists at predicted implementation address warning is expected in that case.
- Remove the existing
payerReportManagerkey fromenvironments/<environment>.json(the script will rewrite it). - Run the deploy:
forge script DeployPayerReportManagerScript --rpc-url base_sepolia --slow --sig "deployContract()" --broadcastThis deploys the implementation, deploys the proxy, initializes the proxy, and writes the new payerReportManager proxy address to environments/<environment>.json.
PayerRegistry caches the settler (PayerReportManager) address in local storage. We need to announce the new proxy address via the parameter registry, then tell PayerRegistry to pull it in.
-
Set
xmtp.payerRegistry.settlerto the new PayerReportManager proxy address (requires ADMIN):Wallet:
forge script DeployPayerReportManagerScript --rpc-url base_sepolia --slow --sig "SetParameterRegistryValues()" --broadcastFireblocks:
export FIREBLOCKS_NOTE="Deploy PayerReportManager - set settler parameter" export FIREBLOCKS_EXTERNAL_TX_ID=$(uuidgen) # idempotency key, re-run before each new Fireblocks command npx fireblocks-json-rpc --http -- \ forge script DeployPayerReportManagerScript --sender $ADMIN --slow --unlocked --rpc-url {} --timeout 14400 --retries 1 \ --sig "SetParameterRegistryValues()" --broadcast
The
FIREBLOCKS_EXTERNAL_TX_IDis an idempotency key (UUID) that prevents duplicate Fireblocks transactions if forge retries the RPC call.Approve the transaction in the Fireblocks console and wait for it to complete.
If forge times out: Don't panic. The Fireblocks transaction will continue processing independently. Check the Fireblocks console to confirm the transaction was approved and completed on-chain. If it was, proceed to the next step. If you need to re-run, generate a new
FIREBLOCKS_EXTERNAL_TX_ID(viauuidgen) to avoid idempotency conflicts with the completed transaction. -
Pull the value into PayerRegistry (permissionless, uses DEPLOYER):
forge script DeployPayerReportManagerScript --rpc-url base_sepolia --slow --sig "UpdateContractDependencies()" --broadcastThis calls
PayerRegistry.updateSettler(). -
Verify the update took effect:
cast call <payerRegistry-proxy> "settler()(address)" --rpc-url base_sepoliaThe returned address should match the new PayerReportManager proxy.
The following contracts have immutable constructor references to payerReportManagerProxy and must be upgraded or redeployed after a PayerReportManager redeployment:
- DistributionManager — has immutable
payerReportManagerProxy
See the upgrade guides for instructions.