James Bachini

Building A Cross Chain Token Bridge With LayerZero v2

Token Bridge

This tutorial will guide you through the process of building a token bridge using LayerZero v2, specifically employing the OFTAdapter on mainnet and the OFT.sol contract on all other chains. We’ll cover the setup and deployment workflow, ensuring you have a comprehensive understanding of the process.

Before we delve into the deployment process, it’s crucial to understand the key components:

  • OFTAdapter.sol This is used on the mainnet to facilitate token bridging.
  • OFT.sol This contract is deployed on all other chains to enable cross-chain token transfers.

Begin by deploying the OFT contracts to all the chains you intend to connect. This forms the foundation of your token bridge network. You can do this via remix, hardhat or foundry.

OFTAdapter.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { OFTAdapter } from "@layerzerolabs/oft-evm/contracts/OFTAdapter.sol";

contract MyOFTAdapter is OFTAdapter {
    constructor(
        address _token,
        address _lzEndpoint,
        address _delegate
    ) OFTAdapter(_token, _lzEndpoint, _delegate) Ownable(_delegate) {}
}

OFT.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { OFT } from "@layerzerolabs/oft-evm/contracts/OFT.sol";

contract MyOFT is OFT {
    constructor(
        string memory _name,
        string memory _symbol,
        address _lzEndpoint,
        address _delegate
    ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
}
Deploying Cross Chain Token Bridge

Peer & DVN Settings

After deployment, you need to whitelist each destination contract on every destination chain. This is done by calling the setPeer function on each OFT contract. Here’s how you can accomplish this:

uint32 aEid = 30110; // Arbitrum
uint32 bEid = 30184; // Base

MyOFT aOFT;
MyOFT bOFT;

function addressToBytes32(address _addr) public pure returns (bytes32) {
    return bytes32(uint256(uint160(_addr)));
}

// Call on both sides per pathway
aOFT.setPeer(bEid, addressToBytes32(address(bOFT)));
bOFT.setPeer(aEid, addressToBytes32(address(aOFT)));

Ensure you replace the example endpoint IDs with the actual ones for your target chains. You can find the correct endpoint IDs in the LayerZero documentation under Supported Chains.

The next step involves setting up the Default Virtual Node (DVN) configuration. This includes optional settings such as block confirmations, security threshold, the Executor, maximum message size, and send/receive libraries. Here are the key functions you’ll need to call:

EndpointV2.setSendLibrary(aOFT, bEid, newLib)
EndpointV2.setReceiveLibrary(aOFT, bEid, newLib, gracePeriod)
EndpointV2.setReceiveLibraryTimeout(aOFT, bEid, lib, gracePeriod)
EndpointV2.setConfig(aOFT, sendLibrary, sendConfig)
EndpointV2.setConfig(aOFT, receiveLibrary, receiveConfig)
EndpointV2.setDelegate(delegate)

These configurations are stored on-chain as part of EndpointV2, along with your respective SendLibrary and ReceiveLibrary. It’s important to review these settings carefully as they control the verification mechanisms of messages sent between your OApps.

If you don’t set any custom configurations, the system will use the default configurations set by LayerZero Labs. However, it’s generally recommended to review and set your own configurations to ensure they meet your specific security and performance requirements.

Finally before doing a cross-chain transfer you need to approve the OFTadapter as a spender of your ERC20 token. This step is crucial for the token amount you want to transfer. Call the approve function on your ERC20 token contract:

erc20Token.approve(address(oftAdapter), amountToTransfer);
OFTAdapter.send(_sendParam, _fee, _refundAddress);

Remember to thoroughly test your implementation on testnets before deploying to mainnet. Additionally, keep your contracts updated and monitor for any announcements from LayerZero regarding protocol upgrades or security patches.

There’s more information in the official docs: https://docs.layerzero.network/v2/developers/evm/oft/quickstart


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.