Skip to main content

Overview

Metastable is built on top of Hyperlane Warp Routes 2.0. Each chain in a Metastable route has a CrossCollateralRouter deployed for each collateral token (e.g. one for USDC, one for the branded stablecoin). CrossCollateralRouter extends HypERC20Collateral, so each instance holds collateral for exactly one ERC-20. Every router has an owner, the admin address set at deployment. It’s typically a wallet or multisig held by the issuing team. The owner manages a per-domain allowlist of trusted peer CrossCollateralRouters, using enrollCrossCollateralRouters and unenrollCrossCollateralRouters, which write to the _crossCollateralRouters mapping (domain → set of router addresses). A single primary remote router can also be enrolled per domain through the standard Router enrollment. Together these define which source/destination pairs are valid for a given route, and allow multiple target routers on the same destination chain (for example, several branded stablecoins).
Token support: standard ERC-20s only. Rebasing tokens, fee-on-transfer tokens, and ERC-777 are not supported. The contract relies on exact-amount accounting.

Cross-chain swap flow

  1. The stablecoin holder’s wallet (msg.sender) calls transferRemoteTo on the source chain router with the destination domain, recipient, amount, and target router.
  2. The source router validates that the target router is enrolled, pulls amount + protocol fee + external fee from msg.sender, routes each fee to its configured fee address, and dispatches a single interchain message via Hyperlane.
  3. The destination router receives the message, verifies it came from a trusted router, and releases the full amount of the target stablecoin to the recipient.
Routers expose a single function for both cross-chain and same-chain swaps:
transferRemoteTo(
    uint32 destination,    // destination domain ID
    bytes32 recipient,     // recipient address on destination
    uint256 amount,        // amount of source token
    bytes32 targetRouter   // enrolled CrossCollateralRouter on destination
) public payable returns (bytes32 messageId)
The returned messageId is the Hyperlane message ID used to track delivery (for example, in the Hyperlane Explorer).

Same-chain swap flow

Same-chain swaps use the same transferRemoteTo function, but pass the local domain as the destination. The source router skips mailbox dispatch and calls the target router’s handle directly. No interchain relay, no gas payment. The function returns the zero hash since no message is dispatched. To allow this, CrossCollateralRouter overrides handle to drop the standard onlyMailbox modifier. The override accepts two callers:
  • The mailbox, for cross-chain messages (origin must be a different domain).
  • Another local CrossCollateralRouter, for same-chain swaps (the caller must be enrolled in this router’s local-domain allowlist).

Fee quoting

Fees are configured per destination domain and per target router. Call quoteTransferRemoteTo on the source router before a swap to get the exact cost for a route:
quoteTransferRemoteTo(
    uint32 destination,
    bytes32 recipient,
    uint256 amount,
    bytes32 targetRouter
) public view returns (Quote[] memory quotes)
Each Quote is { address token, uint256 amount }. The function returns an array of three entries, in this order:
  1. Interchain gas: paid in feeToken(). Zero for same-chain swaps.
  2. Token amount + protocol fee: the source token amount being transferred, plus the protocol fee.
  3. External fee: additional fee in the source token. Zero when no external fee is configured for the route.
The stablecoin holder (msg.sender) pays entries 2 and 3 in the source token (sum them for total source-token cost) plus entry 1 in feeToken() for interchain gas. The recipient (usually the same holder on the destination chain) receives the full amount of the target token. The fee comes from a fee contract set as the router’s feeRecipient. By default, that’s CrossCollateralRoutingFee, which points each route at its own pricing contract, either a fixed schedule or an off-chain signed quote (OffchainQuotedLinearFee) for cases like a preferential 1:1 rate. Routes with no fee recipient charge no protocol fee.

Liquidity and rebalancing

Liquidity for a Metastable route lives directly in the router contracts. The issuing team funds each CrossCollateralRouter with its collateral token, and swaps are settled from those reserves. As swap volume flows in one direction, a router can run low on the collateral it holds. Metastable uses the same onchain rebalancing as HWR 2.0: the rebalancer monitors inventory levels and moves collateral between chains to restore target weights, keeping routes available without manual intervention.
Why rebalancing is different in Metastable: In a same-asset multi-collateral route, restoring balance is straightforward — the rebalancer moves the same token between chains. Metastable routes hold different assets on each side, so an imbalance often can’t be fixed by moving the source token, since the scarce asset has to be sourced directly (e.g. acquiring more of the branded stablecoin on a chain where it’s been drawn down). That extra step relies on external liquidity and carries real cost beyond the cross-chain transfer itself. The mechanics stay automatic; the operating economics are what change.