A B20 token moves through four practical phases: create, bootstrap, operate, and optionally renounce administration.
Create
All B20 tokens are created through the singleton factory:
variant is ASSET or STABLECOIN.
salt contributes to deterministic address derivation.
params are versioned by a leading byte and encoded with B20FactoryLib.
initCalls are ABI-encoded calls that run on the new token before the factory returns.
The factory reverts with FeatureNotActivated if the requested token variant is not active on the chain.
Bootstrap with initCalls
During the creation transaction, factory-originated initCalls bypass token role gates and transfer-side policy gates. This lets you configure policy scopes, grant roles, set caps, and seed balances atomically.
The bypass is deliberately limited:
MINT_RECEIVER_POLICY is always enforced, including during initCalls.
- Pause state is never bypassed.
- Token invariants such as supply cap and balance accounting are never bypassed.
If you start the token paused, put pause(...) late in the initCalls array so earlier bootstrap operations are not blocked by your own pause.
Operate
Common issuer operations include:
- Minting with
MINT_ROLE, subject to MINT_RECEIVER_POLICY and supplyCap.
- Burning from the caller with
BURN_ROLE.
- Seizing with
SEIZE_ROLE through seizeWithMemo when the holder is denied by SEIZE_HOLDER_POLICY.
- Pausing
TRANSFER, MINT, BURN, or SEIZE independently.
- Updating name, symbol, and contract URI with
METADATA_ROLE.
The PausableFeature enum is append-only. Integrators should handle unknown future values defensively when switch-casing over returned pause data.
Freeze and seize
seizeWithMemo transfers a holder’s balance to a destination in one admin operation. It skips allowance and transfer policies; its membership check is SEIZE_HOLDER_POLICY.
The transaction emits Transfer, Memo, and Seized in order.
Pause and unpause
Paused operations revert with ContractPaused(feature).
Memos
Memos are bytes32 payloads emitted immediately after the primary event of a memo-enabled operation.
Memo entrypoints:
transferWithMemo
transferFromWithMemo
mintWithMemo
burnWithMemo
seizeWithMemo
Indexers join a Memo log to the operation it annotates with (transactionHash, logIndex - 1).
Admin renunciation
If an issuer wants an admin-less token, it must grant surviving operational roles, bind required policies, and set the supply cap before calling renounceLastAdmin(). After renunciation, admin-gated configuration cannot be restored.