# 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"
  }
]
```
