XCHAIN Genesis & Reward-Pool Funding
This runbook describes how the XCHAIN gas token comes into existence at the genesis ledger bootstrap, how the operator later opens public minting, and how to seed and maintain the validator reward pool. XCHAIN exists on the BTC chain only.
This is live. BTC mainnet genesis activated at block 950,000 with the XCHAIN token injected as genesis token #1. The sections below describe the shipped mechanics; the operator-facing steps that remain are the launch open-mint and reward-pool management.
Monetary model (why)
- Hard-capped supply. XCHAIN has a permanent
MAX_SUPPLYof 100,000,000 (8 decimals), fixed at genesis. There is no pre-mint: supply starts at zero and is created only through publicMINTs during the launch window, up to the cap. - Fair-mint distribution. Once the mint window opens, anyone can
MINTtheir share; there is no operator allocation minted upfront.ISSUEof XCHAIN stays GAS-only and BTC-only, so only the operator can author the token’s caps and window, but minting itself is public. - Rewards are paid, not minted. Validator rewards are paid by debiting a pre-funded reward
pool address (
config['ADDRESS']['REWARD']) and crediting the validator. See COLLECT and GAS. - Manual top-ups. The pool is a finite balance; the operator refills it with ordinary XCHAIN
SENDs. If it runs dry,COLLECTreturnsinvalid: insufficient reward pooland validators retry after a top-up. No rewards are lost.
How genesis creates the token
The token is not created by an operator-broadcast transaction. When an indexer parses the
pinned genesis block, src/genesis.js injects a synthetic GAS-signed ISSUE as the first
genesis action:
| Parameter | Value | Why |
|---|---|---|
TICK |
XCHAIN |
The reserved gas tick |
MAX_SUPPLY |
100000000 |
Permanent cap |
DECIMALS |
8 |
Editable until the first mint (locked once SUPPLY > 0) |
MINT_SUPPLY |
empty | No pre-mint; supply starts at 0 |
| owner | GAS address | Only GAS can re-ISSUE (tune caps / open the window) |
MINT_START_BLOCK |
999999999 |
Far-future sentinel: the token exists but is un-mintable until the operator lowers this |
The same genesis pass replays the Counterparty (BTC) and Dogeparty (DOGE) asset-name
ownership snapshots onto the XChain ledger: name reservations only, no balances. Genesis is
pinned per network in the coin registry (src/coins/BTC.js / DOGE.js): BTC mainnet block
950,000, DOGE mainnet block 6,240,000, each with a ledgerHash (bundled CSV manifest) and
dumpHash (bundled state dump) that every indexer verifies. The dumps ship inside the Docker
image. LTC and all testnets/regtest launch clean (genesis disabled); regtest can opt in via
the XCHAIN_GENESIS_BLOCK / XCHAIN_GENESIS_LEDGER_HASH / XCHAIN_GENESIS_DUMP_HASH env
overrides.
Step 1: Open the mint (launch)
Minting is governed entirely by the token’s own genesis parameters. To open the launch window,
broadcast a GAS-signed ISSUE for XCHAIN that lowers MINT_START_BLOCK to the launch height,
optionally setting MAX_MINT (per-tx cap) and MINT_ADDRESS_MAX (per-address cap). Because
decimals stay editable while supply is zero, this launch ISSUE can still tune parameters.
Until then, any MINT fails invalid: MINT_START_BLOCK. After the window opens, MINTs are
public and bounded by MAX_SUPPLY (invalid: mint exceeds MAX_SUPPLY past the cap) and the
per-tx / per-address caps if set.
Guard the GAS key like a treasury key. It cannot mint anyone’s XCHAIN, but it authors the mint window and caps.
Step 2: Seed the reward pool
SEND the reward-pool allocation of XCHAIN (acquired through the public mint like anyone else,
or from protocol fee income) to config['ADDRESS']['REWARD'].
The reward-pool address is keyed (operator-controlled), but its key is not needed for normal
operation: COLLECT drains it purely through protocol ledger accounting. The key only matters if
you ever need to move funds out of the pool manually.
Step 3: Ongoing top-ups
Refill the pool at any time by sending XCHAIN to the reward-pool address (treasury → pool). No
special action type; a plain SEND. The next COLLECT immediately sees the higher balance.
stateDiagram-v2
[*] --> Empty
Empty --> Funded: Seed, SEND to reward-pool address
Funded --> Funded: COLLECT drains the pool, validator credited
Funded --> Depleted: Pool balance reaches zero
Depleted --> Depleted: COLLECT fails, invalid insufficient reward pool
Depleted --> Funded: Top-up, SEND replenishes the pool
Verification
- Token exists with the right shape: query the indexer
tokenstable fortick='XCHAIN': expectmax_supply = 100000000,decimals = 8, owner = the GAS address, and (pre-launch)supply = 0with the sentinelMINT_START_BLOCK. - Mint gate holds: before the window opens, a
MINTof XCHAIN failsinvalid: MINT_START_BLOCK; anISSUEof XCHAIN from any non-GAS address fails. - Genesis pin verified: indexer startup logs confirm the genesis
ledgerHash/dumpHashmatch the pinned values; a mismatch is a fatal error, not a warning. - Pool funded: the reward-pool address balance equals the seed allocation.
- Reward lifecycle (regtest e2e): stake → accrue a reward →
COLLECT(pool drops by the reward, validator rises by the same, total supply unchanged) → drain pool →COLLECT(invalid: insufficient reward pool) → top up →COLLECT(succeeds).
Monitoring
The reward pool is finite between top-ups. Its drain rate is governed by the hub reward schedule
(ORACLE_REWARD_PER_ROUND and the per-capability reward types in
xchain-indexer/src/api.js:pushvalidatorrewards). Watch the reward-pool balance and top up
before it depletes; otherwise validators see COLLECT rejections (they retry later, but rewards
stall). A balance threshold alert/monitor is recommended.
Copyright © 2025–2026 Dankest, LLC
Based on XChain Platform by Dankest, LLC – https://dankest.llc
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later) with a commercial license available for proprietary use.