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.
| Flag | An authority can | Reachable through |
|---|---|---|
| MINTABLE | Create supply without limit, diluting every holder | mint |
| SEIZABLE | Destroy any account's balance, consent not required | burn |
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.
| Role | Can | Reachable through |
|---|---|---|
| MINT_ROLE | Mint without limit | mint |
| SEIZE_ROLE | Burn from any account | burn |
| FEE_CONFIG_ROLE | Set the rate, cap, vault and exemptions | setFeeConfig, setFeeVault, setFeeExempt |
| RESTRICTION_ROLE | Pause all transfers; freeze any account | setTransfersPaused, setFrozen |
| HOOK_CONFIG_ROLE | Install, replace or remove the hook | setTransferHook |
| METADATA_ROLE | Write the on-chain store and the token URI | setMetadata, setTokenURI |
| UPGRADER_ROLE | Replace the implementation, on upgradeable tokens | upgradeToAndCall |
| DEFAULT_ADMIN_ROLE | Grant or revoke every role above, including itself | grantRole, 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.