Docs Técnicas
Institution Token
A fungible token issued by a financial institution. Combines BasicToken (supply tracking) and Ownable (single-owner access control) via static composition.
A fungible token issued by a financial institution. Combines BasicToken (supply tracking) and Ownable (single-owner access control) via static composition.
Use this contract when a bank needs to issue a custom asset — loyalty points, digital reais, promissory notes — with a single authorized issuer and an optional hard supply cap.
Source
import std.token.BasicToken
import std.access.Ownable
contract InstitutionToken impl BasicToken, Ownable:
storage:
# inherited: total (u128), owner (Address)
token_name: String
token_symbol: String
decimals: u64 = 6
cap: u128 = 0
balances: Map[Address, u128, 4096]
@construct
def initialize(name: String, symbol: String, token_decimals: u64, initial_owner: Address):
self.token_name = name
self.token_symbol = symbol
self.decimals = token_decimals
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(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(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 burn(account: Address, amount: u128):
require(ctx.caller == self.owner, "only_owner")
require(amount > 0, "amount_must_be_positive")
require(self.balances[account] >= amount, "insufficient_balance")
self.balances[account] = self.balances[account] - amount
self.total = self.total - amount
@tx
def transfer(to: Address, amount: u128):
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
@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
@view
def cap_limit() -> u128:
return self.capLifecycle
deploy BasicToken, Ownable, InstitutionToken to on-chain registry
instantiate InstitutionToken → contract_id
initialize(name, symbol, 6, owner_address)
# optional hard cap
set_cap(1_000_000_000_000) # 1 000 000 tokens at 6 decimals
# issuance
mint_to(recipient, 500_000_000) # 500 tokens
transfer(other, 100_000_000) # holder-initiated transfer
burn(account, 50_000_000) # owner compliance burnKey Design Points
`override def mint` — BasicToken declares mint as the canonical supply-minting entry point. The override adds the only_owner guard and cap check before crediting balances and incrementing total.
`cap == 0` means uncapped — the check self.cap == 0 or self.total + amount <= self.cap lets the owner start uncapped and set a hard limit later. Once set, the cap cannot be lowered below the current supply.
`mint` vs `mint_to` — mint credits the owner's own balance (useful for vault-based issuance patterns). mint_to credits an arbitrary recipient directly.
Burn is owner-only — holders cannot burn their own tokens. This is intentional for regulated assets where destruction must be auditable.