# Deplying Hyperlane Warp Routes for ERC20 Token Bridging

### A. **Objective**

In this guide, we will show how to bridge [WETH10](https://sepolia.etherscan.io/address/0xe67abda0d43f7ac8f37876bbf00d1dfadbb93aaa) from L1 (Sepolia) to L2 (Rollup Testnet) using Hyperlane Warp Routes.&#x20;

These steps apply to all other ERC-20 tokens on any AltLayer Rollup

### B. Contract Deployment

For this tutorial, we will use the following addresses

Deployer: `0xC6391bAb6AfCc5dBDcbafA57C3340BbF9C800d33`&#x20;

Validator: `0x7C19F05dB313D89dea09781DF2c076EC1132C423`&#x20;

Relayer: `0x5d3C6567683d9467B2c317A02ddA5B97E20F6029`

{% hint style="info" %}
You will need to generate your own addresses for the following role. Please ensure they are funded with gas tokens
{% endhint %}

To begin, clone the hyperlane repo <https://github.com/hyperlane-xyz/hyperlane-deploy> and run&#x20;

```bash
yarn install
```

Modify `config/chains.ts with your chain configuration`

The following is a sample configuration with L1 being Sepolia and L2 being AltLayer Testnet.&#x20;

```typescript
import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk';

export const chains: ChainMap<ChainMetadata> = {
  sepolia: {
    name: 'sepolia',
    chainId: 11155111,
    nativeToken: {
      name: 'ether',
      symbol: 'ETH',
      decimals: 18,
    },
    publicRpcUrls: [
      {
        http: 'https://eth-sepolia.g.alchemy.com/v2/api-key',
      },
    ],
  },
  testnet: {
    name: 'testnet',
    chainId: 9997,
    nativeToken: {
      name: 'ALT',
      symbol: 'ALT',
      decimals: 18,
    },
    publicRpcUrls: [
      {
        http: 'https://testnet-rollup-api.altlayer.io',
      },
    ],
  },
};
```

Modify `config/multisig_ism.ts.` In this example, we will set it to 1. In the production environment, a higher threshold should be set.&#x20;

```typescript
import { ChainMap, MultisigIsmConfig } from '@hyperlane-xyz/sdk';

export const multisigIsmConfig: ChainMap<MultisigIsmConfig> = {
  // ----------- Your chains here -----------------
  sepolia: {
    threshold: 1,
    validators: [
      '0x7C19F05dB313D89dea09781DF2c076EC1132C423', // validator address
    ],
  },
  testnet: {
    threshold: 1,
    validators: [
      '0x7C19F05dB313D89dea09781DF2c076EC1132C423', // validator address
    ],
  },
};
```

Run the following command using the deployer private key to deploy the contracts on L1 (Sepolia)

```bash
yarn ts-node scripts/deploy-hyperlane.ts --local testnet \
  --remotes sepolia \
  --key <deployer private key>
```

Run the following command using the deployer private key to deploy the contracts on L2&#x20;

```bash
yarn ts-node scripts/deploy-hyperlane.ts --local sepolia \
  --remotes testnet \
  --key <deployer private key>
```

After running the command, some artifacts will be produced. Here's a sample

1. `artifacts/addresses.json`

```json
{
  "testnet": {
    "multisigIsm": "0x63aC18CFB9207ba750393DaB7509F1aAE4F35B97",
    "proxyAdmin": "0x6aa797913c88b03718044924DDC16A3Ee0f37A3F",
    "mailbox": "0x190c91b92c95DEDf09a954aC538CC926945d81Fb",
    "validatorAnnounce": "0xFc9D5Cf9bdd090182968aF7D478Ee9dfF06dD909",
    "testRecipient": "0xD08D64aF4ed573845861Abcd89860ae8889ed12D",
    "storageGasOracle": "0xAd2310dBcB8aae371082831dA587e96BB1E51daD",
    "interchainGasPaymaster": "0xe7A1f91B9049cC4D1a82C271aF4D6CCA9AFeB20e",
    "defaultIsmInterchainGasPaymaster": "0xd51A3FBAC4424a2a0C330686020341FD70ADc9c5"
  },
  "sepolia": {
    "multisigIsm": "0x63aC18CFB9207ba750393DaB7509F1aAE4F35B97",
    "testRecipient": "0x6aa797913c88b03718044924DDC16A3Ee0f37A3F",
    "proxyAdmin": "0x5324d2355c2cB034cE5dCBCB3Fbb868DBa8C982a",
    "storageGasOracle": "0x190c91b92c95DEDf09a954aC538CC926945d81Fb",
    "interchainGasPaymaster": "0x65Ff5C940Dd9f11BE608e44602370B347f581B2b",
    "defaultIsmInterchainGasPaymaster": "0x34407596169673017849399F332819aa5ef0e565",
    "mailbox": "0xd51A3FBAC4424a2a0C330686020341FD70ADc9c5",
    "validatorAnnounce": "0x2c29105f892e6A7F8E0547A9423861734c6352D0"
  }
}
```

2. `artifacts/agent_config.json`

```json
{
  "chains": {
    "sepolia": {
      "name": "sepolia",
      "domain": 11155111,
      "addresses": {
        "mailbox": "0xd51A3FBAC4424a2a0C330686020341FD70ADc9c5",
        "interchainGasPaymaster": "0x65Ff5C940Dd9f11BE608e44602370B347f581B2b",
        "validatorAnnounce": "0x2c29105f892e6A7F8E0547A9423861734c6352D0"
      },
      "protocol": "ethereum",
      "finalityBlocks": 1,
      "connection": {
        "type": "http"
      },
      "index": {
        "from": 3728779
      }
    },
    "testnet": {
      "name": "testnet",
      "domain": 9997,
      "addresses": {
        "mailbox": "0x190c91b92c95DEDf09a954aC538CC926945d81Fb",
        "interchainGasPaymaster": "0xe7A1f91B9049cC4D1a82C271aF4D6CCA9AFeB20e",
        "validatorAnnounce": "0xFc9D5Cf9bdd090182968aF7D478Ee9dfF06dD909"
      },
      "protocol": "ethereum",
      "finalityBlocks": 1,
      "connection": {
        "type": "http"
      },
      "index": {}
    }
  }
}
```

Modify `config/warp_tokens.ts` using values from `artifacts/addresses.json`. In this configuration, we filled the contract addresses of WETH10, the token we would like to bridge from L1 to L2.&#x20;

```typescript
import { TokenType } from '@hyperlane-xyz/hyperlane-token';

import type { WarpRouteConfig } from '../src/warp/config';

// A config for deploying Warp Routes to a set of chains
// Not required for Hyperlane core deployments
export const warpRouteConfig: WarpRouteConfig = {
  base: {
    // Chain name must be in the Hyperlane SDK or in the chains.ts config
    chainName: 'sepolia',
    type: TokenType.collateral, //  TokenType.native or TokenType.collateral
    // If type is collateral, a token address is required:
    address: '0xe67abda0d43f7ac8f37876bbf00d1dfadbb93aaa', // WETH10
    mailbox: '0xd51A3FBAC4424a2a0C330686020341FD70ADc9c5',
    interchainGasPaymaster: '0x65Ff5C940Dd9f11BE608e44602370B347f581B2b',

    // Optionally, specify owner, mailbox, and interchainGasPaymaster addresses
    // If not specified, the Permissionless Deployment artifacts or the SDK's defaults will be used
  },
  synthetics: [
    {
      chainName: 'testnet',
      mailbox: '0x190c91b92c95DEDf09a954aC538CC926945d81Fb',
      interchainGasPaymaster: '0xe7A1f91B9049cC4D1a82C271aF4D6CCA9AFeB20e',

      // Optionally specify a name, symbol, and totalSupply
      // If not specified, the base token's properties will be used

      // Optionally, specify owner, mailbox, and interchainGasPaymaster addresses
      // If not specified, the Permissionless Deployment artifacts or the SDK's defaults will be used
    },
  ],
};
```

Run this command using the deployer private key to deploy the wrap contracts. This will deploy the  H`ypERC20` contracts to L2. In this example, the `HypERC20` contract will be WETH10 on L2.&#x20;

```bash
yarn ts-node scripts/deploy-warp-routes.ts --key <deployer private key>
```

After running the command, artifacts will be produced

1. `artifacts/warp-token-addresses.json`

```json
{
  "sepolia": {
    "router": "0xffA5f94329f41b9353F4ccA74Ba59D3Faed75AAe",
    "tokenType": "collateral"
  },
  "testnet": {
    "router": "0xffA5f94329f41b9353F4ccA74Ba59D3Faed75AAe",
    "tokenType": "synthetic"
  }
}
```

2. `artifacts/warp-ui-token-list.json`

```json
[
  {
    "chainId": 11155111,
    "name": "Wrapped Ether v10",
    "symbol": "WETH10",
    "decimals": 18,
    "type": "collateral",
    "address": "0xe67abda0d43f7ac8f37876bbf00d1dfadbb93aaa",
    "hypCollateralAddress": "0xffA5f94329f41b9353F4ccA74Ba59D3Faed75AAe"
  }
]
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.altlayer.io/altlayer-documentation/external-integrations/enabling-permissionless-interoperability-on-altlayer-rollup-with-hyperlane/deplying-hyperlane-warp-routes-for-erc20-token-bridging.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
