Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add layer zero examples #3326

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions tools/layer-zero-example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# keys
HEDERA_PK=0x
BSC_PK=0x

# OApp config
OAPP_HEDERA_CONTRACT=0x
OAPP_BSC_CONTRACT=0x

# OFT config
OFT_HEDERA_CONTRACT=0x
OFT_BSC_CONTRACT=0x

# OFT Adapter config
ERC20_HEDERA_CONTRACT=0x
ERC20_BSC_CONTRACT=0x
OFT_ADAPTER_HEDERA_CONTRACT=0x
OFT_ADAPTER_BSC_CONTRACT=0x

# ONFT config
ONFT_HEDERA_CONTRACT=0x
ONFT_BSC_CONTRACT=0x

# ONFT Adapter config
ERC721_HEDERA_CONTRACT=0x
ERC721_BSC_CONTRACT=0x
ONFT_ADAPTER_HEDERA_CONTRACT=0x
ONFT_ADAPTER_BSC_CONTRACT=0x

# OFT HTS config
OFT_HTS_HEDERA_CONTRACT=0x
OFT_HTS_BSC_CONTRACT=0x
17 changes: 17 additions & 0 deletions tools/layer-zero-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
node_modules
.env

# Hardhat files
/cache
/artifacts

# TypeChain files
/typechain
/typechain-types

# solidity-coverage files
/coverage
/coverage.json

# Hardhat Ignition default folder for deployments against a local node
ignition/deployments/chain-31337
125 changes: 125 additions & 0 deletions tools/layer-zero-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Layer Zero examples

### OApp
Nana-EC marked this conversation as resolved.
Show resolved Hide resolved

npx hardhat deploy-oapp --network hedera_testnet
npx hardhat deploy-oapp --network bsc_testnet

npx hardhat set-peer --source <hedera_oapp_address> --target <bsc_oapp_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_oapp_address> --target <hedera_oapp_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "OAppTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "OAppTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "OAppTests @hedera @test" --network hedera_testnet
npx hardhat test --grep "OAppTests @bsc @test" --network bsc_testnet


### OFT

npx hardhat deploy-oft --decimals 18 --mint 1000000000000000000 --network hedera_testnet
npx hardhat deploy-oft --decimals 18 --mint 1000000000000000000 --network bsc_testnet

npx hardhat set-peer --source <hedera_oft_address> --target <bsc_oft_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_oft_address> --target <hedera_oft_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "OFTTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "OFTTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "OFTTests @hedera @test" --network hedera_testnet
npx hardhat test --grep "OFTTests @bsc @test" --network bsc_testnet

### OFT Adapter

npx hardhat deploy-erc20 --network hedera_testnet
npx hardhat deploy-erc20 --network bsc_testnet

npx hardhat deploy-oft-adapter --token <erc20_hedera_address> --network hedera_testnet
npx hardhat deploy-oft-adapter --token <erc20_bsc_address> --network bsc_testnet

npx hardhat set-peer --source <hedera_oft_adapter_address> --target <bsc_oft_adapter_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_oft_adapter_address> --target <hedera_oft_adapter_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "OFTAdapterTests @hedera @fund-and-approve" --network hedera_testnet
npx hardhat test --grep "OFTAdapterTests @bsc @fund-and-approve" --network bsc_testnet

npx hardhat test --grep "OFTAdapterTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "OFTAdapterTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "OFTAdapterTests @hedera @test" --network hedera_testnet
npx hardhat test --grep "OFTAdapterTests @bsc @test" --network bsc_testnet

### ONFT

npx hardhat deploy-onft --network hedera_testnet
npx hardhat deploy-onft --network bsc_testnet

npx hardhat set-peer --source <hedera_onft_address> --target <bsc_onft_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_onft_address> --target <hedera_onft_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "ONFTTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "ONFTTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "ONFTTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "ONFTTests @bsc @send" --network bsc_testnet

### ONFT Adapter

npx hardhat deploy-erc721 --network hedera_testnet
npx hardhat deploy-erc721 --network bsc_testnet

npx hardhat deploy-onft-adapter --token <erc721_hedera_address> --network hedera_testnet
npx hardhat deploy-onft-adapter --token <erc721_bsc_address> --network bsc_testnet

npx hardhat set-peer --source <hedera_onft_adapter_address> --target <bsc_onft_adapter_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_onft_adapter_address> --target <hedera_onft_adapter_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "ONFTAdapterTests @hedera @mint" --network hedera_testnet
npx hardhat test --grep "ONFTAdapterTests @bsc @mint" --network bsc_testnet

npx hardhat test --grep "ONFTAdapterTests @hedera @approve" --network hedera_testnet
npx hardhat test --grep "ONFTAdapterTests @bsc @approve" --network bsc_testnet

npx hardhat test --grep "ONFTAdapterTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "ONFTAdapterTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "ONFTAdapterTests @hedera @test" --network hedera_testnet
npx hardhat test --grep "ONFTAdapterTests @bsc @test" --network bsc_testnet

### OFT HTS

npx hardhat deploy-oft-hts --network hedera_testnet
npx hardhat deploy-oft --decimals 8 --mint 1000 --network bsc_testnet

npx hardhat set-peer --source <hedera_oft_address> --target <bsc_oft_address> --network hedera_testnet
npx hardhat set-peer --source <bsc_oft_address> --target <hedera_oft_address> --network bsc_testnet

fill the .env

npx hardhat test --grep "OFTHTSTests @hedera @send" --network hedera_testnet
npx hardhat test --grep "OFTHTSTests @bsc @send" --network bsc_testnet

wait a couple minutes, the LZ progress can be tracked on https://testnet.layerzeroscan.com/tx/<tx_hash>

npx hardhat test --grep "OFTHTSTests @hedera @test" --network hedera_testnet
npx hardhat test --grep "OFTHTSTests @bsc @test" --network bsc_testnet
45 changes: 45 additions & 0 deletions tools/layer-zero-example/contracts/BaseHTSOFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: MIT
natanasow marked this conversation as resolved.
Show resolved Hide resolved

pragma solidity ^0.8.20;

import {OFTCore} from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFTCore.sol";

/**
* @title OFT Contract
* @dev OFT is an ERC-20 token that extends the functionality of the OFTCore contract.
*/
abstract contract BaseHTSOFT is OFTCore {
/**
* @dev Constructor for the OFT contract.
* @param _name The name of the OFT.
* @param _symbol The symbol of the OFT.
* @param _lzEndpoint The LayerZero endpoint address.
* @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
*/
constructor(
string memory _name,
string memory _symbol,
address _lzEndpoint,
address _delegate
) OFTCore(8, _lzEndpoint, _delegate) {}

/**
* @dev Retrieves the address of the underlying ERC20 implementation.
* @return The address of the OFT token.
*
* @dev In the case of OFT, address(this) and erc20 are the same contract.
*/
function token() public view returns (address) {
return address(this);
}

/**
* @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
* @return requiresApproval Needs approval of the underlying token implementation.
*
* @dev In the case of OFT where the contract IS the token, approval is NOT required.
*/
function approvalRequired() external pure virtual returns (bool) {
return false;
}
}
10 changes: 10 additions & 0 deletions tools/layer-zero-example/contracts/ERC20Mock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

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

contract ERC20Mock is ERC20 {
constructor() ERC20("ERC20Mock", "E20M") {
_mint(msg.sender, 10000000000000000000);
}
}
12 changes: 12 additions & 0 deletions tools/layer-zero-example/contracts/ERC721Mock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

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

contract ERC721Mock is ERC721 {
constructor() ERC721("ERC721Mock", "E721M") {}

function mint(address _to, uint256 _tokenId) external {
_mint(_to, _tokenId);
}
}
74 changes: 74 additions & 0 deletions tools/layer-zero-example/contracts/ExampleOApp.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

import {OApp, Origin, MessagingFee} from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/OApp.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract ExampleOApp is OApp {
constructor(address _endpoint, address _owner) OApp(_endpoint, _owner) Ownable(_owner) {}

// Some arbitrary data you want to deliver to the destination chain!
string public data;

/**
* @notice Sends a message from the source to destination chain.
* @param _dstEid Destination chain's endpoint ID.
* @param _message The message to send.
* @param _options Message execution options (e.g., for sending gas to destination).
*/
function send(
uint32 _dstEid,
string memory _message,
bytes calldata _options
) external payable {
// Encodes the message before invoking _lzSend.
// Replace with whatever data you want to send!
bytes memory _payload = abi.encode(_message);
_lzSend(
_dstEid,
_payload,
_options,
// Fee in native gas and ZRO token.
MessagingFee(msg.value, 0),
// Refund address in case of failed source message.
payable(msg.sender)
);
}

/**
* @dev Called when data is received from the protocol. It overrides the equivalent function in the parent contract.
* Protocol messages are defined as packets, comprised of the following parameters.
* @param _origin A struct containing information about where the packet came from.
* @param _guid A global unique identifier for tracking the packet.
* @param payload Encoded message.
*/
function _lzReceive(
Origin calldata _origin,
bytes32 _guid,
bytes calldata payload,
address, // Executor address as specified by the OApp.
bytes calldata // Any extra data or options to trigger on receipt.
) internal override {
// Decode the payload to get the message
// In this case, type is string, but depends on your encoding!
data = abi.decode(payload, (string));
}

/**
* @notice Quotes the gas needed to pay for the full omnichain transaction in native gas or ZRO token.
* @param _dstEid Destination chain's endpoint ID.
* @param _message The message.
* @param _options Message execution options (e.g., for sending gas to destination).
* @param _payInLzToken Whether to return fee in ZRO token.
* @return fee A `MessagingFee` struct containing the calculated gas fee in either the native token or ZRO token.
*/
function quote(
uint32 _dstEid,
string memory _message,
bytes memory _options,
bool _payInLzToken
) public view returns (MessagingFee memory fee) {
bytes memory payload = abi.encode(_message);
fee = _quote(_dstEid, payload, _options, _payInLzToken);
}
}
25 changes: 25 additions & 0 deletions tools/layer-zero-example/contracts/ExampleOFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

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

contract ExampleOFT is OFT {
uint8 decimalsArg = 8;

constructor(
string memory _name,
string memory _symbol,
address _lzEndpoint,
address _delegate,
uint256 _initialMint,
uint8 _decimals
) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {
_mint(msg.sender, _initialMint);
decimalsArg = _decimals;
}

function decimals() public view override returns (uint8) {
return decimalsArg;
}
}
13 changes: 13 additions & 0 deletions tools/layer-zero-example/contracts/ExampleOFTAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

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

contract ExampleOFTAdapter is OFTAdapter {
constructor(
address _token,
address _lzEndpoint,
address _owner
) OFTAdapter(_token, _lzEndpoint, _owner) Ownable(_owner) {}
}
Loading
Loading