Pre-auditThree days of senior audit time for $1,500, credited in full toward your Zealynx audit.3 audit days, credited toward your auditSee how →
M-10·audit-finding

Retirement can deauthorize the replacement while preserving the superseded market

Fixednfterc-1155marketplace
TL;DR

Retirement can deauthorize the replacement while preserving the superseded market. Final disposition: Fixed.

Severity
MEDIUM
Method
MManual review
CAT.

Tracker: issue #31 · Status: Fixed · Verified at: audit-v3-rereview-handoff

02Section · Affected files

Affected files

script/retire_superseded.sh#L28-L59 script/UpgradeSettlement.s.sol#L91-L125

03Section · Description

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:

code
artifact names replacement: sends targeting replacement = 0
artifact 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:

  1. An operator deploys and verifies a replacement with UpgradeSettlement.
  2. The upgrade script leaves addresses.json pointing to the superseded market.
  3. The operator runs retire_superseded.sh as the next upgrade step.
  4. The script preserves the superseded market and removes both required permissions from the replacement.
04Section · Impact

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.

05Section · Recommendations

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.

06Section · Remediation

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.

07Section · Verification provenance

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.

Status
Fixed
M-10