Skip to main content

cougr_core/standards/
pausable.rs

1use soroban_sdk::{contracttype, Address, Env, Symbol};
2
3use super::error::StandardsError;
4
5const PAUSED_PREFIX: &str = "std_pause";
6
7/// Pause state primitive for emergency stops.
8#[derive(Clone, Debug)]
9pub struct Pausable {
10    id: Symbol,
11}
12
13#[contracttype]
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct PausedEvent {
16    pub account: Address,
17}
18
19#[contracttype]
20#[derive(Clone, Debug, Eq, PartialEq)]
21pub struct UnpausedEvent {
22    pub account: Address,
23}
24
25impl Pausable {
26    pub fn new(id: Symbol) -> Self {
27        Self { id }
28    }
29
30    pub fn is_paused(&self, env: &Env) -> bool {
31        env.storage()
32            .persistent()
33            .get(&self.paused_key(env))
34            .unwrap_or(false)
35    }
36
37    pub fn require_paused(&self, env: &Env) -> Result<(), StandardsError> {
38        if self.is_paused(env) {
39            return Ok(());
40        }
41        Err(StandardsError::NotPaused)
42    }
43
44    pub fn require_not_paused(&self, env: &Env) -> Result<(), StandardsError> {
45        if self.is_paused(env) {
46            return Err(StandardsError::Paused);
47        }
48        Ok(())
49    }
50
51    pub fn pause(&self, env: &Env, caller: &Address) -> Result<PausedEvent, StandardsError> {
52        if self.is_paused(env) {
53            return Err(StandardsError::Paused);
54        }
55        env.storage().persistent().set(&self.paused_key(env), &true);
56        Ok(PausedEvent {
57            account: caller.clone(),
58        })
59    }
60
61    pub fn unpause(&self, env: &Env, caller: &Address) -> Result<UnpausedEvent, StandardsError> {
62        if !self.is_paused(env) {
63            return Err(StandardsError::NotPaused);
64        }
65        env.storage()
66            .persistent()
67            .set(&self.paused_key(env), &false);
68        Ok(UnpausedEvent {
69            account: caller.clone(),
70        })
71    }
72
73    fn paused_key(&self, env: &Env) -> (Symbol, Symbol) {
74        (Symbol::new(env, PAUSED_PREFIX), self.id.clone())
75    }
76}