Skip to content

Contract Reference

Core Contracts

XPower (moe) — Proof-of-Work Token

Source: source/contracts/XPower.sol:19Inheritance: ERC20Permit, ERC20Burnable, MoeMigratable, OwnableStandards: ERC20, EIP-2612 (permit), ERC165

Key Functions

solidity
function init() external;

Caches the most recent block hash (blockhash(block.number - 1)) and its timestamp into a 1-hour interval slot. Must be called before mint() for each interval. Emits Init(bytes32 blockHash, uint256 timestamp).

solidity
function mint(address to, bytes32 blockHash, bytes calldata data) external;

Verifies a proof-of-work nonce and mints tokens. data contains the nonce. Requirements:

  • blockHash must be recent (within current 1-hour interval)
  • The (nonceHash, blockHash) pair must be unique (duplicate prevention)
  • The nonce hash must have at least 1 leading zero nibble
  • Mints (2^zeros - 1) * 10^18 XPOW to both to and owner()
solidity
function blockHashOf(uint256 interval) external view returns (bytes32);
function currentInterval() public view returns (uint256);
function decimals() public view virtual override returns (uint8);

Events

EventParameters
Initbytes32 indexed blockHash, uint256 timestamp

Custom Errors

ErrorTrigger
DuplicatePairIndex(bytes32 pair_index)Nonce+block pair already used
ExpiredBlockHash(bytes32 block_hash)Block hash outside current hour
EmptyNonceHash(bytes32 nonce_hash)Nonce produced zero leading zeros

Internal Logic

  • _hashOf(address to, bytes32 blockHash, bytes data) — computes keccak256(address(this) ^ to, blockHash, data) → returns (nonceHash, nonceHash ^ blockHash) for pair-index uniqueness
  • _zerosOf(bytes32 nonceHash) — counts leading zero hex nibbles via 63 - (log2(nonceHash) >> 2)
  • _amountOf(uint256 level) — reward formula: (2^level - 1) * 10^decimals

XPowerNft (nft) — Deposit Receipt NFT

Source: source/contracts/XPowerNft.sol:11Inheritance: NftBaseERC1155, ERC1155Supply, ERC1155Burnable, URIMalleable, NftRoyalty, NftMigratable, OwnableStandards: ERC1155, EIP-2981 (royalty), ERC165

Key Functions

solidity
function mint(address account, uint256 level, uint256 amount) external;

Mints amount of NFTs at level for account. Transfers amount * denominationOf(level) XPOW from account to the contract as deposit. NFT ID = 100 * year() + level.

solidity
function mintBatch(address account, uint256[] memory levels, uint256[] memory amounts) external;

Batch mints across multiple levels. Sums total XPOW deposit and transfers in single transferFrom.

solidity
function burn(address account, uint256 id, uint256 amount) public override;

Burns amount of id NFTs from account. Returns the underlying XPOW deposit back to account. Only succeeds if the NFT is redeemable: yearOf(id) + 2^(levelOf(id)/3) - 1 <= year() or emigration is open.

solidity
function burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) public override;

Batch burn with pre-check that all IDs are redeemable.

solidity
function upgrade(address account, uint256 anno, uint256 level, uint256 amount) external;

Upgrades amount * 1000 NFTs at level - 3 to amount NFTs at level. Requires level > 2. Example: 1000× level-3 → 1× level-6, 1000× level-6 → 1× level-9.

solidity
function upgradeBatch(address account, uint256[] memory annos, uint256[][] memory levels, uint256[][] memory amounts) external;

Batch upgrade across multiple years and levels.

solidity
function approveMint(address operator, bool approved) external;
function approveUpgrade(address operator, bool approved) external;

Delegation: allows operator to mint or upgrade on behalf of caller.

solidity
function approvedMint(address account, address operator) public view returns (bool);
function approvedUpgrade(address account, address operator) public view returns (bool);
function idBy(uint256 anno, uint256 level) public pure returns (uint256);
function idsBy(uint256 anno, uint256[] memory levels) public pure returns (uint256[] memory);
function denominationOf(uint256 level) public pure returns (uint256);
function levelOf(uint256 nftId) public pure returns (uint256);
function yearOf(uint256 nftId) public pure returns (uint256);
function year() public view returns (uint256);

Events

EventParameters
ApproveMintingaddress indexed account, address indexed operator, bool approved
ApproveUpgradingaddress indexed account, address indexed operator, bool approved

Inherited from NftBase/parents: TransferSingle, TransferBatch, ApprovalForAll, URI.

Custom Errors

ErrorTrigger
IrredeemableIssue(uint256 nft_id)Burn attempted before maturity
NonTernaryLevel(uint256 level)Level not divisible by 3

APowerNft (ppt) — Staking Receipt NFT

Source: source/contracts/APowerNft.sol:14Inheritance: NftBase, ReentrancyGuardTransientAccess Control: onlyOwner on mint(), burn(), mintBatch(), burnBatch() — owner is NftTreasury

Key Functions

solidity
function init(address mty) external;

One-time post-constructor init. Sets the MoeTreasury reference. Emits Init(mty).

solidity
function mint(address account, uint256 nftId, uint256 amount) external onlyOwner;
function burn(address account, uint256 nftId, uint256 amount) public override onlyOwner;

Mints/burns staked NFT receipts. onlyOwner restricts to NftTreasury. Updates age accumulators and share accumulators.

solidity
function ageOf(address account, uint256 nftId) external view returns (uint256);

Returns age in seconds: balance * block.timestamp - _age[account][nftId]. Used by MoeTreasury.rewardOf() for reward calculation.

solidity
function shares() external view returns (int256[34] memory);

Returns 34-element array of share accumulators per level tier (level / 3). Each entry accumulates amount * 10^level for mint and subtracts on burn. Used by MoeTreasury.refreshRates().

solidity
function safeTransferFrom(address account, address to, uint256 nftId, uint256 amount, bytes memory data) public override nonReentrant;
function safeBatchTransferFrom(address account, address to, uint256[] memory nftIds, uint256[] memory amounts, bytes memory data) public override nonReentrant;

Overrides ERC1155 transfers to reset age tracking on transfer and refresh claimed amounts via MoeTreasury.refreshClaimed().

Events

EventParameters
Initaddress mty

Custom Errors

ErrorTrigger
AlreadyInitialized(MoeTreasury moe_treasury)init() called twice
InsufficientBalance(uint256 balance)Burn exceeds balance
InvalidAmount(uint256 amount)Zero amount
EmptyAmounts()Empty amounts array
EmptyIds()Empty IDs array
LengthMismatch(uint256[] nft_ids, uint256[] amounts)Array length mismatch

APower (sov) — Store-of-Value Token

Source: source/contracts/APower.sol:18Inheritance: ERC20Permit, ERC20Burnable, SovMigratable, OwnableStandards: ERC20, EIP-2612 (permit)

Key Functions

solidity
function mint(address to, uint256 claim) external onlyOwner returns (uint256);

Mints APOW at a rate-limited pace. Wraps wrappable(claim) XPOW from treasury, then computes mintable APOW via exponential moving average of claims. Returns the minted amount. onlyOwner restricts to MoeTreasury.

solidity
function wrappable(uint256 claim) public view returns (uint256);

Returns min(claim, _moe.balanceOf(owner())) — the amount of XPOW available to wrap from the treasury balance.

solidity
function mintable(uint256 claim) external view returns (uint256);
function mintableBatch(uint256[] memory claims) external view returns (uint256[] memory);

Preview the APOW amount that would be minted for a given claim without executing. Uses the long-term mean of claims: mean = (mean * time + sqrt(claim)) / t.

solidity
function burn(uint256 amount) public override;
function burnFrom(address account, uint256 amount) public override;

Burns APOW and returns proportional XPOW from the contract's balance: unwrappable(amount) = balance * amount / (amount + totalSupply()).

solidity
function unwrappable(uint256 amount) public view returns (uint256);
function metric() external view returns (uint256);

metric() returns APOW-to-XPOW backing ratio scaled to 1e18: 1e18 * balance / totalSupply().

Events

Inherited ERC20 events: Transfer, Approval.


MoeTreasury (mty) — Reward Distributor

Source: source/contracts/MoeTreasury.sol:25Inheritance: ReentrancyGuardTransient, MoeTreasurySupervised, Ownable, Banq

Key Functions

solidity
function claim(address account, uint256 nftId, uint256 amount, uint256 nonce) external nonReentrant banq(account, amount, nonce);

Claims accumulated APOW rewards for a single staked NFT. Computes claimable(account, nftId), updates _claimed tracker, calls _sov.mint(), then the banq modifier auto-supplies to lending pool. Emits Claim.

solidity
function claimBatch(address account, uint256[] memory nftIds, uint256 amount, uint256 nonce) external nonReentrant banq(account, amount, nonce);

Batch claim across multiple staked NFTs. Requires nftIds to be unique and sorted. Emits ClaimBatch.

solidity
function claimable(address account, uint256 nftId) public view returns (uint256);
function claimableBatch(address account, uint256[] memory nftIds) public view returns (uint256[] memory);

Returns pending (unclaimed) XPOW reward: rewardOf(account, nftId) - claimed(account, nftId).

solidity
function rewardOf(address account, uint256 nftId) public view returns (uint256);

Calculates reward: (aprOf(nftId) + apbOf(nftId)) * ageOf(account, nftId) * 10^18 * denominationOf(levelOf(nftId)) / (1e6 * CENTURY).

solidity
function mintable(address account, uint256 nftId) external view returns (uint256);
function mintableBatch(address account, uint256[] memory nftIds) external view returns (uint256[] memory);

Preview APOW that would be minted for pending rewards via _sov.mintable(claimable(...)).

solidity
function aprOf(uint256 nftId) public view returns (uint256);
function aprTargetOf(uint256 nftId) public view returns (uint256);
function getAPR(uint256 nftId) public view returns (uint256[] memory);
function setAPR(uint256 nftId, uint256[] memory array) public onlyRole(APR_ROLE);
function setAPRBatch(uint256[] memory nftIds, uint256[] memory array) external onlyRole(APR_ROLE);

APR (Annual Percentage Rate): level-based reward rate defined by a 4-coefficient polynomial [add, div, mul, exp]. Evaluated as: pow(mul * level / div + add, exp / 256). Protected by Rpp.checkValue (rate change ≤ 2×) and Rpp.checkStamp (≥ 1 month between changes).

solidity
function apbOf(uint256 nftId) public view returns (uint256);
function apbTargetOf(uint256 nftId) public view returns (uint256);
function getAPB(uint256 nftId) public view returns (uint256[] memory);
function setAPB(uint256 nftId, uint256[] memory array) public onlyRole(APB_ROLE);
function setAPBBatch(uint256[] memory nftIds, uint256[] memory array) external onlyRole(APB_ROLE);

APB (Annual Percentage Bonus): vintage-based bonus for long-term stakers, depends on year() - yearOf(nftId).

solidity
function refreshRates(bool allLevels) external;

Recalculates APR scalar for each level based on share distribution. Called by NftTreasury after every stake/unstake. Share-weighted scalar redistributes rewards toward under-staked levels.

solidity
function refreshClaimed(address account, uint256 nftId, uint256 balanceOld, uint256 balanceNew) external onlyOwner;

Rescales _claimed when partial unstake occurs: claimed = claimed * balanceNew / balanceOld.

solidity
function claimed(address account, uint256 nftId) public view returns (uint256);
function minted(address account, uint256 nftId) public view returns (uint256);

Trackers for claimed XPOW rewards and minted APOW totals per (account, nftId).

Events

EventParameters
Claimaddress account, uint256 nftId, uint256 amount
ClaimBatchaddress account, uint256[] nftIds, uint256[] amounts
SetAPRuint256 nftId, uint256[] array
SetAPBuint256 nftId, uint256[] array
RefreshRatesbool allLevels

Custom Errors

ErrorTrigger
NonUnique(uint256[] nft_ids)Duplicate or unsorted IDs in batch claim
InvalidClaim(uint256 nft_id)Claim resulted in zero APOW

NftTreasury (nty) — Staking Manager

Source: source/contracts/NftTreasury.sol:16Inheritance: ERC1155Holder

Key Functions

solidity
function stake(address account, uint256 nftId, uint256 amount) external;

Stakes XPowerNft: transfers nft from account to treasury, mints ppt for account. Calls mty.refreshRates(false). Emits Stake.

solidity
function stakeBatch(address account, uint256[] memory nftIds, uint256[] memory amounts) external;

Batch stake across multiple NFT IDs.

solidity
function unstake(address account, uint256 nftId, uint256 amount) external;

Unstakes: burns ppt from account, returns nft from treasury. Calls mty.refreshRates(false). Emits Unstake.

solidity
function unstakeBatch(address account, uint256[] memory nftIds, uint256[] memory amounts) external;

Batch unstake across multiple NFT IDs.

solidity
function approveStake(address operator, bool approved) external;
function approveUnstake(address operator, bool approved) external;
function approvedStake(address account, address operator) public view returns (bool);
function approvedUnstake(address account, address operator) public view returns (bool);

Delegation: allows operator to stake/unstake on behalf of caller.

Events

EventParameters
Stakeaddress account, uint256 nftId, uint256 amount
StakeBatchaddress account, uint256[] nftIds, uint256[] amounts
Unstakeaddress account, uint256 nftId, uint256 amount
UnstakeBatchaddress account, uint256[] nftIds, uint256[] amounts
ApproveStakingaddress indexed account, address indexed operator, bool approved
ApproveUnstakingaddress indexed account, address indexed operator, bool approved

Custom Errors

ErrorTrigger
InvalidAmount(uint256 amount)Zero amount in stake/unstake

Base Contracts

ContractSourcePurpose
NftBasebase/NftBase.sol:17Shared ERC1155 base for XPowerNft and APowerNft. Provides NFT ID math (idBy, levelOf, yearOf, denominationOf), supply tracking, and composable URI/royalty/migration support.
NftMigratablebase/NftMigratable.sol:13ERC1155 migration from old v9.x contracts. Supports migrate(), migrateBatch(), seal()/sealAll(), and emigration via migratable(bool). ~4-year deadline.
NftRoyaltybase/NftRoyalty.sol:13EIP-2981 royalty with flat 0.5% rate (price / 200). Beneficiary configurable via setRoyal() by NFT_ROYAL_ROLE.
URIMalleablebase/URIMalleable.sol:17Per-year metadata URIs. Mutable for 10 years after the year, then permanent. Contract-level contractURI() for OpenSea.
Supervisedbase/Supervised.sol:7AccessControl base. Defines VERSION, DEFAULT_ADMIN_ROLE, and all sub-roles via abstract supervised contracts.
Migratablebase/Migratable.sol:17ERC20 migration from old contracts. Extended by MoeMigratable and SovMigratable with seal and unit-conversion logic.

Libraries

LibrarySourcePurpose
Constantlibs/Constant.sol:4Time constants (CENTURY, YEAR, MONTH, WEEK, DAY, HOUR, MIN, SEC), DECIMALS = 18, VERSION = 0x10c1.
Nftlibs/Nft.sol:6NFT ID composition/decomposition. idBy(year, level)100 * year + level. Requires level % 3 == 0 and level < 100. year() computed from block.timestamp via century math.
Powerlibs/Power.sol:6Fractional exponentiation: pow(n * 1e18, exp * 3906250e9) / 1e18. Exponent must be in [128, 512].
Polynomialslibs/Polynomials.sol:11Polynomial evaluation with power exponentiation. eval3 through eval6 for 4–7 coefficient arrays.
Integratorlibs/Integrator.sol:8Δ-stamp weighted arithmetic mean. Appends (stamp, value) items and computes cumulative area for mean calculation.
Banqlibs/Banq.sol:12Auto-supply to lending pool via banq modifier. Burns excess above claim amount. Enforces MIN_NET2RIP = 100 threshold.
Rpplibs/Rpp.sol:9Rug-pull protection. Validates parameter arrays (checkArray), rate changes ≤ 2× (checkValue), and minimum 1-month between changes (checkStamp).
Arraylibs/Array.sol:4sorted() and unique() array validators used for batch operation input validation.