Security and governance
What no role can change
Security on CenterChain is mostly a list of things that are refused. Some privileged messages are gated on a capability, some invariants raise an alarm instead of failing a block, and seven rules hold regardless of configuration.
Capabilities
A capability is a module-wide switch configured at wiring time. A message whose capability is absent fails; it is not silently degraded.
enable_metadata
Gates MsgSetDenomMetadata.
enable_force_transfer
Gates MsgForceTransfer.
enable_burn_from
Gates burning from an address other than the sender.
enable_admin_sudo_mint
Gates minting on behalf of a denom by the module authority.
enable_community_pool_fee_funding
Gates sending the denom creation fee to the community pool instead of burning it.
The shipped chain enables all five. enable_admin_sudo_mint is wired with a sudo-admin predicate that always returns false, so the sudo-mint path is not reachable in the default build. Capabilities are deliberately separate from authority: authority answers who, a capability answers whether that action exists at all on this chain.
Invariants that alarm instead of failing
Liquidity, every block
In-memory state invariants.
Liquidity, every 10,000 blocks
Reserve, farm and fee account balances reconciled against bank balances and LP supply.
Income, every 10,000 blocks
Every yield pool holds at least its total unpaid liability, including holders never checkpointed, plus the active NFT earmarks.
A violation emits an alarm event, liquidity_invariant_violation or income_invariant_violation, both carrying the height and the error, and returns no error.
That is deliberate: a returned error from EndBlock aborts finalization, so an alarm would itself become a chain halt. Raising it as an event keeps the chain making progress while making the failure unmissable to a monitor.
The same income check runs at genesis, where it does fail, because there is no prior state to continue from. The NFT market deposit invariant is implemented and exercised by tests but is not registered with the crisis module, so it does not run automatically.
State limits
Every module caps the size of its collections, and the caps are checked before any transfer, not after. A swap that would create a 65th fee denom on a record already holding 64 is rejected with the accrued fees untouched.
Token factory
100,000 denoms, 100,000 pool policy records, 100,000 blacklisted addresses.
Liquidity
10,000 pools; 10,000 farm positions with 1,000 per pool; 100,000 lots with 10,000 per position; 10,000 reward records per pool; 64 denoms per record.
NFT market
10,000 active listings, 2,048 bytes per listing, 32 accepted denoms per class.
Income
1,000 streams, 50 NFT claims per message.
What governance can reach
The gov module account is every module authority. It can:
- Change any module parameters.
- Move an NFT class issuer.
- Emergency-pause or close a liquidity pool, and activate an emergency ownership transfer.
- Register or remove an IBC denom, which gates risk-increasing operations on that asset.
- Set the token factory pool denylist.
- Set the income income_admins list through a parameter change.
A denied pool ownership transfer is the exception worth knowing. Governance can start the emergency path but the pool owner has no way to cancel it, while governance cannot start the normal path. A cooperative handover and a recovery are separate on purpose.
Immutable rules
These hold regardless of configuration, and no role bypasses them.
- 01
A blacklist entry is absolute. No role, including governance, can send or receive a blacklisted denom.
- 02
A consumed authorization is final. No role can un-consume one or revive a used sequence number.
- 03
Sequence numbers are never reused. Pruning an expired authorization does not return its order_seq to the available space.
- 04
The output of a swap always goes to the holder. The executor cannot redirect it.
- 05
A class metadata immutability flag cannot be changed. It is fixed at creation and no message alters it.
- 06
Pool close and retirement are one-way. Closing clears every pending fee and ownership change, and retirement deletes the pool.
- 07
Alarms never halt the chain. An invariant violation is an event, not a failed block.
Requirements on an integrator
- Mirror state, do not infer it. Several messages emit no event, including MsgSetNFTMetadata, blacklist changes, delegate changes and parameter updates. Re-query rather than waiting for the event stream.
- Be idempotent. Deduplicate on the order id for swaps, the listing id for the market, and the transaction hash for everything else.
- Reconcile. On-chain events are the source of truth, and an off-chain index is a cache that must be rebuildable from them.
- Simulate. The ante chain returns the same rejections in simulation that DeliverTx will, so a dry run is meaningful.
What is not published
No security review and no bug bounty program has been published. Internal engineering documents, including security reviews, are held outside the published documentation on purpose. This page lists what the chain itself enforces and nothing that has not been written down and released.
The published network is centerchain-testnet-1 with four validators on a single host, and its tokens are valueless. There is no main network.