Skip to content

fix: pool pause() is not idempotent — can be called multiple times with no error #376

@thewealthyplace

Description

@thewealthyplace

Bug

contracts/pool/src/lib.rspause() sets a Paused storage flag to true but does not check whether the contract is already paused. Calling pause() on an already-paused contract:

  1. Succeeds silently (no error, no event distinguishing a double-pause from first pause)
  2. Wastes gas on a no-op write
  3. Could confuse monitoring systems that count pause events

Same issue applies to unpause() on an already-unpaused contract.

Fix

pub fn pause(env: &Env, admin: Address) {
    admin.require_auth();
    verify_admin(&env, &admin);
    
    if is_paused(&env) {
        return Err(PoolError::AlreadyPaused);
    }
    
    env.storage().persistent().set(&DataKey::Paused, &true);
    env.events().publish((Symbol::new(&env, "POOL"), Symbol::new(&env, "paused")), admin);
}

pub fn unpause(env: &Env, admin: Address) {
    admin.require_auth();
    verify_admin(&env, &admin);
    
    if !is_paused(&env) {
        return Err(PoolError::NotPaused);
    }
    
    env.storage().persistent().set(&DataKey::Paused, &false);
    env.events().publish((Symbol::new(&env, "POOL"), Symbol::new(&env, "unpaused")), admin);
}

Apply the same fix to the invoice and credit score contracts.

Acceptance Criteria

  • pause() returns AlreadyPaused when already paused
  • unpause() returns NotPaused when already unpaused
  • Applied to all three contracts
  • Unit tests for idempotency cases

References

  • contracts/pool/src/lib.rs, contracts/invoice/src/lib.rs, contracts/credit_score/src/lib.rspause(), unpause()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions