Skip to content

✅ [Fixed] transfer_admin and update_admin are duplicate entrypoints with inconsistent event emission #916

Description

@Ejirowebfi

Severity: Critical (as filed) · Area: Contract (contracts/token-factory/src/lib.rs) · Status: ✅ Resolved — re-verified against the tree on 2026-08-19

Description

Original defect. transfer_admin and update_admin were independently written copies of the same state transition, and they had drifted: only update_admin emitted adm_upd. Any monitoring built on that event — a reasonable thing to build for admin-key rotation — would silently miss a rotation performed through transfer_admin, giving an attacker holding a compromised admin key a documented way to rotate to their own key without tripping event-based alerting.

Why this is now closed. Both entrypoints are now thin delegates over one implementation:

  • rotate_admin (lib.rs:1610-1626) holds the single copy of the auth check, the self-transfer guard, the state write, and the adm_upd emission. transfer_admin (lib.rs:1629) and update_admin (lib.rs:1634) each call it and do nothing else, so no rotation path can be silent and the two cannot drift again.
  • The duplication itself is retained deliberately rather than accidentally: transfer_admin is kept as an ABI alias for callers built against the older signature, documented as such at lib.rs:1627-1628 and docs/contract-abi.md:348-352, which also records the original divergence and directs new integrations to update_admin.
  • Tests pin the equivalence: test_transfer_admin_and_update_admin_share_guards (test.rs:3788) and test_transfer_admin_and_update_admin_produce_same_state (test.rs:3807), alongside the pre-existing rotation tests at test.rs:1549-1590 and test.rs:3771.
  • The event table at docs/contract-abi.md:436 lists adm_upd with its (current_admin, new_admin) payload.

Note that the other half of what a reviewer might expect here — that admin rotation is still single-step, so a typo'd address permanently bricks the factory — is a separate, still-open defect tracked in #1012.

Tasks

Acceptance Criteria

  • Every code path that changes FactoryState.admin emits adm_upd, verified by test.
  • The contract surface has one documented rotation path, with the alias explicitly labeled as a compatibility shim.

Re-verified on 2026-08-19 during the 30-issue codebase audit tracked in ISSUES.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Third CampaignCampaign: Third CampaignauditFrom the ISSUES.md codebase auditbugSomething isn't workingcontractssecurityseverity: criticalFunds/consensus/permanent-brick risk

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions