Nomad Docs
  • Nomad 101
    • Funds Recovery
    • Introduction
    • Our Mission
    • Getting Started
  • The Nomad Protocol
    • Overview
    • Cross-chain Messaging
      • Lifecycle of a Message
    • Verification Mechanisms
      • Background on Verification
      • Native Verification
      • External Verification
      • Optimistic Verification
      • Comparing Mechanisms
    • Security
      • Root of Trust
        • Fraud
          • Optimistic Timeout Period
          • Fraud Recovery
        • App-Governed Root of Trust
        • Liveness Assumptions
      • Attack Vectors
        • Key Compromise
        • Economic Attacks
        • Smart Contract Bugs
      • Long-Term Security
        • Permissionless Watchers
        • Financial Controls
        • Cross-Domain MEV
    • Smart Contracts
      • Home
      • Replica
      • XAppConnectionManager
    • Off-chain Agents
      • Updater
      • Watchers
      • Relayer
      • Processor
  • Token Bridge
    • Overview
    • How to Bridge
      • Using Etherscan
      • Nomad Bridge App
      • Testnet Bridge App
    • Asset Issuers
      • Custom Representations
    • Deployed Tokens
      • Mainnet
      • Testnet
    • Smart Contracts
      • BridgeRouter
      • TokenRegistry
      • BridgeToken
      • BridgeMessage
    • Architecture
    • FAQ
  • Governance Bridge
    • Overview
    • Zodiac: Nomad Module
    • Smart Contracts
      • NomadModule
    • Architecture
  • Developers
    • Quickstart
      • Send Messages
      • Receive Messages
    • Environments
      • Domain (Chain) IDs
    • Application Developers
      • Building xApps
      • SDK
        • Contracts SDK
        • Typescript SDK
      • Examples
        • Ping Pong
        • Example Bridge GUI
        • xApp Example
      • Advanced
        • Router Pattern
    • Node Operators
      • Running Agents Guide
        • Troubleshooting
      • Running a Watcher
      • Agent Operations
      • Agent Gas Values
      • The Keymaster
    • Core Developers
      • Upgrade Setup
      • Deploying Contracts
        • Development
        • Production
  • Operational Security
    • Audits
    • Bug Bounty
    • Governance
    • Contracts
    • Agent Operations
  • Resources
    • Awesome Interoperability
    • Brand Kit
    • FAQ
    • Glossary
    • GitHub
    • Discord
    • Twitter
    • Website
Powered by GitBook
On this page
  • Sending and Receiving Tokens
  • Enrolling Custom Representations
  1. Token Bridge
  2. Smart Contracts

BridgeRouter

PreviousSmart ContractsNextTokenRegistry

Last updated 2 years ago

Contract code:

The BridgeRouter contract is the entry point for the token bridge application and implements its interface, per . It enables users to “send” tokens from Chain A to Chain B via a lock-and-mint mechanism.

Sending and Receiving Tokens

Sending

The sending side logic is implemented in the function:

// ======== External: Send Token =========

/**
 * @notice Send tokens to a recipient on a remote chain
 * @param _token The token address
 * @param _amount The token amount
 * @param _destination The destination domain
 * @param _recipient The recipient address
 */
function send(
    address _token,
    uint256 _amount,
    uint32 _destination,
    bytes32 _recipient,
    bool /*_enableFast - deprecated field, left argument for backwards compatibility */
) external;

Receiving

// ======== External: Handle =========

/**
 * @notice Handles an incoming message
 * @param _origin The origin domain
 * @param _nonce The unique identifier for the message from origin to destination
 * @param _sender The sender address
 * @param _message The message
 */
function handle(
    uint32 _origin,
    uint32 _nonce,
    bytes32 _sender,
    bytes memory _message
) external override onlyReplica onlyRemoteRouter(_origin, _sender);

Lock-and-Mint Mechanism

The BridgeRouter enforces the following strict invariant:

The amount locked on the chain where the token originates must always be equal to the circulation of representational tokens minted on all destination chains.

You can see this in the codebase here:

Enrolling Custom Representations

    // ======== External: Custom Tokens =========

    /**
     * @notice Enroll a custom token. This allows projects to work with
     * governance to specify a custom representation.
     * @param _domain the domain of the canonical Token to enroll
     * @param _id the bytes32 ID of the canonical of the Token to enroll
     * @param _custom the address of the custom implementation to use.
     */
    function enrollCustom(
        uint32 _domain,
        bytes32 _id,
        address _custom
    ) external onlyOwner {
        // Sanity check. Ensures that human error doesn't cause an
        // unpermissioned contract to be enrolled.
        IBridgeToken(_custom).mint(address(this), 1);
        IBridgeToken(_custom).burn(address(this), 1);
        tokenRegistry.enrollCustom(_domain, _id, _custom);
    }

The receiving side logic is implemented in the function:

Sending side:

Receiving side:

The BridgeRouter enables custom tokens to be enrolled by calling :

https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-bridge/contracts/BridgeRouter.sol
the Router pattern
send
handle
https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-bridge/contracts/BridgeRouter.sol#L149
https://github.com/nomad-xyz/monorepo/blob/main/packages/contracts-bridge/contracts/BridgeRouter.sol#L278
enrollCustom