Skip to content

Add HOLLAR routes between Hydration and AssetHub - #343

Open
hitchho wants to merge 5 commits into
galacticcouncil:masterfrom
hitchho:feat/hollar-assethub
Open

Add HOLLAR routes between Hydration and AssetHub#343
hitchho wants to merge 5 commits into
galacticcouncil:masterfrom
hitchho:feat/hollar-assethub

Conversation

@hitchho

@hitchho hitchho commented Jul 17, 2026

Copy link
Copy Markdown

What

Adds XCM support for HOLLAR (Hydration asset 222 / AssetHub foreign asset {Parachain(2034), GeneralIndex(222)}) between Hydration and AssetHub, both directions.

  • hollar asset + registration on both chains (18 decimals, 0.02 ED/minBalance, verified on-chain)
  • Hydration side reads balances from the GHO erc20 (0x531a654d1696ED52e7275A8cede955E82620f99a) via balanceId + evm().erc20()
  • assethub → hydration: DestinationReserve (burns the hub derivative, withdraws from AssetHub's sovereign on Hydration), dest fee 0.02 HOLLAR
  • hydration → assethub: LocalReserve for the asset with the destination fee paid in DOT via DestinationReserve — HOLLAR has no fee-payment pool on AssetHub (BuyExecution in HOLLAR fails TooExpensive, verified via DryRunApi.dry_run_xcm). This required a small builder extension: optional feesTransferType on polkadotXcm().transferAssetsUsingTypeAndThen() (maps to the pallet's native fees_transfer_type arg)

Bug fixes surfaced along the way

  • transferAssetsUsingTypeAndThen emitted unsorted Assets vectors. The runtime only decodes Assets sorted by canonical Location order, and the builder unconditionally placed the fee first. Any fee/asset pair ordered the wrong way (e.g. DOT parents:1 fee with a parents:0 local asset) produced an extrinsic the runtime rejects with an opaque wasm trap (Bad input data) in both DryRunApi and validate_transaction. Added a canonical location comparator (parents → interior arity → junction variant/value, mirroring the runtime's derived Ord) and order the pair accordingly. This was originally misdiagnosed as a runtime issue — see Not a bug: unsorted XCM v4 Assets vector fails SCALE decode, surfaces as opaque wasm trap (client-side, fixed in sdk#343) hydration-node#1491 (closed with the analysis)
  • HydrationEvmResolver.toH160 was wrong for native substrate accounts: it unconditionally unwrapped bytes 4..-8, which is only correct for ETH\0-prefixed EVM accounts; native accounts must truncate to the first 20 bytes (mirrors pallet-evm-accounts::evm_address). Needed for erc20 balance reads of substrate-held HOLLAR

Verification (mainnet dry runs)

  • assethub → hydration: dry_run_call on AssetHub succeeds (ForeignAssets burn) and the forwarded XCM executes Complete on Hydration via dry_run_xcm. AssetHub's sovereign on Hydration backs the hub supply 1:1 (~417k HOLLAR)
  • hydration → assethub: dry_run_call on Hydration succeeds (DOT fee + erc20 HOLLAR withdrawn to AH sovereign, WithdrawAsset(DOT) → BuyExecution(DOT) → ReserveAssetDeposited(HOLLAR) → DepositAsset forwarded) and the forwarded XCM executes Complete on AssetHub via dry_run_xcm
  • xc-cfg builds and unit tests pass; verified end-to-end in hydration-ui against mainnet

@changeset-bot

changeset-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e255fa9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@galacticcouncil/xc-cfg Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants