Technical Bulletin: POLYX Integration Readiness for Polymesh Runtime v8

Polymesh v8 upgrade advisory: changes to POLYX transfers, events, balances, and memo/DID handling for exchanges, wallets, and custody providers.
Chain updates
April 1, 2026

TL;DR

  • Upgrade timeline: Polymesh v8 expected May 2026, with ≥4 weeks notice before mainnet upgrade
  • Event changes:
    • balances.Transfer will no longer include memo or DID fields
    • Use balances.TransferWithMemo for memo-based deposits
  • Action required (deposits):
    • Memo-based systems → switch to TransferWithMemo (available since v7.4)
    • Address-based systems → use Transfer
    • Do not parse both events for the same transfer
  • Extrinsics: legacy transfer removed, use standard Substrate calls (transfer_*)
  • Balances: update parsing to use frozen instead of miscFrozen / feeFrozen
  • Transferable balance formula updated
  • DID requirement removed (since v7.3):
    • Receiving addresses do not need a DID
    • Remove any DID checks on withdrawal validation

Overview

Polymesh runtime v8 is an upcoming release. This bulletin is provided in advance so that exchange, custody, and wallet teams can plan and prepare integration changes ahead of the upgrade. The mainnet upgrade is expected in May 2026. A firm date will be announced at least 4 weeks in advance.

This bulletin is for exchange, custody, and wallet engineering teams that support on-chain POLYX transfers and balance reconciliation.

Scope: POLYX token transfer flows on the Polymesh blockchain (balances pallet behavior and related account-balance semantics).

Polymesh runtime v8 aligns POLYX balance behavior with the upstream Polkadot SDK (Substrate) balances model and interface.

The rationale for this change is to:

  • Reduce network-specific integration logic
  • Improve compatibility with standard Polkadot SDK wallets, indexers, and operational tooling
  • Make transfer semantics and storage layout more predictable across Polkadot SDK-based environments

For exchanges, custody platforms, and wallet providers, this results in simpler long-term maintenance, fewer custom parsing rules, and clearer forward compatibility as upstream standards evolve.

What Changes in v8

1) Transfer Extrinsics

The POLYX transfer API surface moves to the standard balances calls:

  • transfer_allow_death
  • transfer_keep_alive
  • transfer_all

The legacy transfer call is removed. transfer_with_memo remains available for memo-bearing transfers.

For withdrawals or sending POLYX, integrations should support at least one of the four transfer methods (transfer_allow_death, transfer_keep_alive, transfer_all, or transfer_with_memo).

Supporting any one of these methods is sufficient. However, it is recommended, but not mandatory, to support transfer_with_memo for outgoing transfers, since some destinations, such as exchanges, require unique memos for deposit attribution.

2) Transfer Events

Current Event Structure (v7.4, pre-v8)

The balances.Transfer event currently emits six fields:

balances.Transfer(
  from_did: Option<IdentityId>,
  from: AccountId,
  to_did: Option<IdentityId>,
  to: AccountId,
  amount: Balance,
  memo: Option<Memo>
)   

The balances.TransferWithMemo event (introduced in v7.4) emits four fields:

balances.TransferWithMemo(
  from: AccountId,
  to: AccountId,
  amount: Balance,
  memo: Memo
)

In v7.4, POLYX transfers executed via transfer_with_memo emit both Transfer and TransferWithMemo. Integrations should parse only one of these event streams for deposit accounting to avoid double counting.

v8 Event Structure

In v8, balances.Transfer aligns with the standard Polkadot SDK format and drops the identity and memo fields:

balances.Transfer(
  from: AccountId,
  to: AccountId,
  amount: Balance
)

All POLYX transfers emit balances.Transfer.

balances.TransferWithMemo remains unchanged and is emitted only when the transfer_with_memo extrinsic is used.

This means:

  • Standard transfers emit only Transfer
  • transfer_with_memo emits both Transfer and TransferWithMemo

Compatibility Note for Current Runtime (v7.4)

balances.TransferWithMemo was introduced in v7.4 specifically to provide forward compatibility with v8. Because v8 removes the identity and memo fields from the standard Transfer event, a dedicated event was introduced in advance so that memo-based POLYX deposit flows can continue to function across the upgrade.

 TransferWithMemo is compatible with both v7.4 and v8. Exchanges that track memo-based POLYX deposits should switch to consuming TransferWithMemo.

 Important:

 In v7.4, TransferWithMemo is emitted only when transfer_with_memo is used

  • When it is emitted, Transfer is also emitted for the same extrinsic
  • Parse only one event stream per flow to avoid double counting

Note on Deposit Address Strategy

Since v7.3, Polymesh no longer requires an account to have an associated Decentralised Identity (DID) in order to receive POLYX or participate in staking.

This has a direct practical implication for exchanges.

Prior to v7.3, every receiving address required a DID, which made unique per-user deposit addresses difficult to operate at scale. Memo-based deposits to a shared address were commonly used as a workaround.

With DID requirements removed for POLYX, exchanges can now allocate a unique on-chain deposit address per user, following the standard pattern used across most Polkadot SDK-based chains, without requiring each user to hold a DID.

Both deposit models remain fully supported:

Approach Event to parse Notes
Memo-based deposits (shared address) balances.TransferWithMemo Memo identifies the user, available since v7.4, forward-compatible with v8
Unique deposit address per user balances.Transfer Standard pattern, no memo required

Important: Since v7.3, receiving addresses are not required to have an associated DID to receive POLYX. Integrations should not enforce DID existence checks when validating withdrawal destinations, as this can lead to valid transfers being incorrectly rejected.

3) system.account Balance Data Layout

system.account.data moves from:

  • free
  • reserved
  • miscFrozen
  • feeFrozen

to:

  • free
  • reserved
  • frozen
  • flags

Account data is migrated in two stages.

At upgrade time:
miscFrozen and feeFrozen are replaced with a single single frozen value. flags is initialised to the same value as frozen. free and reserved remain unchanged.

After the account is next updated (for example, via transfer or staking):
reserved is recalculated to reflect upstream semantics, free is adjusted accordingly, and flags is updated to its full upstream format including version bits.

The v8 transferable balance formula below produces correct results for accounts in either state.

4) Transferable Balance Semantics

Legacy transferable calculation:    

transferable = free - max(miscFrozen, feeFrozen)

v8-compatible calculation:      

transferable = free - max(ED, frozen - reserved)

Where:

  • free is the account free balance
  • reserved is protocol-reserved balance
  • frozen is the total locked or frozen amount
  • ED is the existential deposit

Since Polymesh uses ED = 0, this simplifies to:      

transferable = free - max(0, frozen - reserved)  

In v8, an account’s total balance remains free + reserved. The reserved field now reflects protocol-reserved funds such as staked tokens, so reported free balances may differ from pre-v8 for accounts.

5) transfer_keep_alive vs transfer_allow_death

Both calls are exposed for compatibility with standard Polkadot SDK balances tooling.

With ED = 0 and no account reaping at zero balance, their practical behavior is equivalent for exchange integrations.

Integration Guidance for Exchanges

Use the following as your implementation baseline:

  1. Support at least one of the four transfer methods for withdrawals (transfer_allow_death, transfer_keep_alive, transfer_all, or transfer_with_memo)
  2. Prefer supporting transfer_with_memo for outgoing transfers where counterparties require memos
  3. Do not require a DID for withdrawal destination addresses
  4. For memo-based deposits, consume balances.TransferWithMemo
  5. For address-based deposits, consume balances.Transfer
  6. Do not parse both events for the same transfer flow in v7.4 or v8
  7. Treat the presence of a transfer event as the authoritative signal that value moved
  8. Update balance parsing logic to handle frozen and flags
  9. Update available balance computation to the v8 formula

Summary

Polymesh runtime v8 standardises POLYX balance interfaces and event semantics around the upstream Polkadot SDK model, while preserving memo-capable transfers via TransferWithMemo.

Exchanges that adopt TransferWithMemo for memo-based flows and update balance and storage handling in advance will be well positioned for a smooth v8 transition.

Share post
Learn more about
development on Polymesh
Discover the open source Polymesh universe.

The Polymesh Developer Portal is contains comprehensive documentation, specialized user journeys, and hands-on exercises for building on the purpose-built Polymesh network.

Keep reading