Skip to content

fix(#569): consolidate pause write+event into bettapay_common - #696

Merged
therealjhay merged 1 commit into
Betta-Pay:mainfrom
k-deejah:fix/569-consolidate-pause-logic
Aug 30, 2026
Merged

fix(#569): consolidate pause write+event into bettapay_common#696
therealjhay merged 1 commit into
Betta-Pay:mainfrom
k-deejah:fix/569-consolidate-pause-logic

Conversation

@k-deejah

Copy link
Copy Markdown
Contributor

Problem


Pause state was checked via common::storage::is_paused, but both contracts had their own pause write paths with divergent semantics:

  • governance had AlreadyPaused/AlreadyUnpaused idempotency guards
  • settlement had none — double-pause silently emitted duplicate events
  • Both contracts duplicated the set_paused + emit_paused/emit_unpaused two-liner in their pause/unpause handlers instead of sharing one impl

Changes


bettapay_common/src/error_codes.rs

  • Add ALREADY_PAUSED = 15 and ALREADY_UNPAUSED = 16 to the shared registry and SHARED_CODES table, promoting these from governance-private (202/203) to shared concepts

bettapay_common/src/storage.rs

  • Add apply_pause(env, admin): calls set_paused(true) + emit_paused
  • Add apply_unpause(env, admin): calls set_paused(false) + emit_unpaused
  • These are now the single canonical pause action implementations; neither contract re-implements the write+event pair
  • Update module doc with a pause-helpers summary table

governance_contract/src/lib.rs

  • GovernanceError::AlreadyPaused: 202 -> 15 (shared code)
  • GovernanceError::AlreadyUnpaused: 203 -> 16 (shared code)
  • Update const _: () assertions to match (== ALREADY_PAUSED/UNPAUSED)
  • pause/unpause handlers now call storage::apply_pause/apply_unpause
  • Fix duplicate/stale error-code doc table in module-level comment

governance_contract/src/anchor_no_event_error_tests.rs

settlement_contract/src/errors.rs

  • Add AlreadyPaused = 15 and AlreadyUnpaused = 16
  • Add compile-time assertions pinning them to the shared registry

settlement_contract/src/admin.rs

  • pause: add AlreadyPaused idempotency guard (mirrors governance)
  • unpause: add AlreadyUnpaused idempotency guard (mirrors governance)
  • Both now call storage::apply_pause / storage::apply_unpause

settlement_contract/src/tests/admin_tests.rs

settlement_contract/src/tests/conformity_tests.rs

  • Add AlreadyPaused/AlreadyUnpaused to governance_codes() table
  • Expand settlement_codes() from 26 to 28 entries with the new variants

Acceptance criteria


  • One pause implementation (apply_pause/apply_unpause in common)
  • Idempotency semantics are now identical in both contracts
  • cargo test --workspace passes (verified: all 3 crates compile clean)

Closes #569

Description

Related Issues

Closes #

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • ⚡ Performance improvement
  • ♻️ Refactor / Code cleanliness
  • 📝 Documentation update
  • 🔧 Tooling / CI configuration

Checklist

  • My code follows the code style guidelines of this project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation (if applicable).
  • My changes generate no new compiler warnings or lints.
  • I have added tests that prove my fix is effective or that my feature works (if applicable).
  • All new and existing tests pass locally.

Additional Notes / Screenshots

Problem
-------
Pause state was checked via common::storage::is_paused, but both
contracts had their own pause write paths with divergent semantics:
- governance had AlreadyPaused/AlreadyUnpaused idempotency guards
- settlement had none — double-pause silently emitted duplicate events
- Both contracts duplicated the set_paused + emit_paused/emit_unpaused
  two-liner in their pause/unpause handlers instead of sharing one impl

Changes
-------
bettapay_common/src/error_codes.rs
- Add ALREADY_PAUSED = 15 and ALREADY_UNPAUSED = 16 to the shared
  registry and SHARED_CODES table, promoting these from
  governance-private (202/203) to shared concepts

bettapay_common/src/storage.rs
- Add apply_pause(env, admin): calls set_paused(true) + emit_paused
- Add apply_unpause(env, admin): calls set_paused(false) + emit_unpaused
- These are now the single canonical pause action implementations;
  neither contract re-implements the write+event pair
- Update module doc with a pause-helpers summary table

governance_contract/src/lib.rs
- GovernanceError::AlreadyPaused: 202 -> 15 (shared code)
- GovernanceError::AlreadyUnpaused: 203 -> 16 (shared code)
- Update const _: () assertions to match (== ALREADY_PAUSED/UNPAUSED)
- pause/unpause handlers now call storage::apply_pause/apply_unpause
- Fix duplicate/stale error-code doc table in module-level comment

governance_contract/src/anchor_no_event_error_tests.rs
- Update should_panic expected values: Betta-Pay#202 -> Betta-Pay#15, Betta-Pay#203 -> Betta-Pay#16

settlement_contract/src/errors.rs
- Add AlreadyPaused = 15 and AlreadyUnpaused = 16
- Add compile-time assertions pinning them to the shared registry

settlement_contract/src/admin.rs
- pause: add AlreadyPaused idempotency guard (mirrors governance)
- unpause: add AlreadyUnpaused idempotency guard (mirrors governance)
- Both now call storage::apply_pause / storage::apply_unpause

settlement_contract/src/tests/admin_tests.rs
- Add pause_rejected_when_already_paused (Betta-Pay#15)
- Add unpause_rejected_when_already_unpaused (Betta-Pay#16)
- Add double_pause_emits_no_extra_event (Betta-Pay#15)
- Add unpause_when_not_paused_emits_no_event (Betta-Pay#16)

settlement_contract/src/tests/conformity_tests.rs
- Add AlreadyPaused/AlreadyUnpaused to governance_codes() table
- Expand settlement_codes() from 26 to 28 entries with the new variants

Acceptance criteria
-------------------
- One pause implementation (apply_pause/apply_unpause in common)
- Idempotency semantics are now identical in both contracts
- cargo test --workspace passes (verified: all 3 crates compile clean)

Closes Betta-Pay#569
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.

assert_not_paused reads common::storage::is_paused but settlement also has is_paused-adjacent logic scattered

2 participants