Retirement can deauthorize the replacement while preserving the superseded market
Retirement can deauthorize the replacement while preserving the superseded market. Final disposition: Fixed.
Tracker: issue #31 · Status: Fixed · Verified at: audit-v3-rereview-handoff
Affected files
script/retire_superseded.sh#L28-L59 script/UpgradeSettlement.s.sol#L91-L125
Description
UpgradeSettlement.run() deploys and authorizes a replacement settlement but only prints its address; it never stages or promotes that address into deployments/base-sepolia/addresses.json. The retirement script then treats the two settlements named in that artifact as the live pair and targets every other settlement found in broadcast history.
Following the documented upgrade-then-retire sequence with the stale artifact therefore reverses the intended cutover: the superseded market is excluded, while the replacement is de-whitelisted and loses its relayer role. A deterministic run of the audited retirement script produced:
artifact names replacement: sends targeting replacement = 0artifact names superseded: sends targeting replacement = 2
The two sends in the second case were the badge de-whitelisting transaction and the relayer-role revocation, after which the script printed done. and exited successfully.
Vulnerable Scenario: The following steps help understand the issue:
- An operator deploys and verifies a replacement with
UpgradeSettlement. - The upgrade script leaves
addresses.jsonpointing to the superseded market. - The operator runs
retire_superseded.shas the next upgrade step. - The script preserves the superseded market and removes both required permissions from the replacement.
Impact
The replacement cannot execute settlements, while the authority that retirement was intended to remove remains on the superseded market. Recovery requires restoring both permissions, and re-authorizing the badge permission re-arms its activation delay. Failed settlements revert atomically, so the demonstrated consequence is an inverted cutover and trading outage rather than partial asset movement.
Recommendations
Make the upgrade produce an authenticated per-upgrade manifest that explicitly records both the superseded and replacement settlements. Validate the manifest, replacement bytecode, badge binding, class mask, and relayer before sending any retirement transaction.
Retire only the recorded superseded address after the replacement has been promoted and verified. Fail closed if the promoted artifact and the upgrade manifest disagree, and verify the final permissions on both contracts before reporting completion.
Remediation
Fixed. Lineage is reconstructed from the signed manifests, a candidate that any manifest names as a replacement and that no later manifest superseded is never retired, and the artifact is held to the latest manifest. The global FORCE_RETIRE_NEWER=true override is refused by name and must now name the markets it is for.
Verification provenance
Final disposition: Fixed. Verified at audit-v3-rereview-handoff, commit f020448976eb7c4895e1626ef3228876cff2b7d2. This earlier remediation disposition is carried forward from the prior re-review, not independently re-verified in the generation-d pass. The report-wide scope and evidence limitations remain applicable; see the final report overview.