Skip to content

Dedicated validator role for crowdfunding milestone co-authorization (admin quorum is used today) #140

Description

@0xdevcollins

Source: docs/threat-model.md v1.0, Spoof.2 (accepted; planned hardening).

Finding

claim_milestone for crowdfunding calls require_auth() on storage::get_admin(env) (grant.rs) — the same DataKey::Admin address that gates pause, fees, the token list, and (with the timelock at zero) upgrades. There is no separate co-signer role in the contract. The mainnet admin is a genuine 2-of-3 (three weight-1 signers, medium/high thresholds 2, master key weight 0 — Horizon, 2026-09-11), so a single backend-held key cannot satisfy the check: every crowdfunding milestone release requires the admin quorum.

Please confirm how crowdfunding milestone claims are actually signed in production. If a server holds two signer keys to make this routine, that is a full admin compromise waiting to happen and contradicts docs/admin-custody-policy.md; if the quorum signs each milestone by hand, the design imposes a ceremony on a routine flow.

Change

  • Add a Validator role in instance storage (set by admin, two-step or timelocked rotation), used only by claim_milestone for crowdfunding
  • Keep the owner's require_auth(); the validator replaces the admin in that one check
  • Backend co-signs with the validator key; the admin quorum is never exercised in a routine flow
  • Update the threat model (Spoof.2, EoP.3, EoP.7, Info.3) and the custody policy

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions