Skip to content

[CRITICAL] upgrade() allows arbitrary WASM replacement with no timelock, delay, or multi-sig — single compromised admin key = total loss #168

Description

@grantfox-oss

Summary

pulse_token/src/lib.rs upgrade (lines ~89-101) lets the admin replace the entire contract WASM immediately with no timelock, no multi-sig, and no code-hash pinning:

admin.require_auth();
env.deployer().update_current_contract_wasm(new_wasm_hash);

Impact

  • Single-key total compromise: anyone who breaches the admin key can replace the WASM with arbitrary code — mint unlimited tokens, drain balances, lock users out.
  • No notification window: there is no delay for users to exit or for governance to intervene.
  • No hash verification: the new WASM hash is not compared against a known-good allowlist.

Fix

  • Require a multi-sig (M-of-N) approval for WASM upgrades.
  • Add a minimum timelock (e.g., 7 days) between scheduling an upgrade and it taking effect.
  • Restrict new_wasm_hash to a pre-approved set of hashes.
  • Emit an UpgradeScheduled event on scheduling and UpgradeApplied on execution.

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 OSSThird CampaignCampaign: Third CampaigncriticalCritical severity - funds at risksecuritySecurity vulnerabilitytokenPULSE token contractupgradeabilityUpgrade / admin control

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions