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-09·audit-finding

Base deployment silently retains DEFAULT_ADMIN when ADMIN_ADDRESS is unset

Fixednfterc-1155marketplace
TL;DR

Base deployment silently retains DEFAULT_ADMIN when ADMIN_ADDRESS is unset. Final disposition: Fixed.

Severity
MEDIUM
Method
MManual review
CAT.

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

02Section · Affected files

Affected files

script/DeployBase.s.sol#L220-L237

03Section · Description

Description

DeployBase._handoverAdmin() reads ADMIN_ADDRESS with the deployer as its default and immediately returns when both addresses match. An unset variable therefore skips all three beginDefaultAdminTransfer() calls without warning, while the deployment continues successfully.

The deployed Base Sepolia badge and both markets retain the deploying EOA as defaultAdmin, report no pending admin, and emitted no DefaultAdminTransferScheduled event from deployment through the review block. A focused test of the real deployment script also confirmed that leaving ADMIN_ADDRESS unset schedules no transfer on any contract, whereas setting it schedules all three.

Vulnerable Scenario: The following steps help understand the issue:

  1. An operator runs the base deployment without setting ADMIN_ADDRESS.
  2. The script defaults the intended admin to the broadcast account and silently skips the handover.
  3. The deployment completes with the badge and both markets administered by the operational deployment key.
  4. Compromise or misuse of that key can change market permissions, grant minting authority, and modify treasury or fee configuration.
04Section · Impact

Impact

A successful deployment can leave every protocol contract under the broadcast key instead of the intended long-term administrator. This creates a live administrative-key exposure across the badge and both markets. The current evidence establishes the unsafe state, but not how the deployment key is stored, so the issue is rated Medium rather than High.

05Section · Recommendations

Recommendations

Require ADMIN_ADDRESS with vm.envAddress() and reject both the zero address and the deployer unless an explicit, visibly logged emergency override is enabled. Before promoting deployment artifacts, assert that all three contracts report the expected pending admin.

For existing deployments, begin the transfer on the badge and both markets, accept each transfer from the intended administrator after the delay, and verify defaultAdmin() on all three contracts.

06Section · Remediation

Remediation

Fixed. The silent no-op is gone: an unset ADMIN_ADDRESS reverts. Keeping the deploy key now requires an explicit ADMIN_KEEP_DEPLOYER equal to the deployer, conflicts with a named admin are refused, the run prints the banner, and adminKeptByDeployer goes into the artifact. An emergency configuration is now impossible to reach by forgetting a variable.

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-09