LayerZero Integration Checklist

The checklist below is intended to help prepare a project that integrates LayerZero for an external audit or Mainnet deployment
  • Use the latest version of solidity-examples package. Do not copy contracts from LayerZero repositories directly to your project.
  • If your project requires token bridging inherit your token from OFT or ONFT. For new tokens use OFT or ONFT, for bridging existing tokens use ProxyOFT or ProxyONFT.
  • For bridging only between EVM chains use OFT and for bridging between EVM and non EVM chains (e.g., Aptos) use OFTV2.
  • Do not hardcode LayerZero chain Ids. Use admin restricted setters instead.
  • Do not hardcode address zero (address(0)) as zroPaymentAddress when estimating fees and sending messages. Pass it as a parameter instead.
  • Do not hardcode useZro to false when estimating fees and sending messages. Pass it as a parameter instead.
  • Do not hardcode zero bytes (bytes(0)) as adapterParamers. Pass them as a parameter instead.
  • Set setUseCustomAdapterParams as True for OFT and ONFT
  • Test the amount of gas required for the execution on the destination chain. Use custom adapter parameters and specify the minimum destination gas for each cross-chain path when the default amount of gas (200,000) is not enough.
  • Call setMinDstGas to set the minimum gas. (200k for OFT for all EVMs except Arbitrum is enough. For Arbitrum, set as 2M. ) This requires whoever calls the send function to provide the adapter params with a destination gas >= amount set in the minDstGasLookup for that chain. So that your users don't run into failed messages on the destination. It makes it a smoother end-to-end experience for all.
  • Do not add requires statements that repeat existing checks in the parent contracts. For example, lzReceive function in LzApp contract checks that the message sender is LayerZero endpoint and the scrAddress is a trusted remote, do not perform the same checks in nonblockingLzReceive.
  • If your contract derives from LzApp, do not call lzEndpoint.send directly, use _lzSend.
  • For ONFTs that allow minting a range of tokens on each chain, make the variables that specify the range (e.g. startMintId and endMintId) immutable.