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 Cap: 43,830 Tokens
The APOW supply cap is 43,830 tokens (with 18 decimals:
Breaking this down:
The denominator of 20 represents the smallest NFT denomination step (
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:
Banq(sovLink, 43_830 * 10 ** APower(sovLink).decimals())Inside _banq(), before tokens are supplied to the pool, the total supply is checked:
if (_token.totalSupply() > _free_supply) {
revert Capped(_free_supply);
}This check runs atomically with every mint operation — if total supply would exceed the cap, the entire transaction reverts. There is no possibility of a race condition or partial mint beyond the cap.
Migration Exclusion
The SovMigratable contract (used during APOW migration from legacy contracts) sets _free_supply = 0. This is intentional and correct:
- Migrated tokens were already subject to the cap when originally minted
- Re-enforcing the cap during migration would double-count existing supply
- Setting the cap to 0 effectively disables the check (since
0 ≥ totalSupplyis 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:
Where
The expected XPOW per hash is:
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
Treasury Balance Cap
The APOW supply cap constrains the total amount of APOW that can ever exist, 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:
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:
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 cap is a hard stop — no execution path can exceed it, regardless of reward formula errors.
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 Cap
When totalSupply() > 43_830 × 10^18:
- All
claim()andclaimBatch()calls revert withCapped(43_830 * 10^18) - Stakers can still accumulate claimable rewards (the
_claimedcounter 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() > 0will 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 supply cap is not hardcoded as an immutable constant beyond deployment. However, changes are constrained by the role hierarchy and Rpp (Rug Pull Protection) contract:
Role Hierarchy
| Role | Capability |
|---|---|
DEFAULT_ADMIN_ROLE | Initialize pool address (init()) |
APR_ROLE | Adjust APR polynomial parameters (indirectly affects mint rate) |
APB_ROLE | Adjust APB polynomial parameters (indirectly affects mint rate) |
The _free_supply parameter is set in the Banq constructor and is immutable — it cannot be changed post-deployment. To change the cap, a new MoeTreasury contract would need to be deployed and the role structure migrated.
Rate-Based Indirect Adjustment
While the supply cap itself is immutable, the rate at which the cap is approached can be adjusted through APR/APB reparametrization. Lower rates mean slower approach; higher rates mean faster approach. These adjustments are bounded by Rpp:
| Rpp Constraint | Limit |
|---|---|
| Value change | 0.5× to 2.0× of current value |
| Time between changes | Minimum 1 month (Constant.MONTH) |
| Array validation | Length 4; div and mul non-zero |
This means the speed of cap approach is governable, but the cap itself is a fixed economic commitment.
Comparison with Other Systems
| System | Total Supply | Issuance | Adjustability |
|---|---|---|---|
| Bitcoin | 21,000,000 BTC | Halving every ~4 years | Immutable (social consensus) |
| Ethereum | Variable (~120M ETH) | Proof-of-stake issuance | Governance-adjustable |
| XPower APOW | 43,830 APOW | ~1 token/min mean | Cap immutable, rate governable |
| XPower XPOW | Unbounded | PoW-probabilistic | Self-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: the cap is fixed, but the approach rate can be tuned — a hybrid of Bitcoin's certainty and Ethereum's flexibility.
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.