Skip to content

Architecture Overview

Tech Stack

LayerTechnologyVersion
LanguageSolidity^0.8.34
FrameworkFoundry (forge)v10.x
MathPRB Mathv4.1.2
ContractsOpenZeppelinv5.6.1
Token StandardsERC20, ERC1155, ERC2981, ERC165
Transient StorageEIP-1153 (ReentrancyGuardTransient)
LicenseGPL-3.0

Optimizer is enabled by default for builds (foundry.toml profile). Tests run with optimizer disabled via FOUNDRY_OPTIMIZER=false. Compiler warnings 2394, 3860, 5574, 4591, and 6335 are suppressed.

Version & Networks

  • Protocol Version: 0x10c1 (10.2.0), stored as Constant.VERSION at source/contracts/libs/Constant.sol:44
  • Network Mainnet: Avalanche C-Chain (chain ID 43114)
  • Network Testnet: Avalanche Fuji (chain ID 43113)

All contracts expose uint256 public constant VERSION = Constant.VERSION (via Supervised or NftTreasury).

Source Layout

source/
├── contracts/
│   ├── XPower.sol          # core: PoW ERC20 token (alias: moe)
│   ├── XPowerNft.sol       # core: deposit receipt ERC1155 (alias: nft)
│   ├── APowerNft.sol       # core: staking receipt ERC1155 (alias: ppt)
│   ├── APower.sol          # core: store-of-value ERC20 (alias: sov)
│   ├── MoeTreasury.sol     # core: reward distributor (alias: mty)
│   ├── NftTreasury.sol     # core: staking manager (alias: nty)
│   ├── base/
│   │   ├── NftBase.sol         # ERC1155 base: NFT ID math, supply tracking
│   │   ├── NftMigratable.sol   # ERC1155 migration: old→new NFT bridging
│   │   ├── NftRoyalty.sol      # EIP-2981: 0.5% royalty with configurable beneficiary
│   │   ├── URIMalleable.sol    # Per-year mutable metadata URIs (permanent after decade)
│   │   ├── Supervised.sol      # Role-based access control hierarchy
│   │   └── Migratable.sol      # ERC20 migration: MoeMigratable + SovMigratable
│   └── libs/
│       ├── Constant.sol        # Time constants, decimals, protocol version
│       ├── Nft.sol             # NFT ID composition: idBy(year, level), yearOf, levelOf, denominationOf
│       ├── Power.sol           # Fractional exponentiation via PRB Math pow()
│       ├── Polynomials.sol     # eval3/eval4/eval5/eval6: linear+power evaluation
│       ├── Integrator.sol      # Δ-stamp weighted arithmetic mean over (stamp, value) items
│       ├── Banq.sol            # Auto-supply to lending pool with excess-burning safety
│       ├── Rpp.sol             # Rug-pull protection: parameter change guardrails
│       └── Array.sol           # sorted() and unique() array validators

Inheritance Tree

XPower (moe)

ERC20 → ERC20Permit, ERC20Burnable → Migratable → MoeMigratableSupervised → Supervised → AccessControl
                                                                                  ↘︎
                                                                              Ownable
                                                                                  ↗︎
XPower ──→ ERC20Permit, ERC20Burnable, MoeMigratable, Ownable

Key parent: ERC20Permit for gasless approvals, ERC20Burnable for burn, Ownable for mint authorization, MoeMigratable for migration from legacy v9.x contracts.

XPowerNft (nft)

ERC1155 → ERC1155Supply, ERC1155Burnable → URIMalleable → URIMalleableSupervised
                                          → NftRoyalty → NftRoyaltySupervised
                                          → NftMigratable → NftMigratableSupervised
                                          → Ownable

NftBase ──→ ERC1155, ERC1155Supply, ERC1155Burnable, URIMalleable, NftRoyalty, NftMigratable, Ownable
                                                                                                      ↗︎
XPowerNft ──→ NftBase

APowerNft (ppt)

NftBase (same chain as XPowerNft)

APowerNft ──→ NftBase, ReentrancyGuardTransient

Adds ReentrancyGuardTransient (EIP-1153) for safe transfer reentrancy protection. onlyOwner restricts mint/burn to NftTreasury.

APower (sov)

ERC20 → ERC20Permit, ERC20Burnable → Migratable → SovMigratable (Migratable + Banq + ReentrancyGuardTransient)
                                                                          ↘︎
                                                                      Ownable
                                                                          ↗︎
APower ──→ ERC20Permit, ERC20Burnable, SovMigratable, Ownable

Directly references XPower for wrap/unwrap operations. onlyOwner restricts mint to MoeTreasury.

MoeTreasury (mty)

MoeTreasurySupervised → Supervised → AccessControl

Banq → Supervised → AccessControl

MoeTreasury ──→ ReentrancyGuardTransient, MoeTreasurySupervised, Ownable, Banq

Integrates 5 libraries: Polynomials, Integrator, Array, Power, Banq, Rpp. Constructor sets owner to NftTreasury address.

NftTreasury (nty)

ERC1155Holder

NftTreasury ──→ ERC1155Holder

Minimal contract — holds staked XPowerNft tokens, interacts bidirectionally with APowerNft and MoeTreasury.

Contract Relationship Diagram

                   ┌──────────────┐
                   │  XPower      │  (moe) ERC20 PoW token
                   │  mint()      │
                   └──────┬───────┘
                          │ deposit XPOW

           ┌──────────────────────────────┐
           │  XPowerNft                   │  (nft) ERC1155 deposit receipt
           │  mint(account, level, amount)│
           │  burn(account, id, amount)   │
           │  upgrade(account, anno, ...) │
           └──────────────┬───────────────┘
                          │ safeTransferFrom → nty

  ┌─────────────────────────────────────────────────────┐
  │  NftTreasury  (nty)  ERC1155Holder                   │
  │  stake(account, nftId, amount)                       │
  │  unstake(account, nftId, amount)                     │
  └──────┬──────────────────────────────────┬───────────┘
         │ ppt.mint / ppt.burn              │ refreshRates()
         ▼                                  ▼
  ┌──────────────┐              ┌──────────────────────┐
  │  APowerNft   │  (ppt)       │  MoeTreasury (mty)   │
  │  ageOf()     │              │  claim(account, ...)  │
  │  shares()    │              │  aprOf() / apbOf()    │
  └──────────────┘              │  rewardOf()           │
                                │  setAPR() / setAPB()  │
                                └──────────┬────────────┘
                                           │ sov.mint(to, claim)

                                ┌──────────────────────┐
                                │  APower  (sov)        │
                                │  mint(to, claim)      │
                                │  burn(amount) → unwrap│
                                │  metric()             │
                                └──────────────────────┘

Flow summary:

  1. Mining: User calls XPower.init() to cache block hash, then XPower.mint(to, blockHash, data) with a valid nonce. XPOW minted to both beneficiary and treasury owner (doubling supply).
  2. Deposit: User calls XPowerNft.mint(account, level, amount) — XPOW transferred to NFT contract, ERC1155 receipt minted.
  3. Stake: User calls NftTreasury.stake(account, nftId, amount) — XPowerNft locked in treasury, APowerNft minted as staking receipt.
  4. Claim: User calls MoeTreasury.claim(account, nftId, amount, nonce) — reward calculated from age × rate × denomination, APOW minted at rate-limited pace.
  5. Unwrap: User calls APower.burn(amount) — APOW burned, proportional XPOW returned from treasury.

Role System

All roles are defined in Supervised.sol via AccessControl:

RoleAdmin RoleScopeDescription
DEFAULT_ADMIN_ROLEGlobalGrant/revoke all roles
APR_ROLEAPR_ADMIN_ROLEMoeTreasurySet APR polynomial parameters
APB_ROLEAPB_ADMIN_ROLEMoeTreasurySet APB polynomial parameters
MOE_SEAL_ROLEMOE_SEAL_ADMIN_ROLEXPowerSeal MOE immigration
SOV_SEAL_ROLESOV_SEAL_ADMIN_ROLEAPowerSeal SOV immigration
NFT_SEAL_ROLENFT_SEAL_ADMIN_ROLENftMigratableSeal NFT immigration
NFT_OPEN_ROLENFT_OPEN_ADMIN_ROLENftMigratableOpen NFT emigration
NFT_ROYAL_ROLENFT_ROYAL_ADMIN_ROLENftRoyaltySet royalty beneficiary
URI_DATA_ROLEURI_DATA_ADMIN_ROLEURIMalleableSet metadata URIs

Each role follows a two-tier pattern: the _ROLE grants action rights, the _ADMIN_ROLE manages granters.

Key Design Decisions

  • onlyOwner on mint/burn: APowerNft.mint()/burn() and APower.mint() are onlyOwner — ownership is transferred to NftTreasury and MoeTreasury respectively in their constructors.
  • Double mint: XPower.mint() mints to both to (beneficiary) and owner() (treasury), effectively doubling supply on each PoW discovery.
  • Block hash expiry: XPower.mint() requires block hash cached within the current 1-hour interval (block.timestamp / 3600).
  • NFT levels divisible by 3: All NFT levels must be multiples of 3 (0, 3, 6, ..., 99). The Nft.idBy() function enforces this with level % 3 == 0.
  • Redemption maturity: XPowerNft tokens are redeemable (burnable for underlying XPOW) when yearOf(id) + 2^(level/3) - 1 <= year().
  • Rate limit: APower.mint() targets ~1 APOW per minute long-term average using a square-root scaling of claims.
  • Banq auto-supply: The banq modifier in MoeTreasury.claim() auto-supplies freshly minted APOW to a lending pool, burning any excess above the claim amount.