Modules

Five modules, five responsibilities

CenterChain is a Cosmos SDK application chain with five modules of its own. They sit on top of the standard SDK modules, and several of them replace a stock behaviour: the token factory installs the bank send restriction and owns the NFT transfer policy.

How they fit together

  • The token factory is the base layer. Every other CenterChain module creates or administers a denom through it.
  • Liquidity mints LP shares through the token factory, and the LP denom is fixed tofactory/liquidity/pool/{pool_id}.
  • The NFT market and income both hook NFT burns. A burn refunds the seller deposit and releases the token earmark back into the shared yield pool.
  • Income settles on every bank send. It prepends its own send restriction so a holder accrual is checkpointed against the pre-transfer balance.

tokenfactory

Token Factory

The base layer of CenterChain. Any account creates and administers its own bank-native denom, decides who may hold or receive it, and authorizes a swap between two denoms.

Consensus version 2

  • A denom is factory/{creator}/{subdenom}, and the creating account becomes its first admin. Creating a denom writes bank denom metadata, a DenomAuthorityMetadata record and a creator-to-denom index entry.
  • The denom creation fee is 10000000ucen by default and is burned unless community-pool funding is enabled. The create path also consumes 2000000 extra gas.
  • factory/liquidity/pool/{pool_id} is a reserved namespace. A genesis file may contain such a denom only when the liquidity module account administers it and it matches a registered pool id, which is what stops an account from minting a counterfeit LP share.
  • Caps: subdenom 44 bytes, creator segment 75 bytes, 100,000 denoms and 100,000 blacklisted addresses across the chain.

Who uses it.The denom admin, a delegate, and any holder who wants to move one token into another.

liquidity

Liquidity

A constant-product automated market maker. It holds two-denom pools, mints LP shares through the token factory, and governs the whole pool lifecycle.

Consensus version 5

  • The LP share denom is always factory/liquidity/pool/{pool_id} and is only ever administered by the liquidity module account.
  • Every number is an integer and every division floors. The fee scale is 1,000,000 parts per million, and a message that leaves the field empty defaults to a 3,000 ppm swap fee, 300,000 ppm to LPs and 700,000 ppm to stakers.
  • A swap too small to cover its own fee is rejected rather than rounded to a zero output.
  • Caps: 10,000 pools, 10,000 farm positions with 1,000 per pool, 100,000 lots with 10,000 per position, 64 denoms per fee record.

Who uses it.The pool owner and the liquidity providers who stake their LP shares.

nftrwa

NFT

An overlay on the stock cosmossdk.io/x/nft keeper that adds the rules a real world asset needs: an issuer-scoped class id, a technical issuer, sequential token ids, immutable metadata and a lock other modules can escrow with.

Consensus version 1

  • A class id is {issuer}/{product_ref}. The first segment must be the signer own bech32 address, both segments are printable ASCII, the separator appears exactly once and neither side may contain a slash.
  • A token id is {class_id}/{sequence}. The sequence is a per-class counter that starts at 1 and only ever increases, and the module assigns it rather than the sender choosing it.
  • token_metadata_immutable is fixed when the class is created. When it is set, MsgSetNFTMetadata fails with ErrImmutableTokenMetadata, but only after the sender is confirmed as the class issuer.
  • The lock is the escrow other modules use: the holder keeps ownership and nobody else can move or burn the token until it is released.

Who uses it.The technical issuer of a class and the holder of a token.

nftmarket

NFT Market

A fixed-price secondary market for the tokens the NFT module creates. It charges no protocol fee.

Consensus version 1

  • The seller keeps ownership while the listing is live. The token is locked under the order id nftmarket/{listing_id}, which stops the seller transferring or burning it out from under the listing.
  • The listing deposit is 1000000ucen by default, must be denominated in ucen, and is backed by an invariant: the module account balance must always equal the sum of active listing deposits.
  • Every listing has an expiry. Leaving expiry_height at zero substitutes the default duration of 100,000 blocks, and no listing may be created further ahead than the 1,000,000 block maximum.
  • A purchase never burns. If the royalty consumes the whole price the result is ErrRoyaltyInvalid rather than a zero payment.
  • Caps: 10,000 active listings, 2,048 bytes per listing, 32 accepted denoms per class.

Who uses it.The technical issuer who enables a class for trading, the seller and the buyer.

income

Income

Distributes income to the holders of a denom and pays the claimable amounts attached to individual NFTs. It stores distribution state, never a schedule: the chain does not know a coupon calendar.

Consensus version 1

  • Fungible balances use a reward-per-share accumulator. Funds go to a yield address, a single global index for the eligibility and reward pair moves, and a holder right becomes arithmetic against the balance.
  • NFTs use an earmarked claimable. An administrator pushes a per-token amount and the claim is paid from the same yield pool on the holder instruction.
  • Accounting is lazy. There is no per-block sweep and no reward is lost because a holder did not claim.
  • Every 10,000 blocks EndBlock checks that every yield pool holds at least the total unpaid liability for its reward denom, including holders who were never checkpointed and the active NFT earmarks.
  • Caps: 1,000 streams and 50 NFT claims per message.

Who uses it.The holder, the denom admin, the class issuer and the income managers set through the income_admins parameter.

Where the rules live

The modules are only half of the chain. The other half is the single function every send passes through, and it is what a sender actually feels.