# BuildV2UpgradeBatch configuration Source: [BuildV2UpgradeBatch.s.sol](../../script/v2/upgrade/BuildV2UpgradeBatch.s.sol). Configuration: [UpgradeConfig.sol](../../script/v2/configs/UpgradeConfig.sol), which inherits [SharedConfig.sol](../../script/v2/configs/SharedConfig.sol). Reviewed baseline: [deployment runbook](../v2-deployment-runbook.md). Use this after [DeployV2Dependencies](./DeployV2Dependencies.md) has deployed and verified its contracts. This is a read-only builder: it validates production bindings and generates the timelock calldata for both proxy upgrades in one batch. Running it does not deploy, schedule, execute, or upgrade contracts. The Make targets use [ScheduleV2Upgrade](../../script/v2/upgrade/ScheduleV2Upgrade.s.sol) and [ExecuteV2Upgrade](../../script/v2/upgrade/ExecuteV2Upgrade.s.sol) for those transactions, sharing this builder's batch encoding and preflights. Contract settings below are Solidity constants in those configuration files. `TBD` means an unresolved deployment output or launch decision; the zero values marked `TBD` and `UPGRADE_CONFIGURATION_APPROVED = false` are placeholders, not approved launch settings. ## 1. Existing addresses already configured These addresses are in `SharedConfig.sol`. User-confirmed addresses are identified separately from source constants. Source constants must still be verified against the intended production configuration. | Constant | Currently configured address | Source / purpose | |---|---|---| | `STAKED_USDAT_PROXY` | `0xD166337499E176bbC38a1FBd113Ab144e5bd2Df7` | User-confirmed; first upgrade target. | | `WITHDRAWAL_QUEUE_PROXY` | `0x4Bc9FEC04F0F95e9b42a3EF18F3C96fB57923D2e` | User-confirmed; second upgrade target. | | `USDAT` | `0x23238f20b894f29041f48D88eE91131C395Aaa71` | User-confirmed; queue implementation asset binding. | | `TIMELOCK` | `0xfD5782E3BFF366601da3973aE30C583dE4F08A67` | Source constant; existing admin/upgrade timelock for both proxies. | | Environment variable | Value | Purpose | |---|---|---| | `ADMIN` | Loaded by `source syncprod` | Fireblocks sender; scheduling requires this address to hold `PROPOSER_ROLE` on `TIMELOCK`. | ## 2. Deployed dependency addresses All five constants are populated in `UpgradeConfig.sol` from the latest deployment record. Confirm Etherscan verification for these replacement addresses before scheduling. | Constant to set | Value | Deployment output | |---|---|---| | `STAKED_USDAT_IMPLEMENTATION` | `0x2b7074CF6681382b70E239063931ebE83C0f4E0A` | `deployed.stakedUsdatImplementation` | | `WITHDRAWAL_QUEUE_IMPLEMENTATION` | `0xdAF6f8523D7A707D173A12041e1523FDF1373f23` | `deployed.withdrawalQueueImplementation` | | `STRC_MIRROR_MODULE` | `0xa2Cf4B9410cEbcDCeb3cFf772aC0219F6D1105C9` | `deployed.strcMirrorModule` | | `STRCON_MODULE` | `0x3C0f0b502aa7C2ed85620f7f52B8eFb8049b1ECf` | `deployed.strconModule` | | `EXECUTION_POLICY` | `0x69a4cc75f654Eb5fF0eD73E0153Fd17Fc66878dc` | `deployed.executionPolicy` | The wrapper oracle and linked library addresses are already bound into these deployments. This step needs no additional inputs for the wrapper, linked library, STRCon token, price feeds, runtime hashes, or the deployer's nonce. ## 3. Wallet addresses These addresses are user-provided and set in `UpgradeConfig.sol`. Confirm eligibility, funding, allowances, and wallet controls using the runbook. | Constant to set | Value | Purpose | |---|---|---| | `RECOVERY_ADDRESS` | `0x6e5301A99E321f535C9e077f8f7F98770229B1a4` | Canonical destination for seizures and token rescue; must satisfy vault restrictions. | | `SURPLUS_SOURCE` | `0xbBeb892bAA398251EBe80809906F2Ae51EF5a783` | Dedicated USDat source wallet that preapproves the vault for surplus transfers. | | `EXECUTION_VEHICLE` | `0xb3C29aa9196785F0aa5ECA6Cb0BcF1E92D83A468` | Trading counterparty and migration delivery wallet; initializes the execution policy. | | Wallet controls to record | Value | |---|---| | Execution vehicle controlling wallet / signers / approval quorum | TBD | ## 4. Assign all twelve operational role addresses Role holders are set in `UpgradeConfig.sol`. All twelve holders are user-provided below. Enter the controlling timelock contract address for each timelocked role. Record wallet controls or the governance reference for every holder. | Constant to set | Holder address | Role / constraint | Controls / signers / quorum reference | |---|---|---|---| | `VAULT_PARAMETER_MANAGER` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | `PARAMETER_MANAGER_ROLE`; timelock required. | 1-hour timelock (user-provided); controls TBD. | | `VAULT_MARKET_MODE_MANAGER` | `0xC35580434261f667d6abBDa9E3dC1DC31e5A1b92` | `MARKET_MODE_MANAGER_ROLE`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `VAULT_OPERATOR` | `0xC35580434261f667d6abBDa9E3dC1DC31e5A1b92` | `OPERATOR_ROLE`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `VAULT_SURPLUS_MANAGER` | `0xC35580434261f667d6abBDa9E3dC1DC31e5A1b92` | `SURPLUS_MANAGER_ROLE`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `VAULT_BLACKLISTER` | `0xf5a93281ac8604f99755cc489317e75aC334cfE2` | `BLACKLISTER_ROLE`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `VAULT_ENFORCER` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | `ENFORCER_ROLE`; timelock required. | 1-hour timelock (user-provided); controls TBD. | | `VAULT_PAUSER` | `0xf5a93281ac8604f99755cc489317e75aC334cfE2` | `PAUSER_ROLE`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `VAULT_UNPAUSER` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | `UNPAUSER_ROLE`; timelock required. | 1-hour timelock (user-provided); controls TBD. | | `QUEUE_OPERATOR` | `0xC35580434261f667d6abBDa9E3dC1DC31e5A1b92` | Queue `OPERATOR_ROLE`; matches `VAULT_OPERATOR`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `QUEUE_ENFORCER` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | Queue `ENFORCER_ROLE`; timelock required; matches `VAULT_ENFORCER`. | 1-hour timelock (user-provided); controls TBD. | | `QUEUE_PAUSER` | `0xf5a93281ac8604f99755cc489317e75aC334cfE2` | Queue `PAUSER_ROLE`; matches `VAULT_PAUSER`. | Fireblocks MPC wallet; approvers / approval quorum TBD. | | `QUEUE_UNPAUSER` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | Queue `UNPAUSER_ROLE`; timelock required; matches `VAULT_UNPAUSER`. | 1-hour timelock (user-provided); controls TBD. | Per [specification §2.8](../saturn-v2-spec.md#28-roles), operator, market-mode manager, and surplus manager may share one address in any combination. Parameter manager, enforcer, and unpauser may share one timelock; blacklister and pauser may share one wallet. The current launch role assignments use this approved sharing. All other cross-role co-location remains prohibited. Holding the same role on both proxies is permitted. The builder checks nonzero role addresses but does not enforce these sharing constraints or verify operational timelock controls. `DEFAULT_ADMIN_ROLE` is preserved, not supplied to either initializer. The builder requires `TIMELOCK` to hold it on both proxies. Record the complete existing holder sets and controls in the runbook; this check does not exclude additional admins. The mirror, wrapper, module, and execution policy use the vault's authorization registry and need no separate operational role address inputs here. ### Governance controls supporting those role assignments The deployment script does not create governance timelocks. Identify and verify these contracts before selecting the role addresses. Each column records a role's timelock; approved shared roles may refer to the same instance. Record separate instances if vault and queue use different holders for the same role. These records support configuration review and are not extra arguments to `BuildV2UpgradeBatch`. | Control | Admin / upgrade | Parameter manager | Enforcement | Unpause | |---|---|---|---|---| | Contract address | `TIMELOCK` above | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | `0x6F72de4F529a03Bfa883825152656a8c62CBB626` | | Contract version / source | TBD | TBD | TBD | TBD | | Minimum delay, seconds | `432000` (script requires 5 days) | `3600` (user-provided; verify live) | `3600` (user-provided; verify live) | `3600` (user-provided; verify live) | | Timelock admin holder(s) | TBD | TBD | TBD | TBD | | Proposer address(es) | `ADMIN` loaded by `source syncprod`; complete set TBD | TBD | TBD | TBD | | Executor address(es) / open execution | Open execution required via role grant to `address(0)`; complete set TBD | TBD | TBD | TBD | | Canceller address(es) | TBD | TBD | TBD | TBD | | Controlling wallet(s) / signers / approval quorum | TBD | TBD | TBD | TBD | | Target contract(s) / granted role(s) | Both proxies / `DEFAULT_ADMIN_ROLE`; complete grants TBD | TBD | TBD | TBD | ## 5. Set the non-address inputs Set these inputs in `UpgradeConfig.sol`. Zero fees or capacity can be deliberate values, but their current zero constants are not a recorded approval. Review every field before enabling the builder. Basis points use `100 bps = 1%`; USDat amounts use 6 decimal places. | Constant to set | Approved value | Current value / requirement | |---|---|---| | `BASE_REDEMPTION_FEE_BPS` | 10 bps (0.10%) | `10`; no greater than elevated redemption fee. | | `ELEVATED_REDEMPTION_FEE_BPS` | 50 bps (0.50%) | `50`; no less than the base redemption fee and at most `500` bps. | | `ELEVATED_DEPOSIT_FEE_BPS` | 25 bps (0.25%) | `25`; at most `500` bps. | | `EXECUTION_TOLERANCE_BPS` | 75 bps (0.75%) | `75`; at most `500` bps. | | `MIGRATION_TOLERANCE_BPS` | 200 bps (2%) | `200`; at most `500` bps. | | `INITIAL_EXECUTION_CAPACITY` | 6,000,000 USDat | `6_000_000e6`; `uint128`, raw USDat units; initial available capacity also starts at this amount. | | `INITIAL_EXECUTION_REFILL_PER_DAY` | 6,000,000 USDat/day | `6_000_000e6`; `uint128`, raw USDat units per day. | | `BATCH_SALT` | `bytes32(0)` | Zero is allowed; use the same salt when scheduling and executing. | | `UPGRADE_CONFIGURATION_APPROVED` | TBD — enable after review | Currently `false`; `run()` requires `true`. | `SharedConfig.sol` sets `EXPECTED_CHAIN_ID = 1`, `TIMELOCK_DELAY = 5 days`, and the migration tolerance cap to `500` bps. `UpgradeConfig.sol` sets `UPGRADE_PREDECESSOR = bytes32(0)` and fee/execution tolerance caps of `500` bps. No planned timestamps are required. The timelock sets readiness to the actual scheduling block timestamp plus five days; execution checks readiness on-chain. The vault reads legacy seed accounting from preserved proxy storage during initialization. No seed accounting values, vesting timestamp, or legacy queue inventory is an initializer input. Those observations belong in the runbook. ## 6. Outputs and next step The builder returns/logs the two proxy upgrade payloads, encoded initializers, batch targets and ETH values, `scheduleCalldata`, `executeCalldata`, and `operationId`. These are outputs to retain after running the builder, not fields to supply beforehand. Both upgrades are encoded into the same atomic batch, with the vault first and the queue second. The Make targets regenerate the batch from the current configuration on each run. Execution requires that exact operation to be ready on-chain. Keep the configuration unchanged after scheduling; changing the batch requires a new proposal. Use the [runbook](../v2-deployment-runbook.md) for rehearsal, submission, the delay, execution evidence, and the validation round trip. After the upgrade and its validation gate, use [BuildV2Migration](./BuildV2Migration.md) for the separate migration inputs.