OApp Standard

Simplified cross-chain communication for data transfer between contracts on LayerZero v2.

LayerZero v2 is built on the OApp Standard and used to exchange data between contracts on different blockchains. This simplifies complex financial logic in DeFi apps and supports various smart contract use cases.

OApp Example

This interface can be extended for various purposes, including specific financial logic in a DeFi application or a voting mechanism in a DAO. LayerZero offers the OApp for implementing generic message passing in your contracts:

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

import { OAppSender } from "./OAppSender.sol";
// @dev import the origin so its exposed to OApp implementers
import { OAppReceiver, Origin } from "./OAppReceiver.sol";
import { OAppCore } from "./OAppCore.sol";

abstract contract OApp is OAppSender, OAppReceiver {
    constructor(address _endpoint, address _owner) OAppCore(_endpoint, _owner) {}

    function oAppVersion() public pure virtual returns (uint64 senderVersion, uint64 receiverVersion) {
        senderVersion = SENDER_VERSION;
        receiverVersion = RECEIVER_VERSION;
    }
}

The Sender and Receiver libraries provide wrappers over LZ’s endpoint, allowing for the sending (\_lzSend) and receiving (\_lzReceive) of data via internal transactions. The example shows a simple application logic using an Omni Fungible Token (OFT).

Omni Fungible Token (OFT)

The OFT.sol contract is an ERC-20 token for cross-chain transfer capabilities. It includes OAppSender and OAppReceiver libraries, a user-friendly interface for communicating contracts between different blockchain environments.

pragma solidity ^0.8.22;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { OFTCore } from "./OFTCore.sol";

contract OFT is OFTCore, ERC20 {
    constructor(
        string memory _name,
        string memory _symbol,
        address _lzEndpoint,
        address _owner
    ) ERC20(_name, _symbol) OFTCore(decimals(), _lzEndpoint, _owner) {}

    function oftVersion() external pure returns (uint64 major, uint64 minor) {
        return (1, 1);
    }

    function token() external view returns (address) {
        return address(this);
    }

    function _debitSender(
        uint256 _amountToSendLD,
        uint256 _minAmountToCreditLD,
        uint32 _dstEid
    ) internal virtual override returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
        (amountDebitedLD, amountToCreditLD) = _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);

        _burn(msg.sender, amountDebitedLD);
    }

    function _debitThis(
        uint256 _minAmountToReceiveLD,
        uint32 _dstEid
    ) internal virtual override returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
        (amountDebitedLD, amountToCreditLD) = _debitView(balanceOf(address(this)), _minAmountToReceiveLD, _dstEid);

        _burn(address(this), amountDebitedLD);
    }

    function _credit(
        address _to,
        uint256 _amountToCreditLD,
        uint32 /*_srcEid*/
    ) internal virtual override returns (uint256 amountReceivedLD) {
        _mint(_to, _amountToCreditLD);
        return _amountToCreditLD;
    }
}

In the OFT contract, the following functions define the Omni Fungible Token's behavior:

  • The \_oftVersion function: Returns the OFT contract version.
  • The \_token function: Returns the OFT token contract address.
  • The \_debitSender function: Debits tokens from the sender's balance for cross-chain transfers.
  • The \_debitThis function: Debits tokens from the contract's balance for cross-chain transfers.
  • The \_credit function: Credits tokens to the recipient's balance on the target chain, completing the cross-chain transfer.

These functions comprise the core mechanism of managing and transferring tokens in a cross-chain.

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.