betterERC
Docs/Integrating

Mintable and seizable

The two bits nothing reveals until they are used, who holds them, and the question that has to be answered before any other separation of keys means anything.

All docs

The flags on the pages above all describe what a transfer does, which means a determined integrator could have discovered them by simulating one. These two are different. Supply growing and a balance vanishing are not transfers you could have screened, and nothing about the token reveals either power until somebody uses it.

FlagAn authority canReachable through
MINTABLECreate supply without limit, diluting every holdermint
SEIZABLEDestroy any account's balance, consent not requiredburn

Every token in this framework sets both, unconditionally. The functions live on the shared base beneath every module, so no extension set can remove them, and a token that reported zero while holding these keys would be making the vocabulary's strongest claim while omitting its most expensive facts.

What this changes if you lend

A frozen borrower is not merely a borrower who cannot move collateral. A freeze is usually the step immediately before a burn, and the burn works on a frozen account by design — a freeze that blocked burning could never be settled. So the collateral behind a position can be destroyed rather than stuck.

Treat accountState(borrower).frozen as a liquidation-relevant signal, not only as a transfer-time check.

The question that comes first

The reference tokens split minting from seizing, and split both from fee configuration, restriction and metadata. That bounds the damage from one compromised operator, and it is worth having. It is not a structural limit.

RoleCanReachable through
MINT_ROLEMint without limitmint
SEIZE_ROLEBurn from any accountburn
FEE_CONFIG_ROLESet the rate, cap, vault and exemptionssetFeeConfig, setFeeVault, setFeeExempt
RESTRICTION_ROLEPause all transfers; freeze any accountsetTransfersPaused, setFrozen
HOOK_CONFIG_ROLEInstall, replace or remove the hooksetTransferHook
METADATA_ROLEWrite the on-chain store and the token URIsetMetadata, setTokenURI
UPGRADER_ROLEReplace the implementation, on upgradeable tokensupgradeToAndCall
DEFAULT_ADMIN_ROLEGrant or revoke every role above, including itselfgrantRole, revokeRole

The last row is the one that matters most and gets read least. The admin role can hand itself any other role, so "the fee key is separate from the freeze key" limits an operator error and does not limit the owner. Find out who holds it, and whether it sits behind a timelock, before relying on any other separation.

You cannot enumerate role holders. hasRole answers about an address you already suspect; building the full list means replaying RoleGranted and RoleRevoked from the deployment block.