Skip to content

Upgrading NFTs

Upgrading consolidates 1,000 lower-level XPowerNfts into 1 higher-level NFT — multiplying your denomination by 1,000× and dramatically increasing your staking reward potential at the cost of a longer maturity lock.

Why Upgrade?

The upgrade mechanism is the primary way to climb the tier ladder without additional XPOW. Instead of mining and depositing 10+3 XPOW to mint a single tier +3 NFT directly, you can accumulate 1,000 NFTs at tier and consolidate them:

1,000 NFTs at level 1 NFT at level +3

This is value-preserving because:

1,000×10=10+3

The total XPOW backing is unchanged. But at the higher level:

  • Denomination is 1,000× larger — multiplying your reward base
  • Maturity lock roughly doubles — from 2/31 to 2(+3)/31 years
  • You need fewer NFTs to manage — 1 instead of 1,000

Prerequisites

  • 1,000 or more XPowerNfts at the same level and same mint year
  • If staked, you must unstake first (see Unstaking)
  • A small amount of AVAX for gas

Step-by-Step

1. Check Eligibility

You need at least 1,000 NFTs at a given level (where 0) from the same mint year. Example: 1,000 level-3 NFTs minted in 2026 (ID 202603).

Your balance can be checked:

XPowerNft.balanceOf(yourAddress, nftId)

Upgrades consume source NFTs at 1000×amount of the target. So:

  • 1,000 level-3 → 1 level-6 requires burning 1,000 source NFTs
  • 2,000 level-3 → 2 level-6 requires burning 2,000 source NFTs
  • 3,500 level-3 → 3 level-6 requires burning 3,000, leaving 500 level-3 remaining

2. Unstake If Staked

Upgrading only works on XPowerNfts, not APowerNfts. If your NFTs are currently staked:

  1. Claim any pending rewards: MoeTreasury.claim(yourAddress, nftId, nonce)
  2. Unstake: NftTreasury.unstake(yourAddress, nftId, amount)

The returned XPowerNfts can then be upgraded. You can re-stake the upgraded NFTs afterward.

3. Perform the Upgrade

XPowerNft.upgrade(yourAddress, year, targetLevel, amount)

Where:

  • yourAddress is the NFT owner (must be msg.sender or approved for upgrades)
  • year is the mint year of the source NFTs (e.g., 2026)
  • targetLevel is the output level (must be 3, i.e., a multiple of 3 greater than 0)
  • amount is how many upgraded NFTs to produce

The source level is implicitly targetLevel - 3. The contract burns amount * 1000 NFTs at the source level and mints amount at the target level.

Example: upgrading 3,000 level-3 to 3 level-6:

XPowerNft.upgrade("0xYour...", 2026, 6, 3)
  • Burns 3 × 1,000 = 3,000 NFTs at ID 202603 (level 3)
  • Mints 3 NFTs at ID 202606 (level 6)

Gas cost: depends on the number of source NFTs burned. Upgrading 1,000 → 1 costs roughly the gas of burning 1,000 plus minting 1: ~300,000–600,000 gas.

4. Verify the Upgrade

After the transaction confirms:

  1. Your XPowerNft balance for the source ID (202603) decreases by amount * 1000
  2. Your XPowerNft balance for the target ID (202606) increases by amount
  3. The TransferBatch event logs both the burns (from your address to 0x0) and the mints (from 0x0 to your address)

Batch Upgrade

To upgrade across multiple years or target levels in one transaction:

XPowerNft.upgradeBatch(
    yourAddress,
    [year1, year2],
    [[targetLevel1, targetLevel2], [targetLevel3]],
    [[amount1, amount2], [amount3]]
)

This processes groups atomically — all upgrades succeed or the entire transaction reverts. Batch upgrading saves gas by amortizing the per-transaction overhead across multiple upgrade operations.

Lock Reset

Upgrading preserves the mint year — the upgraded NFT keeps the same vintage as the source NFTs. This means:

  • The maturity formula uses the original mint year, not the upgrade year
  • A level-3 NFT minted in 2026, upgraded to level-6 in 2028, still matures in 2029 (2026 + 26/31=3 years)
  • The maturity lock is determined by the target level, not the source level

The new maturity offset is:

maturityYear=originalMintYear+2targetLevel/31

This is usually longer than the source level's maturity. For example:

  • Source level 3: matures in 2026 + 1 = 2027
  • Target level 6: matures in 2026 + 3 = 2029

You're trading an extra 2 years of lock for 1,000× the denomination and staking reward potential.

Gas Efficiency

Upgrade PathSource NFTs BurnedApprox. Gas
1,000 × level-0 → 1 × level-31,000~300,000–500,000
1,000 × level-3 → 1 × level-61,000~300,000–600,000
1,000 × level-6 → 1 × level-91,000~350,000–600,000
3,000 × level-3 → 3 × level-63,000~500,000–800,000

Gas scales with the number of source NFTs burned, since each burn operation involves ERC-1155 storage writes. Upgrading large quantities is gas-intensive — if you plan to hold a high-level position, consider minting at the target level directly when you have enough XPOW.

Upgrade from Level 0

Upgrading 1,000,000 level-0 NFTs to 1 level-9 NFT would require burning 1,000,000 separate NFTs — this is gas-prohibitive. For high-level positions, mine and deposit XPOW at the target level or at an intermediate level (3 or 6) and upgrade from there.

What Happens Internally

When you call XPowerNft.upgrade(account, anno, level, amount), the following sequence executes:

1. Authorization and Validation

The contract checks:

  • account == msg.sender or approvedUpgrade(account, msg.sender) — unauthorized callers revert
  • level > 2 — the target level must be at least 3 (since upgrading to level 0 is meaningless and level 0 has no lower source)
  • level % 3 == 0 — reverts with NonTernaryLevel if not a multiple of 3
  • level < 100 — reverts with InvalidLevel
  • anno > 2020 — reverts with InvalidYear

2. Source Burn

The contract computes sourceId = idBy(anno, level - 3) — the NFT ID one tier below the target. It calls _burn(account, sourceId, amount * 1000), destroying amount * 1000 source NFTs from your wallet. The burn is a standard ERC-1155 operation — the tokens are permanently removed from circulation.

3. Target Mint

The contract computes targetId = idBy(anno, level) — the NFT ID at the target tier, with the same year. It calls _mint(account, targetId, amount, ""), creating amount new NFTs in your wallet at the higher level.

4. Event Emission

The TransferBatch event is emitted with two arrays:

  • ids = [sourceId, targetId]
  • values = [amount * 1000, amount]

From the event, the source burn appears as a transfer to address(0) and the target mint as a transfer from address(0). The single TransferBatch event captures both sides of the upgrade atomically.

5. XPOW Invariant

The total XPOW value is preserved:

amount * 1000 * 10^(level-3) = amount * 1000 * 10^level / 1000 = amount * 10^level

No XPOW is minted or burned during an upgrade — only NFTs change hands. The underlying XPOW in the XPowerNft contract's escrow remains constant.