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
| Property | Value |
|---|---|
| Bridge protocol | Hyperlane (modular interoperability) |
| Token model | Lock-and-mint / burn-and-unlock |
| Base class | TokenRouter (Hyperlane warp route) |
| Source chains | Ethereum, Base, Arbitrum |
| Destination chain | Specter (Chain ID 5446) |
| Security models | TrustedRelayerISM, MultisigISM |
Supported Tokens
The following synthetic g-tokens are deployed on Specter, each backed 1:1 by tokens locked on their source chain:
| Token | Symbol | Specter Address | Underlying |
|---|---|---|---|
| Ghost USDC | gUSDC | 0x65c9091a6A45Db302a343AF460657C298FAA222D | USDC on Ethereum/Base/Arbitrum |
| Ghost WETH | gWETH | 0x923295a3e3bE5eDe29Fc408A507dA057ee044E81 | WETH on Ethereum/Base/Arbitrum |
| Ghost LABS | gLABS | 0x062f8a68f6386c1b448b3379abd369825bec9aa2 | LABS token |
| Ghost VIRTUAL | gVIRTUAL | 0xaF12d2f962179274f243986604F97b961a4f4Cfc | VIRTUAL 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:
- Transfers
amountof the token from the user to itself (lock) - 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:
| Field | Description |
|---|---|
sender | Collateral contract address on source chain |
recipient | HypGhostERC20Synthetic address on Specter |
body | ABI-encoded (address to, uint256 amount) |
origin | Source 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
tofnvalidators) - Higher latency (must collect
tsignatures) - 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:
- Use a fresh address to commit (funded by the Gas Relayer)
- Wait for other commits to increase the anonymity set
- Reveal to another fresh address
- 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:
| Fee | Paid On | Description |
|---|---|---|
| Bridge gas | Source chain | Native gas for the transferRemote transaction + Hyperlane relay gas payment |
| Destination gas | Specter | Covered 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
HypERC20Collateralimplementations - 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:
- Testnet: TrustedRelayerISM (current)
- Early mainnet: MultisigISM with 3-of-5 validator threshold
- 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)