MAINNET chainIds WERE UPDATED ON SEPTEMBER 6. PLEASE REFER TO https://github.com/LayerZero-Labs/set-trusted-remotes
- A formal audit (May 21, 2022) can in /audit folder *
yarn install
npx hardhat test
- The code in the
/contracts
folder demonstrates LayerZero behaviours. NonblockingLzApp
is a great contract to extend. Take a look at howOmniCounter
overrides_nonblockingLzReceive
and_LzReceive
to easily handle messaging. There are also example forOFT
andONFT
which illustrate erc20 and erc721 cross chain functionality.- Always audit your own code and test extensively on
testnet
before going to mainnet 🙏
The examples below use two chains, however you could substitute any LayerZero supported chain!
The OmnichainFungibleToken
has two varieties of deployments:
BasedOFT.sol
- The token supply is minted (on deployment) on thebase
chain. Other chains deploy with 0 supply initially.OFT.sol
- At deploy time, any quantity of tokens can be minted, regardless of chain.
For the BasedOFT
, the initial supply will be minted entirely on the Base Chain
on deployment. All tokens transferred out of the base
chain will be locked in the contract (and minted on destination), and tokens transferred out of other
chains will be burned on that chain. Tokens returning to the base
chain will be unlocked
and transferred to the destination address. This results in the Base chain
being like the home base, hence the name.
In the example deployment below we use BasedOFT
and the base
chain is rinkeby
.
This setting is configured in constants/oftBaseChain.json
.
The OmnichainFungibleToken
deployed on other chains will use this configuration to set their base
chain.
Using the Ethereum network (testnet: rinkeby)
as a base
(really its like the source of truth) is a security decision.
In the event a chain goes rogue, Ethereum will be the final source of truth for OFT tokens.
- Add a .env file (to the root project directory) with your MNEMONIC="" and fund your wallet in order to deploy!
- Follow any of the tutorials below
WARNING: You must perform the setTrustedRemote() (step 2).
- Deploy two contracts:
rinkeby
is thebase
chain. Fuji is the oft for the other chain.
npx hardhat --network rinkeby deploy --tags ExampleBasedOFT
npx hardhat --network fuji deploy --tags ExampleOFT
- Set the "trusted remotes" (ie: your contracts) so each of them can receive messages from one another, and
only
one another.
npx hardhat --network rinkeby setTrustedRemote --target-network fuji --local-contract ExampleBasedOFT --remote-contract ExampleOFT
npx hardhat --network fuji setTrustedRemote --target-network rinkeby --local-contract ExampleOFT --remote-contract ExampleBasedOFT
- Send tokens from rinkeby to fuji
npx hardhat --network rinkeby oftSend --target-network fuji --qty 42
Pro-tip: Check the ERC20 transactions tab of the destination chain block explorer and await your tokens!
This ONFT contract allows minting of nftId
s on separate chains. To ensure two chains can not mint the same nfId
each contract on each chain is only allowed to mintnftIds
in certain ranges.
Check constants/onftArgs.json
for the specific test configuration used in this demo.
WARNING: You must perform the setTrustedRemote() (step 2).
- Deploy two contracts:
npx hardhat --network bsc-testnet deploy --tags ExampleUniversalONFT721
npx hardhat --network fuji deploy --tags ExampleUniversalONFT721
- Set the "trusted remotes", so each contract can send & receive messages from one another, and
only
one another.
npx hardhat --network bsc-testnet onftSetTrustedRemote --target-network fuji
npx hardhat --network fuji onftSetTrustedRemote --target-network bsc-testnet
- Mint an NFT on each chain!
npx hardhat --network bsc-testnet onftMint
npx hardhat --network fuji onftMint
- [Optional] Show the token owner(s)
npx hardhat --network bsc-testnet onftOwnerOf --token-id 1
npx hardhat --network fuji onftOwnerOf --token-id 11
- Send ONFT across chains
npx hardhat --network bsc-testnet onftSend --target-network fuji --token-id 1
- Verify your token no longer exists on the source chain & wait for it to reach the destination side.
npx hardhat --network bsc-testnet onftOwnerOf --token-id 1
npx hardhat --network fuji onftOwnerOf --token-id 1
OmniCounter is a simple contract with a counter. You can only remotely increment the counter!
- Deploy both OmniCounters:
npx hardhat --network bsc-testnet deploy --tags OmniCounter
npx hardhat --network fuji deploy --tags OmniCounter
- Set the remote addresses, so each contract can receive messages
npx hardhat --network bsc-testnet ocSetTrustedRemote --target-network fuji
npx hardhat --network fuji ocSetTrustedRemote --target-network bsc-testnet
- Send a cross chain message from
bsc-testnet
tofuji
!
npx hardhat --network bsc-testnet ocIncrementCounter --target-network fuji
Optionally use this command in a separate terminal to watch the counter increment in real-time.
npx hardhat --network fuji ocPoll
Just use our checkWireUpAll task by running the following command with the correct Contract parameter
npx hardhat checkWireUpAll --e testnet --contract OmniCounter
Many of the example contracts make use of LayerZeroEndpointMock.sol which is a nice way to test LayerZero locally!