UPGRADE_TIMELOCK_LEDGERS was set to 0 on both events and profile on 2026-08-18 (commit cd0054c) so the 1.7.0 rollout could iterate without a day's wait per attempt. This must be reversed before the first funded mainnet campaign.
Why it was safe to remove, and why that expires
Mainnet holds no escrow today — both events are Completed with remaining_escrow: 0 — so the control currently protects nothing. That stops being true the moment a campaign funds.
With no window, a compromised 2-of-3 admin can call propose_upgrade and apply_upgrade in a single sequence and swap the wasm outright. cancel_pending_upgrade never gets a chance to fire, which is the entire point of audited control H6 (closed 2026-06-04).
Scope
The #[cfg(feature = "testnet")] split was deliberately kept rather than collapsed, so each contract is a single-value edit. Both tests assert UPGRADE_TIMELOCK_LEDGERS == 0 with a "restore me" message, so flipping the constant fails them loudly rather than passing silently.
Trigger
Whichever comes first:
- the first mainnet campaign funds escrow
- the third-party audit starts — it will flag a removed H6 control as a finding
Tracked in BACKLOG.md under P1.
UPGRADE_TIMELOCK_LEDGERSwas set to0on botheventsandprofileon 2026-08-18 (commitcd0054c) so the 1.7.0 rollout could iterate without a day's wait per attempt. This must be reversed before the first funded mainnet campaign.Why it was safe to remove, and why that expires
Mainnet holds no escrow today — both events are
Completedwithremaining_escrow: 0— so the control currently protects nothing. That stops being true the moment a campaign funds.With no window, a compromised 2-of-3 admin can call
propose_upgradeandapply_upgradein a single sequence and swap the wasm outright.cancel_pending_upgradenever gets a chance to fire, which is the entire point of audited control H6 (closed 2026-06-04).Scope
contracts/events/src/admin.rs—UPGRADE_TIMELOCK_LEDGERSback to17_280contracts/profile/src/admin.rs— samecontracts/events/src/tests/admin.rs—apply_upgrade_is_immediate_while_the_timelock_is_zeroback to assertingUpgradeTimelockNotElapsedcontracts/profile/src/tests/admin.rs— same for the_profilemirrorUPGRADE_TIMELOCK_LEDGERSconsts in both test files back to17_280The
#[cfg(feature = "testnet")]split was deliberately kept rather than collapsed, so each contract is a single-value edit. Both tests assertUPGRADE_TIMELOCK_LEDGERS == 0with a "restore me" message, so flipping the constant fails them loudly rather than passing silently.Trigger
Whichever comes first:
Tracked in
BACKLOG.mdunder P1.