Skip to content

fix: close protocol-pause bypass via admin-whitelist collision (#26) - #32

Merged
elizabetheonoja-art merged 1 commit into
Utility-Protocol:mainfrom
Mhidesav:fix/issue-26-protocol-pause-bypass
Jun 24, 2026
Merged

fix: close protocol-pause bypass via admin-whitelist collision (#26)#32
elizabetheonoja-art merged 1 commit into
Utility-Protocol:mainfrom
Mhidesav:fix/issue-26-protocol-pause-bypass

Conversation

@Mhidesav

Copy link
Copy Markdown
Contributor

Summary

Closes #26 — Protocol-Pause Bypass via Admin-Whitelist Collision

Root Causes Fixed

1. Admin-Whitelist Collision (auth bypass)

Three velocity-limit admin functions accepted an arbitrary admin: Address parameter and only called admin.require_auth(). Since any transaction source satisfies its own require_auth(), any address could pose as the contract admin.

Affected functions:

  • set_velocity_limit_config
  • apply_velocity_override
  • revoke_velocity_override

Fix: Each function now checks admin == get_admin_or_panic(&env) before require_auth().

2. Storage Key Collision (protocol-pause bypass)

revoke_velocity_override referenced DataKey::VelocityOverrideGlobal and DataKey::VelocityOverride(u64) — variants that do not exist in the DataKey enum. The actual overrides are stored under VelocityDataKey::VelocityOverride(scope) in velocity_limit.rs. This meant the existence check always missed the real key, making overrides impossible to revoke and silently bypassing the circuit-breaker.

Fix: Use velocity_limit::VelocityDataKey::VelocityOverride(meter_id) consistently.

3. Double auth in velocity_limit.rs

apply_override and set_velocity_config duplicated admin.require_auth() even though the callers in lib.rs already perform the verified check.

Fix: Removed the redundant inner require_auth calls.

Tests Added

5 regression tests in src/test.rs:

  • test_configure_velocity_limits_rejects_non_admin
  • test_configure_velocity_limits_succeeds_for_real_admin
  • test_apply_velocity_override_rejects_non_admin
  • test_apply_and_revoke_velocity_override_by_admin
  • test_revoke_velocity_override_rejects_non_admin

CI

All CI steps pass: cargo fmt --check, cargo clippy -- -D warnings, cargo test, cargo build --target wasm32-unknown-unknown --release.

…ty-Protocol#26)

Three velocity-limit admin functions accepted an arbitrary
parameter and only called , allowing any self-authorizing
address to impersonate the contract admin:

- set_velocity_limit_config
- apply_velocity_override
- revoke_velocity_override

Additionally, revoke_velocity_override referenced DataKey::VelocityOverrideGlobal
and DataKey::VelocityOverride (not present in the DataKey enum), creating a
key-collision — the existence check always failed, and revoked the wrong key.

Fixes:
- Add stored-admin identity check before require_auth in all three functions
- Replace DataKey::VelocityOverride* with velocity_limit::VelocityDataKey::VelocityOverride
- Remove redundant require_auth from velocity_limit::apply_override and set_velocity_config
  (auth is enforced by the caller in lib.rs)
- Add 5 regression tests covering non-admin rejection and happy-path flows

@elizabetheonoja-art elizabetheonoja-art left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@elizabetheonoja-art
elizabetheonoja-art merged commit 9cc60d0 into Utility-Protocol:main Jun 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Protocol-Pause Bypass via Admin-Whitelist Collision

2 participants