Skip to content

[20] Implement two-step admin/role transfer across all contracts #20

Description

@merlik787-droi

Problem Statement

Every contract replaces its admin in a single linear call frame. There is no two-step transfer (propose → accept) for:

  • reward-pool::Admin (currently no setter at all — the initialize is the only place this is set).
  • course-registry::Admin, course-registry::RewardPoolAddress, course-registry::BadgeNftAddress.
  • badge-nft::Admin (the authorized registry).
  • quest-engine::Admin, QuestEngine::StakeVault, QuestEngine::RewardPool.
  • stake-vault::Admin.
  • governance::Admin, Governance::BadgeContractAddress.

A typo or loss of admin key in any of these single-step transfers is catastrophic.

Why It Matters

  • A buggy key sent to set_reward_pool_address could route all USDC payouts to an enemy contract.
  • Standard practice (OpenZeppelin AccessControl, Compound Timelock) is two-step with explicit acceptance.
  • Audit deficiency.

Expected Outcome

For each contract:

  • A propose_new_X(proposer, proposed_value) callable by current admin.
  • A accept_X(acceptor) callable by the proposed value, setting the live value.
  • 7-day timelock or similar (configurable per contract).
  • Events XTransferProposed, XTransferAccepted, XTransferCancelled.

Acceptance Criteria

  • All proposed transfers are cancellable by the proposer or admin.
  • Acceptance by non-proposed addresses is rejected.
  • Tests for propose-then-typo-then-cancel recovery.
  • README updated with the new auth flow.

Implementation Notes

  • Consider a shared TwoStepAdmin helper in contracts/common.
  • Reference EIP-1967 / Slip-004 standards.

Files / Modules Affected

All six contracts; possible contracts/common.

Dependencies

Issue #7 (common crate) helpful.

Difficulty

Hard.

Estimated Effort

3–5 days.

Suggested Labels

security, feature, P1, access-control


Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions