Skip to content

Supply Caps

XPower employs a multi-layered supply cap system that constrains APOW (the store-of-value token) while leaving XPOW (the work token) unbounded. This asymmetric design reflects their different economic roles: XPOW represents computational work (inherently unbounded) while APOW represents accumulated time (forecastable and rate-limited).

APOW Free-Supply Cap: 43,830 Tokens

The APOW free-supply cap is 43,830 tokens (with 18 decimals: 43,830×1018 wei). This cap applies only while no lending pool is initialized — once a pool is active, supply enforcement delegates to the pool contract. The value is derived from the target minting rate of 1 token per minute, annualized and divided by twelve:

tokens per year=60×24×365.25=525,960cap=525,9601243,830

The divisor of twelve means the cap represents approximately one month's worth of continuous minting at the base rate of 1 token per minute — providing a sufficient buffer for normal claim activity while preventing unbounded issuance while no lending pool is active.

Pool Transition

The Banq contract supports two operational modes that determine whether the free-supply cap applies:

ModeCap Active?Behavior
pool == address(0) (uninitialized)YestotalSupply() > _free_supply reverts — hard free-supply cap
pool != address(0) (initialized via init())NoTokens sent to pool contract via _supply(); supply governs by pool's own constraints and PoW nonce gate

When DEFAULT_ADMIN_ROLE calls Banq.init(pool), the cap check is replaced by a pool-call with a proof-of-work requirement. This is a one-way transition — once initialized, the pool cannot be unset. Until init() is called, the free-supply cap of 43,830 APOW is strictly enforced.

Cap Enforcement

The cap is enforced by the Banq contract's _free_supply parameter. When MoeTreasury is deployed, it passes the cap to the Banq constructor:

solidity
Banq(sovLink, 43_830 * 10 ** APower(sovLink).decimals())

Inside _banq(), before tokens are supplied to the pool, the total supply is checked:

solidity
if (_token.totalSupply() > _free_supply) {
    revert Capped(_free_supply);
}

This check runs atomically with every mint operation while no pool is configured — if total supply would exceed the free-supply cap, the entire transaction reverts. There is no possibility of a race condition or partial mint beyond the cap while in this state.

Migration Exclusion

The SovMigratable contract (used during APOW migration from legacy contracts) sets _free_supply = 0. This is intentional and correct:

  1. Migrated tokens were already subject to the cap when originally minted
  2. Re-enforcing the cap during migration would double-count existing supply
  3. Setting the cap to 0 effectively disables the check (since 0 ≥ totalSupply is always false when migrating)

XPOW: No Hard Cap

XPOW has no fixed supply cap. Its supply grows with total hash power according to the proof-of-work mining dynamics:

R(z)=(2z1)×1018

Where z is the number of leading zero nibbles found. Since difficulty is probabilistic and miners can always choose to solve higher-difficulty nonces, the supply is unbounded but probability-weighted.

The expected XPOW per hash is:

E[R]=z=1116z×(2z1)×10180.076×1018

This means XPOW supply is effectively constrained by the economic cost of computation. Each token requires approximately 13 Keccak-256 hashes on average, and as difficulty naturally self-selects toward higher z, the cost per token rises. There is no artificial cap because one is not needed — the proof-of-work itself is the limiting factor.

Treasury Balance Cap

The APOW free-supply cap constrains the total amount of APOW while no pool is configured, but a second constraint limits how much can be minted at any given moment: the treasury XPOW balance.

When APOW is minted, XPOW is wrapped:

solidity
function mint(address to, uint256 claim) external onlyOwner returns (uint256) {
    assert(_moe.transferFrom(owner(), address(this), wrappable(claim)));
    ...
}

The wrappable() function clamps the claim to the available treasury balance:

solidity
function wrappable(uint256 claim) public view returns (uint256) {
    uint256 treasury = _moe.balanceOf(owner());
    return Math.min(claim, treasury);
}

This means:

  • APOW minting is capped at min(claim, treasuryBalance) per transaction
  • If the treasury holds 50,000 XPOW but a staker's claimable reward is 100,000, only 50,000 APOW can be minted
  • The remaining 50,000 stays as a pending claim — earnable but not yet mintable until more XPOW flows into the treasury

The treasury accumulates XPOW from the 50% mining split: every successful XPower.mint() sends half of the reward to the treasury owner (set to MoeTreasury). This creates a feedback loop — mining activity funds the treasury, which backs APOW minting, which rewards stakers, whose capital incentivizes more mining.

Economic Rationale

Preventing Runaway Inflation

Without caps, a bug or exploit in the reward calculation could mint unbounded APOW, destroying the token's value. The 43,830 free-supply cap is a hard stop while no lending pool is configured — no execution path can exceed it while in that state, regardless of reward formula errors. Once a pool is initialized, supply constraints become the pool's responsibility.

Maintaining APOW Scarcity

APOW is designed as a store of value with predictable long-term scarcity. The cap creates a known, finite supply that markets can price against — analogous to Bitcoin's 21 million. The difference is that APOW's cap is tighter (43,830 vs. 21 million raw units) and more directly tied to a physical constant (1 token/min × years).

Separation from XPOW

By capping APOW but not XPOW, the system preserves the inflation-hedging properties of the store-of-value token while allowing the work token to scale with network participation. This mirrors central banking models where narrow money is constrained while broad money expands with economic activity.

What Happens When Caps Are Reached

APOW Free-Supply Cap (No Pool)

When totalSupply() > 43_830 × 10^18 and no lending pool is configured:

  • All claim() and claimBatch() calls revert with Capped(43_830 * 10^18)
  • Stakers can still accumulate claimable rewards (the _claimed counter tracks them), but cannot mint
  • Rewards effectively become a claim queue — first to claim when/if the cap is raised gets minted first
  • Burns (burn / burnFrom) continue to function, lowering supply and potentially re-opening mint capacity

Treasury Balance Cap

When wrappable(claim) < claim:

  • The partial wrapper mints only min(claim, treasuryBalance) APOW
  • Remaining claimable amounts stay tracked in _claimed
  • Stakers can claim again later once the treasury refills
  • The mintable() view function returns 0 for any claim that exceeds available treasury

Migration Cap

For migrated tokens, _free_supply = 0 means:

  • The cap check totalSupply() > 0 will trigger if any new supply is minted post-migration
  • This is intentional — migrated tokens are exact mirrors of old supply, not new issuance

Adjustability and Governance

The _free_supply parameter is set in the Banq constructor and is immutable — it cannot be changed post-deployment. To change the free-supply cap, a new MoeTreasury contract would need to be deployed and the role structure migrated.

However, the overall supply constraint can be relaxed by initializing a lending pool. When DEFAULT_ADMIN_ROLE calls Banq.init(pool), the cap check is replaced by pool-governed supply with a PoW nonce gate. Changes are further constrained by the role hierarchy and Rpp (Rug Pull Protection) contract:

Role Hierarchy

RoleCapability
DEFAULT_ADMIN_ROLEInitialize pool address (init())
APR_ROLEAdjust APR polynomial parameters
APB_ROLEAdjust APB polynomial parameters

Self-Adjusting Issuance

Unlike the cap, the APOW issuance rate is not governable — it always self-adjusts toward approximately 1 token per minute via the square-root smoothed exponential moving average built into APower.mint(). No governance action can alter this target rate or the convergence mechanics.

Comparison with Other Systems

SystemTotal SupplyIssuanceAdjustability
Bitcoin21,000,000 BTCHalving every ~4 yearsImmutable (social consensus)
EthereumVariable (~120M ETH)Proof-of-stake issuanceGovernance-adjustable
APower APOW43,830 APOW (free-supply cap pre-pool)~1 token/min mean (self-adjusting)Cap immutable, rate self-adjusting
XPower XPOWUnboundedPoW-probabilisticSelf-regulating via miner economics

Bitcoin Comparison

Bitcoin's 21M cap is a fixed constant enforced by the halving schedule. APOW's 43,830 cap serves the same purpose — a known, finite endpoint — but is smaller and more directly tied to a time-based formula. Both systems make the cap a constitutional commitment: changing it requires a hard fork (Bitcoin) or contract redeployment (XPower).

Ethereum Comparison

Ethereum has no fixed cap; supply is governed by the issuance curve, fee burning (EIP-1559), and validator economics. APOW sits closer to Bitcoin on the spectrum: both the cap and the issuance rate are fixed economic commitments with no governance adjustability.

Key Difference: Dual Token

The XPower dual-token model creates an asymmetry absent in single-token systems:

  • XPOW absorbs the uncertainty of unbounded supply (like ETH)
  • APOW provides the certainty of a fixed cap (like BTC)

This separation allows the protocol to serve both roles — medium of exchange and store of value — without the compromises inherent in single-token designs.