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.

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