Ownership and authority
CenterChain distinguishes three authorities that are often all called "owner". Keeping them apart is the difference between a correct integration and one that loses funds.
| Layer | Held by | Governs |
|---|---|---|
| Denom admin | The account that created a token factory denom | Mint, burn, force transfer, metadata, restriction, delegates, blacklist, poolability |
| Class issuer | The account named in an NFT class id | Mint, burn, metadata, and the class market configuration |
| Pool owner | The account that created a liquidity pool | Pause, fees, ownership transfer, emission schedules, coin recovery |
Above them all is the module authority, the gov module account. It is the
only signer that can change a module parameter, move a class issuer, register an
IBC denom, emergency-pause or close a pool, or recover a pool's IBC-denom
coins.
How an authority is bound to its scope
A denom admin is stored in that denom's DenomAuthorityMetadata, so it travels
with the denom and not with the account's other denoms.
A class issuer is bound structurally: the class id's first segment must be the
issuer's own bech32 address, and MsgCreateClass only accepts a class id whose
prefix is the sender. An account cannot create a class inside another account's
namespace.
A pool owner is a field on the pool, and it can be transferred — with a cooldown, through a two-step request and accept.
In all three cases the check is a direct address comparison inside the message
handler. There is no authz grant, and none of these modules calls the authz
keeper.
Changing an authority
| Transition | How | Delay |
|---|---|---|
| Denom admin | MsgChangeAdmin, signed by the current admin | None. It is immediate and irreversible by the old admin. |
| Class issuer | MsgChangeClassIssuer, signed by the module authority | None. |
| Pool owner | MsgRequestOwnershipTransfer then MsgAcceptOwnershipTransfer by the nominee | ownership_cooldown_blocks, default 720. Either side can cancel. |
| Pool owner, emergency | MsgRequestEmergencyOwnershipTransfer then MsgActivateEmergencyOwnershipTransfer by the authority | emergency_ownership_cooldown_blocks, default 720. The owner has no cancel path. |
The normal and emergency pool-ownership paths are deliberately separate: the first is a cooperative handover, the second is a recovery when the owner is unavailable. Governance can start the second but not the first, and the owner can cancel the first but not the second.
What an authority cannot do
- No authority bypasses a blacklist. A denom admin cannot send to a
blacklisted address or from one, and neither can
gov. - No authority can list an NFT on a market the class has not enabled. The
class issuer sets
secondary_enabled; nothing above it bypasses that. - No authority can change a class's metadata immutability flag. It is fixed at creation.
- No authority can resurrect a consumed authorization. Single use is not revocable by any role.
- Authority does not confer legitimacy. A denom can have an admin and still be one nobody wants to hold. The chain stores the fact; whether a token is trustworthy is not a question it answers.
Income authority
The income module accepts a message from four sources:
- The module authority.
- An address in the module's configured
income_adminslist. - The token factory admin of the eligibility denom.
- The class issuer, when the denom is an NFT class id.
On the default build the income_admins list is empty, so in practice only
gov and the relevant denom admin or class issuer can register, distribute, or
push.
Why the word owner is avoided
A single "owner" field would have to mean minting, burning, transferring, pricing, and listing at once. Those are different powers with different blast radii and different failure modes. Separating them means a compromise of one is not a compromise of all.