Skip to main content

HypGhostERC20Synthetic (Hyperlane Bridge)

Specter uses Hyperlane warp routes to bridge tokens from external EVM chains (Ethereum, Base, Arbitrum) into the Specter privacy layer. The HypGhostERC20Synthetic contract is a synthetic token implementation that mints wrapped "g-tokens" on Specter when the corresponding tokens are locked on the source chain. These g-tokens can then enter the Ghost Protocol commit/reveal pipeline for private transactions.

Overview

PropertyValue
Bridge protocolHyperlane (modular interoperability)
Token modelLock-and-mint / burn-and-unlock
Base classTokenRouter (Hyperlane warp route)
Source chainsEthereum, Base, Arbitrum
Destination chainSpecter (Chain ID 5446)
Security modelsTrustedRelayerISM, MultisigISM

Supported Tokens

The following synthetic g-tokens are deployed on Specter, each backed 1:1 by tokens locked on their source chain:

TokenSymbolSpecter AddressUnderlying
Ghost USDCgUSDC0x65c9091a6A45Db302a343AF460657C298FAA222DUSDC on Ethereum/Base/Arbitrum
Ghost WETHgWETH0x923295a3e3bE5eDe29Fc408A507dA057ee044E81WETH on Ethereum/Base/Arbitrum
Ghost LABSgLABS0x062f8a68f6386c1b448b3379abd369825bec9aa2LABS token
Ghost VIRTUALgVIRTUAL0xaF12d2f962179274f243986604F97b961a4f4CfcVIRTUAL token

Token ID Derivation

When g-tokens enter Ghost Protocol, they need a circuit-compatible identifier. The tokenId used in commitments is derived as:

tokenId = Poseidon2(tokenAddress, 0)

For example, for gUSDC:

import { poseidon2 } from "poseidon-lite";

const gUSDC_ADDRESS = 0x65c9091a6A45Db302a343AF460657C298FAA222Dn;
const gUSDC_TOKEN_ID = poseidon2([gUSDC_ADDRESS, 0n]);

This Poseidon-based derivation ensures the token identifier is a valid BN254 field element, which is required for use inside ZK circuits.

Architecture

Lock-and-Mint Flow

Step 1: Lock on Source Chain

On the source chain (Ethereum, Base, or Arbitrum), a HypERC20Collateral contract holds the locked tokens. When a user initiates a bridge transfer:

// On Ethereum -- user locks USDC into the collateral contract
IERC20(usdc).approve(address(collateral), amount);
collateral.transferRemote{value: bridgeFee}(
specterDomainId, // Hyperlane domain ID for Specter
recipientBytes32, // Recipient address on Specter (bytes32-encoded)
amount // Amount to bridge
);

The collateral contract:

  1. Transfers amount of the token from the user to itself (lock)
  2. Dispatches a Hyperlane message to Specter's mailbox containing the transfer details

Step 2: Cross-Chain Message Relay

The Hyperlane relayer infrastructure picks up the dispatched message and delivers it to Specter's Hyperlane mailbox. The message contains:

FieldDescription
senderCollateral contract address on source chain
recipientHypGhostERC20Synthetic address on Specter
bodyABI-encoded (address to, uint256 amount)
originSource chain Hyperlane domain ID

Step 3: Mint on Specter

When the message arrives at Specter's mailbox, it is verified by the Interchain Security Module (ISM) and delivered to the HypGhostERC20Synthetic contract:

// Inside HypGhostERC20Synthetic (simplified)
function _handle(
uint32 origin,
bytes32 sender,
bytes calldata body
) internal override {
// Verify the sender is the registered collateral contract for this origin
require(
sender == routers[origin],
"Unauthorized sender"
);

// Decode the transfer
(address to, uint256 amount) = abi.decode(body, (address, uint256));

// Mint synthetic g-tokens to the recipient
_mint(to, amount);
}

The newly minted g-tokens are standard ERC-20 tokens on Specter. They can be:

  • Held in a wallet
  • Transferred to other addresses
  • Committed to the CommitRevealVault for private transactions
  • Used in DeFi protocols on Specter

Burn-and-Unlock Flow (Bridging Back)

To bridge tokens back to the source chain, the process reverses:

// On Specter -- user burns g-tokens and triggers unlock on source chain
gUSDC.transferRemote{value: bridgeFee}(
ethereumDomainId, // Hyperlane domain ID for Ethereum
recipientBytes32, // Recipient address on Ethereum
amount // Amount to bridge back
);

TokenRouter Base Class

HypGhostERC20Synthetic extends Hyperlane's TokenRouter base class, which provides the standard warp route interface:

abstract contract TokenRouter is GasRouter {
/// @notice Transfer tokens to a remote chain
function transferRemote(
uint32 destination,
bytes32 recipient,
uint256 amount
) public payable virtual returns (bytes32 messageId);

/// @notice Handle an incoming transfer from a remote chain
function _handle(
uint32 origin,
bytes32 sender,
bytes calldata body
) internal virtual override;
}

The TokenRouter handles:

  • Message formatting and dispatching via the Hyperlane mailbox
  • Gas payment for cross-chain message delivery
  • Router registration (mapping domain IDs to remote router addresses)
  • Reentrancy protection

HypGhostERC20Synthetic overrides _handle to implement the mint logic and transferRemote to implement the burn logic.

Interchain Security Modules (ISMs)

Hyperlane's security is modular -- each warp route can configure its own security model via an Interchain Security Module. Specter uses two ISM types:

TrustedRelayerISM

The TrustedRelayerISM designates a single trusted relayer whose signature is sufficient to validate cross-chain messages. This is the simpler model, used during the testnet phase:

contract TrustedRelayerISM is IInterchainSecurityModule {
address public trustedRelayer;

function verify(
bytes calldata metadata,
bytes calldata message
) external view returns (bool) {
// Verify the message was signed by the trusted relayer
address signer = recoverSigner(metadata, message);
return signer == trustedRelayer;
}
}

Properties:

  • Single point of trust
  • Low latency (no multi-party coordination)
  • Suitable for testnet and controlled environments
  • The trusted relayer is operated by the Specter team

MultisigISM

The MultisigISM requires signatures from a quorum of validators before a cross-chain message is accepted:

contract MultisigISM is IInterchainSecurityModule {
address[] public validators;
uint256 public threshold;

function verify(
bytes calldata metadata,
bytes calldata message
) external view returns (bool) {
// Extract signatures from metadata
// Verify at least `threshold` valid validator signatures
uint256 validSignatures = 0;
for (uint256 i = 0; i < signatures.length; i++) {
address signer = recoverSigner(signatures[i], message);
if (isValidator[signer]) {
validSignatures++;
}
}
return validSignatures >= threshold;
}
}

Properties:

  • Decentralized trust (Byzantine fault tolerant with threshold t of n validators)
  • Higher latency (must collect t signatures)
  • Suitable for mainnet deployment
  • Validator set is configurable per route

Privacy Integration

The bridge itself is not private -- token locking on the source chain and g-token minting on Specter are visible on their respective chains. Privacy begins when the user commits g-tokens to the CommitRevealVault:

The privacy boundary is between the commit and reveal steps. An observer can see:

  • Alice bridges 1000 USDC from Ethereum to Specter (public)
  • Someone commits gUSDC to the vault (potentially linkable to Alice)
  • Someone reveals gUSDC from the vault to a fresh address (unlinkable -- ZK proof)
  • A fresh address bridges gUSDC back to Ethereum (public, but unlinkable to Alice)

For maximum privacy, users should:

  1. Use a fresh address to commit (funded by the Gas Relayer)
  2. Wait for other commits to increase the anonymity set
  3. Reveal to another fresh address
  4. Bridge back from the fresh address

Cross-Chain Commit Flow

A common pattern is committing bridged tokens directly into the privacy layer:

import { ethers } from "ethers";
import { poseidon2, poseidon7 } from "poseidon-lite";

const BN254_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;

// 1. Bridge USDC from Ethereum to Specter (already completed)
// User now has gUSDC on Specter

const gUSDC = new ethers.Contract(
"0x65c9091a6A45Db302a343AF460657C298FAA222D",
erc20ABI,
signer
);

// 2. Approve CommitRevealVault to spend gUSDC
const amount = ethers.parseUnits("1000", 6); // 1000 USDC (6 decimals)
await gUSDC.approve(commitRevealVaultAddress, amount);

// 3. Compute commitment
const secret = randomFieldElement();
const nullifierSecret = randomFieldElement();
const blinding = randomFieldElement();
const tokenId = poseidon2([
BigInt("0x65c9091a6A45Db302a343AF460657C298FAA222D"),
0n,
]);
const policyId = 0n;
const policyParamsHash = 0n;

const commitment = poseidon7([
secret,
nullifierSecret,
tokenId,
amount,
blinding,
policyId,
policyParamsHash,
]);

// 4. Commit to the vault
await commitRevealVault.commitERC20(
gUSDC.address,
amount,
commitment
);

Deployed Warp Routes

Each supported token has a warp route configuration mapping source chain collateral contracts to the Specter synthetic contract:

Ethereum USDC ←→ Specter gUSDC (0x65c9091a6A45Db302a343AF460657C298FAA222D)
Ethereum WETH ←→ Specter gWETH (0x923295a3e3bE5eDe29Fc408A507dA057ee044E81)
Base USDC ←→ Specter gUSDC (shared synthetic)
Arbitrum USDC ←→ Specter gUSDC (shared synthetic)

Multiple source chains can map to the same synthetic token on Specter. For example, USDC bridged from Ethereum, Base, and Arbitrum all mint the same gUSDC token. This unifies liquidity and ensures users from different source chains share the same anonymity set when committing to the vault.

Gas and Fees

Cross-chain transfers incur two types of fees:

FeePaid OnDescription
Bridge gasSource chainNative gas for the transferRemote transaction + Hyperlane relay gas payment
Destination gasSpecterCovered by the Hyperlane relayer; the user does not need GHOST to receive bridged tokens

The Hyperlane relayer covers destination gas costs, meaning a user can bridge tokens to Specter even if they have no GHOST. Once the g-tokens are minted, the user can use the Gas Relayer to obtain a small amount of GHOST for subsequent transactions.

Security Considerations

Collateral Risk

The security of bridged tokens depends on the collateral contracts on source chains. If a collateral contract is compromised, an attacker could mint unbacked synthetic tokens on Specter. Mitigations:

  • Collateral contracts use audited Hyperlane HypERC20Collateral implementations
  • ISM validation ensures only authorized routers can trigger mints
  • Rate limits can be configured per route to cap maximum bridged amounts

ISM Upgrade Path

The ISM can be upgraded without redeploying the synthetic token contract. The planned upgrade path is:

  1. Testnet: TrustedRelayerISM (current)
  2. Early mainnet: MultisigISM with 3-of-5 validator threshold
  3. Mature mainnet: MultisigISM with higher validator count + optional ZK light client ISM

Bridge Monitoring

The Bridge Relayer and Health Monitor services continuously watch for:

  • Mismatched collateral/synthetic balances (supply invariant)
  • Delayed message delivery (potential relayer failure)
  • Unauthorized mint attempts (ISM bypass attempts)
  • Unusual volume patterns (potential exploit indicators)