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-examplespackage. Do not copy contracts from LayerZero repositories directly to your project. - If your project requires token bridging inherit your token from
OFTorONFT. For new tokens useOFTorONFT, for bridging existing tokens useProxyOFTorProxyONFT. - For bridging only between EVM chains use
OFTand for bridging between EVM and non EVM chains (e.g., Aptos) useOFTV2. - Do not hardcode LayerZero chain Ids. Use admin restricted setters instead.
- Do not hardcode address zero (
address(0)) aszroPaymentAddresswhen estimating fees and sending messages. Pass it as a parameter instead. - Do not hardcode
useZrotofalsewhen estimating fees and sending messages. Pass it as a parameter instead. - Do not hardcode zero bytes (
bytes(0)) asadapterParamers. Pass them as a parameter instead. - Set
setUseCustomAdapterParamsasTruefor 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
setMinDstGasto 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 destinationgas >= amountset in theminDstGasLookupfor 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
requiresstatements 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 calllzEndpoint.senddirectly, use_lzSend. - For ONFTs that allow minting a range of tokens on each chain, make the variables that specify the range (e.g.
startMintIdandendMintId) immutable.