Skip to content

Add HOLLAR routes between Hydration and AssetHub#343

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

Add HOLLAR routes between Hydration and AssetHub#343
hitchho wants to merge 3 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

⚠️ No Changeset found

Latest commit: 2ba1fc8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a 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