Skip to content

two-step admin transfer (propose/accept) with timelock #445

Description

@mikewheeleer

Summary

Admin transfer is a single call, so a typo or compromised key hands over the contract irrevocably. Implement a two-step propose/accept transfer with a timelock.

Why this matters

Single-step admin handover is a well-known footgun. Propose/accept + timelock prevents fat-finger and gives a reaction window.

Requirements

  • propose_admin(new) stores a pending admin + proposal timestamp (admin-only).
  • accept_admin() succeeds only when called by the pending admin after the timelock.
  • The current admin can cancel a pending proposal.
  • Emit events for propose/accept/cancel.

Technical guidance

  • Enforce the timelock against the ledger timestamp.
  • Clear the pending slot on accept/cancel.

Edge cases — each must have a test

  • propose then accept after timelock -> transfers
  • accept before timelock -> rejected
  • accept by wrong account -> rejected
  • cancel -> pending cleared
  • events on each step

Acceptance criteria

  • All requirements and every edge case above implemented and covered by tests
  • New unit and integration tests; existing tests still pass and no regressions
  • Structured, typed errors (no leaked internals; stable codes)
  • cargo fmt --check, cargo clippy --all-targets -- -D warnings, and cargo test all pass locally
  • Code follows the repo's existing conventions; no duplication or dead code
  • Short docs/comments explaining the design and any non-obvious decisions
  • PR description explains the approach and includes Closes #<issue>

Out of scope

  • Multi-sig admin
  • Role hierarchy

Rewards

Part of the GrantFox OSS / Official Campaign (FWC26) — this task may be rewarded. PR quality is assessed by AI: depth, correctness under edge cases, meaningful tests, and clean design are what earn the reward. Shallow changes (typos, formatting, trivial docs) do not qualify.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions