Voltar para Documentação

Docs Técnicas

Pausable Institution Token

Extends the institution token with an emergency pause switch. Mint and transfer are blocked while the contract is paused; the owner can pause and unpause at will.

O conteúdo abaixo vem das fontes técnicas do repositório e é prerenderizado no site para leitura direta por pessoas, crawlers e agentes.

Extends the institution token with an emergency pause switch. Mint and transfer are blocked while the contract is paused; the owner can pause and unpause at will.

Use this when the issuing institution needs a circuit breaker — for regulatory intervention, incident response, or scheduled maintenance.

Source

python
import std.token.BasicToken
import std.access.Ownable
import std.token.Pausable

contract PausableInstitutionToken impl BasicToken, Ownable, Pausable:
    storage:
        # inherited: total (u128), owner (Address), paused (bool)
        token_name: String
        token_symbol: String
        cap: u128 = 0
        balances: Map[Address, u128, 4096]

    @construct
    def initialize(name: String, symbol: String, initial_owner: Address):
        self.token_name = name
        self.token_symbol = symbol
        self.owner = initial_owner

    @tx
    def set_cap(new_cap: u128):
        require(ctx.caller == self.owner, "only_owner")
        require(new_cap == 0 or new_cap >= self.total, "cap_below_current_supply")
        self.cap = new_cap

    @tx
    override def mint(amount: u128):
        require(self.paused == False, "contract_paused")
        require(ctx.caller == self.owner, "only_owner")
        require(amount > 0, "amount_must_be_positive")
        require(self.cap == 0 or self.total + amount <= self.cap, "cap_exceeded")
        self.balances[ctx.caller] = self.balances[ctx.caller] + amount
        self.total = self.total + amount

    @tx
    def mint_to(to: Address, amount: u128):
        require(self.paused == False, "contract_paused")
        require(ctx.caller == self.owner, "only_owner")
        require(amount > 0, "amount_must_be_positive")
        require(self.cap == 0 or self.total + amount <= self.cap, "cap_exceeded")
        self.balances[to] = self.balances[to] + amount
        self.total = self.total + amount

    @tx
    def transfer(to: Address, amount: u128):
        require(self.paused == False, "contract_paused")
        require(amount > 0, "amount_must_be_positive")
        require(self.balances[ctx.caller] >= amount, "insufficient_balance")
        self.balances[ctx.caller] = self.balances[ctx.caller] - amount
        self.balances[to] = self.balances[to] + amount

    @tx
    override def pause():
        require(ctx.caller == self.owner, "only_owner")
        require(self.paused == False, "already_paused")
        self.paused = True

    @tx
    override def unpause():
        require(ctx.caller == self.owner, "only_owner")
        require(self.paused == True, "not_paused")
        self.paused = False

    @view
    def balance_of(account: Address) -> u128:
        return self.balances[account]

    @view
    def name() -> String:
        return self.token_name

    @view
    def symbol() -> String:
        return self.token_symbol

Lifecycle

# normal operation
initialize("Real Digital", "BRL", owner)
mint_to(customer, 1_000_000)
transfer(merchant, 500_000)

# emergency pause
pause()
# → mint_to / transfer now reject with "contract_paused"

# resume
unpause()

Key Design Points

`paused` check goes first — every mutating function checks self.paused == False before any other guard. This ensures the pause cannot be bypassed by reordering arguments or constructing unusual callers.

`Pausable` overridesPausable exposes pause() and unpause() without access control so any subclass can decide who controls them. The overrides here add only_owner, narrowing the base behavior rather than replacing it.

`paused` is inherited storage — the field lives in the flattened storage namespace. Contracts that compose Pausable do not redeclare it.

Burn is not paused — compliance burns bypass the pause intentionally. If you need to block burns during pause, add the require(self.paused == False, ...) guard to the burn function as well.