#47·Phantom order config + Asset Hub fee token switch

9d ago
0 Comments
Executed

Built and verified against live nexus, spec nexus-8300. The runtime upgrade has been enacted
since these calls were first drafted, so the pair-centric PhantomOrderConfiguration is now the
on-chain shape and everything below was round-tripped through live metadata rather than
hand-registered types.

Contents

# Call Effect
0 intentsCoprocessor.setPhantomOrderConfig 8 chains, 51 pairs, 102 legs, interval_blocks = 300
1 hostExecutive.updateHostParams Asset Hub (Evm(420420419)) fee token USDC → USDT
  • utility.batch — callHash 0xb0cd5fe416fd7bab118d40ceb775ceed10bbaeb10a95a2743cc8c03fcb5ffd94
  • utility.batchAll — callHash 0x10b6505d890a3520ea1421d9de1bc14b49c6c675ddb61c14cffbf16cf30d2da5

Both calls take Root (GovernanceOrigin and HostExecutiveOrigin are both EnsureRoot), so the
batch dispatches cleanly under a root-origin referendum. The two calls are independent — the phantom
config is local nexus storage, the fee switch is a cross-chain dispatch — so batch order is
immaterial and there is no reason to prefer batchAll beyond ordinary all-or-nothing preference.

Call 1 — fee token switch

0x350100431b0f190001000007c000000000000000000000000001200000000000000000000000

0x35 = pallet 53 HostExecutive, 0x01 = update_host_params; Evm(420420419); a
HostParamUpdate::EvmHostParam with fee_token = Some(0x000007c0…) and every other field None.

Address Asset
current feeToken 0x0000053900000000000000000000000001200000 Asset Hub asset 1337 — USDC
new feeToken 0x000007c000000000000000000000000001200000 Asset Hub asset 1984 — Tether USD, 6 decimals

Both are 6-decimal, so no accompanying set_fee_token_decimals is needed (and that call only applies
to substrate hosts in any case — feeTokenDecimals has no entry for this chain).

The call updates HostParams on nexus and dispatches an ISMP post to the host manager
0x59185dac59b2e0ade6a414964d039b0474d942c0 on Asset Hub, which is what actually switches the token
on the EvmHost. It takes effect there when a relayer delivers the request, not at enactment.

⚠ Drain the old fee token first

EvmHostParamUpdate::fee_token carries an explicit warning in the source:

It's important that before changing this parameter, that all funds have been drained from the
previous feeToken.

Any protocol fees still held in USDC on the Asset Hub EvmHost become stranded once the host is
pointed at USDT. hostExecutive.withdraw (call index 4) is the mechanism for pulling them out. This
batch does not include a withdrawal — decide whether one is needed and, if so, whether it should
precede this proposal or ride in front of the fee switch inside the same batch. This is the one thing
here that is not reversible by simply re-running the call.

Call 0 — phantom order config

Verified by decoding the hex against live 8300 metadata: 8 chains, 51 pairs, interval_blocks = 300,
and re-encoding reproduces the exact bytes.

Chain Consensus Pairs
EVM-1 ethereum ETH0 16
EVM-10 optimism ETH0 3
EVM-56 bsc BSC0 3
EVM-100 gnosis GNO0 1
EVM-137 polygon POLY 12
EVM-8453 base ETH0 12
EVM-42161 arbitrum ETH0 3
EVM-420420419 asset hub DOT0 1

USDC- and USDT-anchored against every other stablecoin, plus USDC/USDT, plus a ZARP/cNGN cross on the
three chains carrying both. All amounts are 10^decimals read live from each token contract. Full
detail in stables-phantom-config.md.

Unchanged caveat: Asset Hub has no ismp.latestStateMachineHeight entry, so the phantom generator
logs a warning and skips that chain until one exists. Note this is nexus reading Asset Hub's state —
the opposite direction from the fee-token dispatch, which travels hyperbridge → Asset Hub — so it
does not by itself block call 1. Worth confirming delivery on the hub after enactment either way.

Weight

Measured via TransactionPaymentCallApi::query_call_info on live nexus:

refTime proofSize
utility.batch 477,970,908 1,627
+5% buffer 501,869,454 1,709
utility.batchAll 519,155,513 1,627
+5% buffer 545,113,289 1,709

Trivial against the normal-class per-extrinsic limit of 1,399,875,000,000 refTime / 7,340,032
proofSize. As before, the weight that actually matters is the generation hook, not this dispatch:
2,654,368,020 refTime / 35,088 proofSize every 300 blocks once all eight chains generate (0.133%
of maxBlock), or 2,364,802,254 / 31,089 today with Asset Hub skipped.

Edited
Reply
Up
Share
This vote has been closed.
Call
Metadata
Timeline4
Comments