From d7a952e71c351c886d143cdaab9e2771797a74a6 Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Fri, 24 May 2024 19:57:33 +0530 Subject: [PATCH 1/7] Add article for ERC20 token transfer across chains --- .../docs/how-tos/send-ERC20-across-chains.md | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md diff --git a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md new file mode 100644 index 00000000000..a880be90304 --- /dev/null +++ b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md @@ -0,0 +1,174 @@ +# Send ERC20 Tokens Across Chains + +## Introduction + +To enable cross-chain transfers of existing ERC20 tokens such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively), LayerZero OFT V2 is utilized. For testing purposes, Sepolia is chosen as the source chain, while the BNB testnet is chosen as the destination chain. + +:::info +Clone the repository for Utilities for LayerZero OFT V2 from [here](https://github.com/iota-community/layerzero-oft-v2-utils). +::: + +### Why Would a User Need to Send ERC20 Tokens Across Chains? + +Sending ERC20 tokens across chains allows users to leverage the strengths and unique features of different blockchain networks, optimize costs, and manage risks more effectively. This flexibility is crucial as the blockchain ecosystem continues to grow and diversify. + +[**Use-case 1**](https://docs.layerzero.network/v2/developers/evm/oft/adapter) + +To enable existing ERC20 tokens for cross-chain sending, both OFTAdapter and OFT contracts are needed. + +[**Use-case 2**](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) + +For new ERC20 tokens to be launched, the OFT standard can be leveraged to enable cross-chain sending without the need for an OFTAdapter. + +### Using IOTA's Implementation of [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) + +The Utilities for LayerZero OFT V2 facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM testnet) and a destination chain (e.g., BNB testnet or IOTA EVM testnet). + +:::tip +Further information: https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types. +::: + +### Procedure to Send Tokens from Source Chain to Destination Chain and Vice Versa + +For existing ERC20 tokens that involve both the OFTAdapter contract (on the source chain) and the OFT contract (on the destination chain), the token sending procedure is as follows: + +1. **Approve Tokens**: The sender approves their ERC20 tokens for the OFTAdapter contract. +2. **Estimate Fee**: The sender calls the function `quoteSend()` of the OFTAdapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. +3. **Send Tokens**: The sender calls the function `send()` of the OFTAdapter contract to transfer tokens from the source chain to the destination chain. +4. **Optional - Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). + +To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: + +1. **Estimate Fee**: The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. +2. **Send Tokens**: The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. +3. **Optional - Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. + + + +#### Sample Solidity code for OFTAdater and OFT contracts in folder `contracts-standard` +- Scripts for: + - Deploy OFTAdapter and OFT contracts + - Set trusted peer + - Set enforced options + - Send tokens from source chain to destination chain and vice versa + +## Installation +``` +$ yarn +``` + +## Compile contracts + +- In the standard implementation for ERC20, copy the folder `contracts-standard`to `contracts` and `contracts-wiota` to `contracts` for custom implementation. Then, run the command: + +``` + $ yarn compile +``` + +## Configuration + +The config is specified in the template file `.env.example` that needs to be copied to another file `.env`. + + +## Deploy contracts + +### Deploy OFTAdapter on source chain (e.g. Sepolia) + +The OFT Adapter facilitates the expansion of an existing token to any supported blockchain as a native token, maintaining a unified global supply and inheriting all features of the OFT Standard. This intermediary contract manages the sending and receiving of pre-deployed tokens. + +For instance, when an ERC20 token is transferred from the source chain (Chain A), it gets locked in the OFT Adapter. Consequently, a corresponding token is minted on the destination chain (Chain B) through the paired OFT Contract. + +``` +$ yarn deploy-oft-adapter-sepolia +``` + + +Log output : + +``` +$ npx hardhat run scripts/deploy_oft_adapter.ts --network sepolia +Deployed MyOFTAdapter contract address: 0x4daa81978576cB91a2e1919960e90e46c2a6D586 +Done in 6.67s. +``` + +### Deploy OFT on destination chain (e.g. BNB testnet) + +``` +$ yarn deploy-oft-bnb-testnet +``` + +Log output : + +``` +$ npx hardhat run scripts/deploy_oft.ts --network bnbTestnet +Deployed MyOFT contract address: 0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +Done in 6.68s. +``` + +## Set trusted peer (Optinal) + +### On OFTAdapter (source chain, e.g. Sepolia) + +``` +$ yarn set-peer-oft-adapter-sepolia +``` + +Log output : + +``` +$ npx hardhat run scripts/set_peer_oft_adapter.ts --network sepolia +setPeerMyOFTAdapter - oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586, lzEndpointIdOnDestChain:40102, oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +MyOFTAdapter - setPeer tx: 0xc17e7a54d96325768b6427ce893d9b6b7ed04bd920089b63a3f96c005073e9c2 +Done in 14.10s. +``` + +### On OFT (destination chain, e.g. BNB testnet) + +``` +$ yarn set-peer-oft-bnb-testnet +``` + +Log output : + +``` +$ npx hardhat run scripts/set_peer_oft.ts --network bnbTestnet +setPeerMyOFT - oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1, lzEndpointIdOnSrcChain:40161, oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586 +MyOFT - setPeer tx: 0xb0012378ee14c9df5c9f86980dd9c96fc8aedb3c19d92c1d91a4259f3981ac35 +Done in 4.66s. +``` + +## Send origin tokens from source chain to destination chain + +``` +$ yarn send-oft-from-sepolia +``` + +Log output : + +``` +$ npx hardhat run scripts/send_oft.ts --network sepolia +sendOFT - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57a4bd139fb673d364a6f12df9177a3f686625f3, amount:2 +sendOFT - approve tx: 0x8fa692edb47b1ad9d21f60b0fa30993e5cd3abd78c3c56fb4f38db5f9b8ac369 +sendOFT - estimated nativeFee: 0.000734209489447653 +sendOFT - send tx on source chain: 0xeb3e44310a09ae2ab2f0d6d6d3fdfd7c490f8ac536bb20a5e16999b23232ef67 +Wait for cross-chain tx finalization by LayerZero ... +sendOFT - received tx on destination chain: 0xc2e5a4be8ae67718e817ff585a32765e393835880068f408fd7724667a25a46c +``` + + +## Send OFT-wrapped tokens back from destination chain to origin chain + +``` +$ yarn send-oft-back-from-bnb-testnet +``` + +Log output : + +``` +$ npx hardhat run scripts/send_oft_back.ts --network bnbTestnet +sendOFTBack - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, amount:2 +sendOFTBack - estimated nativeFee: 0.054815809525020364 +sendOFTBack - send tx on source chain: 0x41bcf78b310dc1bbf9b4005f7412d995011c7815ad5af9cc26b37370e75bbfeb +Wait for cross-chain tx finalization by LayerZero ... +sendOFTBack - received tx on destination chain: 0xc1031694e92512a0189885ad6419e33196a65b8ae56baa9d555be8686d6d42fe +``` \ No newline at end of file From 2bb9e6b204c52b4d628948dfbd2cdc263fd55dd5 Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Fri, 24 May 2024 19:57:46 +0530 Subject: [PATCH 2/7] Add article to side nav-bar --- docs/build/isc/v1.1/sidebars.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/build/isc/v1.1/sidebars.js b/docs/build/isc/v1.1/sidebars.js index a01017561cc..43060c5651f 100644 --- a/docs/build/isc/v1.1/sidebars.js +++ b/docs/build/isc/v1.1/sidebars.js @@ -209,6 +209,11 @@ module.exports = { }, ], }, + { + type: 'doc', + label: 'Send ERC20 Tokens Across Chains', + id: 'how-tos/send-ERC20-across-chains', + }, ], }, { From f44057cb4077016efb27e09a3b4a534ed8eeba69 Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Thu, 30 May 2024 15:23:24 +0530 Subject: [PATCH 3/7] Fix article to send ERC20 across chains --- .../docs/how-tos/send-ERC20-across-chains.md | 160 ++++++++++-------- 1 file changed, 91 insertions(+), 69 deletions(-) diff --git a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md index a880be90304..1c5ec2b54c5 100644 --- a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md +++ b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md @@ -2,10 +2,10 @@ ## Introduction -To enable cross-chain transfers of existing ERC20 tokens such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively), LayerZero OFT V2 is utilized. For testing purposes, Sepolia is chosen as the source chain, while the BNB testnet is chosen as the destination chain. +[LayerZero OFT V2](https://docs.layerzero.network/v2) enables cross-chain transfers of existing ERC20 tokens, such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively). For testing purposes, Sepolia is chosen as the source chain, while the BNB testnet is chosen as the destination chain. -:::info -Clone the repository for Utilities for LayerZero OFT V2 from [here](https://github.com/iota-community/layerzero-oft-v2-utils). +:::info Community Libs +You can clone the Utilities for LayerZero OFT V2 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-oft-v2-utils). ::: ### Why Would a User Need to Send ERC20 Tokens Across Chains? @@ -14,139 +14,158 @@ Sending ERC20 tokens across chains allows users to leverage the strengths and un [**Use-case 1**](https://docs.layerzero.network/v2/developers/evm/oft/adapter) -To enable existing ERC20 tokens for cross-chain sending, both OFTAdapter and OFT contracts are needed. +#### Send Existing ERC20 Tokens Across Chains + +You need both the OFT Adapter and OFT contracts to enable existing ERC20 tokens for cross-chain sending, [**Use-case 2**](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) -For new ERC20 tokens to be launched, the OFT standard can be leveraged to enable cross-chain sending without the need for an OFTAdapter. +#### Create New Cross-chain Fungible Tokens + +If you are about to launch a new ERC20 token, you can use the [OFT standard](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) to enable cross-chain sending without the OFT Adapter. -### Using IOTA's Implementation of [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) +### How To Use IOTA's Utilities for LayerZero OFT V2 -The Utilities for LayerZero OFT V2 facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM testnet) and a destination chain (e.g., BNB testnet or IOTA EVM testnet). +The [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM Testnet) and a destination chain (e.g., BNB Testnet or IOTA EVM Testnet). -:::tip -Further information: https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types. +:::tip Further Information +You can learn more about the available options in the [Layer Zero Documentation](https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types.). ::: -### Procedure to Send Tokens from Source Chain to Destination Chain and Vice Versa +### Send Tokens from One Source Chain to Another Destination Chain (and Vice Versa) -For existing ERC20 tokens that involve both the OFTAdapter contract (on the source chain) and the OFT contract (on the destination chain), the token sending procedure is as follows: +To send existing ERC20 tokens, you will need both the OFT Adapter contract on the source chain and the OFT contract on the destination chain. You should then use the following procedure: -1. **Approve Tokens**: The sender approves their ERC20 tokens for the OFTAdapter contract. -2. **Estimate Fee**: The sender calls the function `quoteSend()` of the OFTAdapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. -3. **Send Tokens**: The sender calls the function `send()` of the OFTAdapter contract to transfer tokens from the source chain to the destination chain. -4. **Optional - Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). +1. **Approve the tokens**: The sender must approve their ERC20 tokens for the OFT Adapter contract. +2. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. +3. **Send the tokens**: The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. +4. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: -1. **Estimate Fee**: The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. +1. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. 2. **Send Tokens**: The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. -3. **Optional - Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. +3. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. + + +#### Sample Solidity code for OFT Adapter and OFT contracts in the folder `contracts-standard` +The [contracts-standard](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) contains scripts to: +- Deploy the OFT Adapter and OFT contracts. +- Set your trusted peers. +- Set enforced options. +- Send tokens from the source chain to the destination chain, and vice versa. +### Install the Library -#### Sample Solidity code for OFTAdater and OFT contracts in folder `contracts-standard` -- Scripts for: - - Deploy OFTAdapter and OFT contracts - - Set trusted peer - - Set enforced options - - Send tokens from source chain to destination chain and vice versa +After you have cloned the [IOTA Community Utilities for LayerZero OFT V2 repository](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main), you should run the following command to install: -## Installation ``` -$ yarn +yarn ``` -## Compile contracts +## Compile the Contracts -- In the standard implementation for ERC20, copy the folder `contracts-standard`to `contracts` and `contracts-wiota` to `contracts` for custom implementation. Then, run the command: +If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: -``` - $ yarn compile +```bash +yarn compile ``` -## Configuration +### Set Your Configuration -The config is specified in the template file `.env.example` that needs to be copied to another file `.env`. +You should copy the template [`.env.example`](https://github.com/iota-community/layerzero-oft-v2-utils/blob/main/.env.example) file to a file called `.env`, and edit any of the configuration options you see fit. +```bash +cp .env.example .env +``` -## Deploy contracts +### Deploy the Contracts -### Deploy OFTAdapter on source chain (e.g. Sepolia) +## Deploy the OFT Adapter Contract On the Source Chain The OFT Adapter facilitates the expansion of an existing token to any supported blockchain as a native token, maintaining a unified global supply and inheriting all features of the OFT Standard. This intermediary contract manages the sending and receiving of pre-deployed tokens. For instance, when an ERC20 token is transferred from the source chain (Chain A), it gets locked in the OFT Adapter. Consequently, a corresponding token is minted on the destination chain (Chain B) through the paired OFT Contract. -``` -$ yarn deploy-oft-adapter-sepolia +```bash +yarn deploy-oft-adapter-sepolia ``` -Log output : +Expected log output : -``` -$ npx hardhat run scripts/deploy_oft_adapter.ts --network sepolia +```bash +npx hardhat run scripts/deploy_oft_adapter.ts --network sepolia Deployed MyOFTAdapter contract address: 0x4daa81978576cB91a2e1919960e90e46c2a6D586 Done in 6.67s. ``` -### Deploy OFT on destination chain (e.g. BNB testnet) +### Deploy OFT on the Destination Chain -``` -$ yarn deploy-oft-bnb-testnet +You can use the following command to deploy OFT on destination chain (e.g. BNB Testnet): + +```bash +yarn deploy-oft-bnb-testnet ``` -Log output : +Expected log output : -``` -$ npx hardhat run scripts/deploy_oft.ts --network bnbTestnet +```bash +npx hardhat run scripts/deploy_oft.ts --network bnbTestnet Deployed MyOFT contract address: 0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 Done in 6.68s. ``` -## Set trusted peer (Optinal) +### (optional) Set the Trusted Peers -### On OFTAdapter (source chain, e.g. Sepolia) +### On OFTAdapter -``` -$ yarn set-peer-oft-adapter-sepolia +You can set the trusted peer in the source chain's OFT Adapter (e.g., Sepolia) using the following command: + +```bash +yarn set-peer-oft-adapter-sepolia ``` -Log output : +Expected log output : -``` -$ npx hardhat run scripts/set_peer_oft_adapter.ts --network sepolia +```bash +npx hardhat run scripts/set_peer_oft_adapter.ts --network sepolia setPeerMyOFTAdapter - oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586, lzEndpointIdOnDestChain:40102, oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 MyOFTAdapter - setPeer tx: 0xc17e7a54d96325768b6427ce893d9b6b7ed04bd920089b63a3f96c005073e9c2 Done in 14.10s. ``` -### On OFT (destination chain, e.g. BNB testnet) +#### On OFT -``` -$ yarn set-peer-oft-bnb-testnet +You can add a trusted peer in the destination chain (e.g. BNB Testnet) using the following command: + +```bash +yarn set-peer-oft-bnb-testnet ``` -Log output : +Expected log output : -``` -$ npx hardhat run scripts/set_peer_oft.ts --network bnbTestnet +```bash +npx hardhat run scripts/set_peer_oft.ts --network bnbTestnet setPeerMyOFT - oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1, lzEndpointIdOnSrcChain:40161, oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586 MyOFT - setPeer tx: 0xb0012378ee14c9df5c9f86980dd9c96fc8aedb3c19d92c1d91a4259f3981ac35 Done in 4.66s. ``` -## Send origin tokens from source chain to destination chain +### Send the Origin Tokens from the Source Chain to the Destination Chain -``` -$ yarn send-oft-from-sepolia -``` -Log output : +You can use the following command to send tokens from the source chain to the destination chain: +```bash +yarn send-oft-from-sepolia ``` -$ npx hardhat run scripts/send_oft.ts --network sepolia + +Expected log output : + +```bash +npx hardhat run scripts/send_oft.ts --network sepolia sendOFT - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57a4bd139fb673d364a6f12df9177a3f686625f3, amount:2 sendOFT - approve tx: 0x8fa692edb47b1ad9d21f60b0fa30993e5cd3abd78c3c56fb4f38db5f9b8ac369 sendOFT - estimated nativeFee: 0.000734209489447653 @@ -156,16 +175,19 @@ sendOFT - received tx on destination chain: 0xc2e5a4be8ae67718e817ff585a32765e39 ``` -## Send OFT-wrapped tokens back from destination chain to origin chain +### Send Oft-Wrapped Tokens Back From the Destination Chain to the Origin Chain -``` -$ yarn send-oft-back-from-bnb-testnet -``` +You can use the following command to send the OFT-wrapped tokens back to the origin chain: -Log output : +```bash +yarn send-oft-back-from-bnb-testnet ``` -$ npx hardhat run scripts/send_oft_back.ts --network bnbTestnet + +Expected log output : + +```bash +npx hardhat run scripts/send_oft_back.ts --network bnbTestnet sendOFTBack - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, amount:2 sendOFTBack - estimated nativeFee: 0.054815809525020364 sendOFTBack - send tx on source chain: 0x41bcf78b310dc1bbf9b4005f7412d995011c7815ad5af9cc26b37370e75bbfeb From 95d9003134afc5b4da42b53063a3809f0dbaceeb Mon Sep 17 00:00:00 2001 From: Vivek Jain Date: Mon, 3 Jun 2024 17:39:16 +0530 Subject: [PATCH 4/7] Add code samples in the article --- .../docs/how-tos/send-ERC20-across-chains.md | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md index 1c5ec2b54c5..4fac9595a3e 100644 --- a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md +++ b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md @@ -37,17 +37,90 @@ You can learn more about the available options in the [Layer Zero Documentation] To send existing ERC20 tokens, you will need both the OFT Adapter contract on the source chain and the OFT contract on the destination chain. You should then use the following procedure: 1. **Approve the tokens**: The sender must approve their ERC20 tokens for the OFT Adapter contract. +```typescript +const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, amountInWei); +``` 2. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. +```typescript + const sendParam = [ + lzEndpointIdOnDestChain, + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTAdapterContract.quoteSend(sendParam as any, false); +``` + 3. **Send the tokens**: The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. +```typescript + const sendTx = await myOFTAdapterContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFT - send tx on source chain:", sendTxReceipt?.hash); +``` 4. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). - +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFT - received tx on destination chain:", deliveredMsg?.dstTxHash); +``` To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: 1. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. -2. **Send Tokens**: The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. +```typescript + // Set the send param + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L10 + const sendParam = [ + lzEndpointIdOnSrcChain, // Sepolia + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // Step 1: call the func quoteSend() to estimate cross-chain fee to be paid in native on the source chain + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTContract.quoteSend(sendParam as any, false); + console.log("sendOFTBack - estimated nativeFee:", ethers.formatEther(nativeFee)); + ``` +2. **Send the Tokens**: The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. +```typescript +const sendTx = await myOFTContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFTBack - send tx on source chain:", sendTxReceipt?.hash); + ``` 3. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. - - +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFTBack - received tx on destination chain:", deliveredMsg?.dstTxHash); + ``` #### Sample Solidity code for OFT Adapter and OFT contracts in the folder `contracts-standard` The [contracts-standard](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) contains scripts to: From 59c6afa3490ca64cee08238a4a05b649ccf46bd5 Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Mon, 3 Jun 2024 12:23:31 -0300 Subject: [PATCH 5/7] fixed headers (#1591) added links to headers --- .../docs/how-tos/send-ERC20-across-chains.md | 82 +++++++++++++------ 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md index 4fac9595a3e..af8cc67fa54 100644 --- a/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md +++ b/docs/build/isc/v1.1/docs/how-tos/send-ERC20-across-chains.md @@ -2,45 +2,52 @@ ## Introduction -[LayerZero OFT V2](https://docs.layerzero.network/v2) enables cross-chain transfers of existing ERC20 tokens, such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively). For testing purposes, Sepolia is chosen as the source chain, while the BNB testnet is chosen as the destination chain. +[LayerZero OFT V2](https://docs.layerzero.network/v2) enables cross-chain transfers of existing ERC20 tokens, such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively). For testing purposes, Sepolia is chosen as the source chain, while the BNB Testnet is chosen as the destination chain. :::info Community Libs + You can clone the Utilities for LayerZero OFT V2 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-oft-v2-utils). + ::: ### Why Would a User Need to Send ERC20 Tokens Across Chains? -Sending ERC20 tokens across chains allows users to leverage the strengths and unique features of different blockchain networks, optimize costs, and manage risks more effectively. This flexibility is crucial as the blockchain ecosystem continues to grow and diversify. - -[**Use-case 1**](https://docs.layerzero.network/v2/developers/evm/oft/adapter) +Sending ERC20 tokens across chains allows users to leverage different blockchain networks' strengths and unique features, optimize costs, and manage risks more effectively. This flexibility is crucial as the blockchain ecosystem continues to grow and diversify. #### Send Existing ERC20 Tokens Across Chains -You need both the OFT Adapter and OFT contracts to enable existing ERC20 tokens for cross-chain sending, - -[**Use-case 2**](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) +You need both the [OFT Adapter](https://docs.layerzero.network/v2/developers/evm/oft/adapter) and OFT contracts to enable existing ERC20 tokens for cross-chain sending, #### Create New Cross-chain Fungible Tokens If you are about to launch a new ERC20 token, you can use the [OFT standard](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) to enable cross-chain sending without the OFT Adapter. -### How To Use IOTA's Utilities for LayerZero OFT V2 +## How To Use IOTA's Utilities for LayerZero OFT V2 The [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM Testnet) and a destination chain (e.g., BNB Testnet or IOTA EVM Testnet). :::tip Further Information + You can learn more about the available options in the [Layer Zero Documentation](https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types.). + ::: -### Send Tokens from One Source Chain to Another Destination Chain (and Vice Versa) +### Send Tokens From One Source Chain to Another Destination Chain (and Vice Versa) To send existing ERC20 tokens, you will need both the OFT Adapter contract on the source chain and the OFT contract on the destination chain. You should then use the following procedure: -1. **Approve the tokens**: The sender must approve their ERC20 tokens for the OFT Adapter contract. +#### 1. Approve the tokens + +The sender must approve their ERC20 tokens for the OFT Adapter contract. + ```typescript const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, amountInWei); ``` -2. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. + +#### 2. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. + ```typescript const sendParam = [ lzEndpointIdOnDestChain, @@ -57,7 +64,10 @@ const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, am const [nativeFee] = await myOFTAdapterContract.quoteSend(sendParam as any, false); ``` -3. **Send the tokens**: The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. +#### 3. Send the tokens + +The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. + ```typescript const sendTx = await myOFTAdapterContract.send( sendParam as any, @@ -70,7 +80,10 @@ const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, am const sendTxReceipt = await sendTx.wait(); console.log("sendOFT - send tx on source chain:", sendTxReceipt?.hash); ``` -4. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). + +#### 4. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). ```typescript const deliveredMsg = await waitForMessageReceived( Number(lzEndpointIdOnDestChain), @@ -78,9 +91,15 @@ const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, am ); console.log("sendOFT - received tx on destination chain:", deliveredMsg?.dstTxHash); ``` + +### Send the OFT-wrapped Tokens Back + To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: -1. **Estimate the fee**: The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. +#### 1. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. + ```typescript // Set the send param // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L10 @@ -100,7 +119,11 @@ To send back the OFT-wrapped tokens on the destination chain to the source chain const [nativeFee] = await myOFTContract.quoteSend(sendParam as any, false); console.log("sendOFTBack - estimated nativeFee:", ethers.formatEther(nativeFee)); ``` -2. **Send the Tokens**: The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. + +#### 2. Send the tokens + +The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. + ```typescript const sendTx = await myOFTContract.send( sendParam as any, @@ -113,7 +136,10 @@ const sendTx = await myOFTContract.send( const sendTxReceipt = await sendTx.wait(); console.log("sendOFTBack - send tx on source chain:", sendTxReceipt?.hash); ``` -3. **(Optional) Wait for Finalization**: The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. + +#### 3. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. ```typescript const deliveredMsg = await waitForMessageReceived( Number(lzEndpointIdOnDestChain), @@ -122,12 +148,15 @@ const sendTx = await myOFTContract.send( console.log("sendOFTBack - received tx on destination chain:", deliveredMsg?.dstTxHash); ``` -#### Sample Solidity code for OFT Adapter and OFT contracts in the folder `contracts-standard` +## Sample Solidity Code for OFT Adapter and OFT Contracts in the `contracts-standard` Folder + The [contracts-standard](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) contains scripts to: -- Deploy the OFT Adapter and OFT contracts. -- Set your trusted peers. + +- [Deploy the OFT Adapter and OFT contracts](#deploy-the-oft-adapter-contract-on-the-source-chain). +- [Set your trusted peers](#optional-set-the-trusted-peers). - Set enforced options. -- Send tokens from the source chain to the destination chain, and vice versa. +- [Send tokens from the source chain to the destination chain](#send-the-origin-tokens-from-the-source-chain-to-the-destination-chain), +and [vice versa](#send-oft-wrapped-tokens-back-from-the-destination-chain-to-the-origin-chain). ### Install the Library @@ -137,7 +166,7 @@ After you have cloned the [IOTA Community Utilities for LayerZero OFT V2 reposit yarn ``` -## Compile the Contracts +### Compile the Contracts If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: @@ -155,7 +184,7 @@ cp .env.example .env ### Deploy the Contracts -## Deploy the OFT Adapter Contract On the Source Chain +#### Deploy the OFT Adapter Contract On the Source Chain The OFT Adapter facilitates the expansion of an existing token to any supported blockchain as a native token, maintaining a unified global supply and inheriting all features of the OFT Standard. This intermediary contract manages the sending and receiving of pre-deployed tokens. @@ -165,7 +194,6 @@ For instance, when an ERC20 token is transferred from the source chain (Chain A) yarn deploy-oft-adapter-sepolia ``` - Expected log output : ```bash @@ -174,7 +202,7 @@ Deployed MyOFTAdapter contract address: 0x4daa81978576cB91a2e1919960e90e46c2a6D5 Done in 6.67s. ``` -### Deploy OFT on the Destination Chain +#### Deploy OFT on the Destination Chain You can use the following command to deploy OFT on destination chain (e.g. BNB Testnet): @@ -192,7 +220,7 @@ Done in 6.68s. ### (optional) Set the Trusted Peers -### On OFTAdapter +#### On OFTAdapter You can set the trusted peer in the source chain's OFT Adapter (e.g., Sepolia) using the following command: @@ -247,7 +275,6 @@ Wait for cross-chain tx finalization by LayerZero ... sendOFT - received tx on destination chain: 0xc2e5a4be8ae67718e817ff585a32765e393835880068f408fd7724667a25a46c ``` - ### Send Oft-Wrapped Tokens Back From the Destination Chain to the Origin Chain You can use the following command to send the OFT-wrapped tokens back to the origin chain: @@ -266,4 +293,5 @@ sendOFTBack - estimated nativeFee: 0.054815809525020364 sendOFTBack - send tx on source chain: 0x41bcf78b310dc1bbf9b4005f7412d995011c7815ad5af9cc26b37370e75bbfeb Wait for cross-chain tx finalization by LayerZero ... sendOFTBack - received tx on destination chain: 0xc1031694e92512a0189885ad6419e33196a65b8ae56baa9d555be8686d6d42fe -``` \ No newline at end of file +``` + From 8fc83a541ee37af6fc1551cbc95ade3947bc3809 Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 20:26:59 +0200 Subject: [PATCH 6/7] Update alpha docs --- .../docs/how-tos/send-ERC20-across-chains.md | 297 ++++++++++++++++++ docs/build/isc/v1.3-alpha/sidebars.js | 5 + 2 files changed, 302 insertions(+) create mode 100644 docs/build/isc/v1.3-alpha/docs/how-tos/send-ERC20-across-chains.md diff --git a/docs/build/isc/v1.3-alpha/docs/how-tos/send-ERC20-across-chains.md b/docs/build/isc/v1.3-alpha/docs/how-tos/send-ERC20-across-chains.md new file mode 100644 index 00000000000..af8cc67fa54 --- /dev/null +++ b/docs/build/isc/v1.3-alpha/docs/how-tos/send-ERC20-across-chains.md @@ -0,0 +1,297 @@ +# Send ERC20 Tokens Across Chains + +## Introduction + +[LayerZero OFT V2](https://docs.layerzero.network/v2) enables cross-chain transfers of existing ERC20 tokens, such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively). For testing purposes, Sepolia is chosen as the source chain, while the BNB Testnet is chosen as the destination chain. + +:::info Community Libs + +You can clone the Utilities for LayerZero OFT V2 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-oft-v2-utils). + +::: + +### Why Would a User Need to Send ERC20 Tokens Across Chains? + +Sending ERC20 tokens across chains allows users to leverage different blockchain networks' strengths and unique features, optimize costs, and manage risks more effectively. This flexibility is crucial as the blockchain ecosystem continues to grow and diversify. + +#### Send Existing ERC20 Tokens Across Chains + +You need both the [OFT Adapter](https://docs.layerzero.network/v2/developers/evm/oft/adapter) and OFT contracts to enable existing ERC20 tokens for cross-chain sending, + +#### Create New Cross-chain Fungible Tokens + +If you are about to launch a new ERC20 token, you can use the [OFT standard](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) to enable cross-chain sending without the OFT Adapter. + +## How To Use IOTA's Utilities for LayerZero OFT V2 + +The [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM Testnet) and a destination chain (e.g., BNB Testnet or IOTA EVM Testnet). + +:::tip Further Information + +You can learn more about the available options in the [Layer Zero Documentation](https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types.). + +::: + +### Send Tokens From One Source Chain to Another Destination Chain (and Vice Versa) + +To send existing ERC20 tokens, you will need both the OFT Adapter contract on the source chain and the OFT contract on the destination chain. You should then use the following procedure: + +#### 1. Approve the tokens + +The sender must approve their ERC20 tokens for the OFT Adapter contract. + +```typescript +const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, amountInWei); +``` + +#### 2. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. + +```typescript + const sendParam = [ + lzEndpointIdOnDestChain, + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTAdapterContract.quoteSend(sendParam as any, false); +``` + +#### 3. Send the tokens + +The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. + +```typescript + const sendTx = await myOFTAdapterContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFT - send tx on source chain:", sendTxReceipt?.hash); +``` + +#### 4. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFT - received tx on destination chain:", deliveredMsg?.dstTxHash); +``` + +### Send the OFT-wrapped Tokens Back + +To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: + +#### 1. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. + +```typescript + // Set the send param + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L10 + const sendParam = [ + lzEndpointIdOnSrcChain, // Sepolia + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // Step 1: call the func quoteSend() to estimate cross-chain fee to be paid in native on the source chain + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTContract.quoteSend(sendParam as any, false); + console.log("sendOFTBack - estimated nativeFee:", ethers.formatEther(nativeFee)); + ``` + +#### 2. Send the tokens + +The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. + +```typescript +const sendTx = await myOFTContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFTBack - send tx on source chain:", sendTxReceipt?.hash); + ``` + +#### 3. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFTBack - received tx on destination chain:", deliveredMsg?.dstTxHash); + ``` + +## Sample Solidity Code for OFT Adapter and OFT Contracts in the `contracts-standard` Folder + +The [contracts-standard](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) contains scripts to: + +- [Deploy the OFT Adapter and OFT contracts](#deploy-the-oft-adapter-contract-on-the-source-chain). +- [Set your trusted peers](#optional-set-the-trusted-peers). +- Set enforced options. +- [Send tokens from the source chain to the destination chain](#send-the-origin-tokens-from-the-source-chain-to-the-destination-chain), +and [vice versa](#send-oft-wrapped-tokens-back-from-the-destination-chain-to-the-origin-chain). + +### Install the Library + +After you have cloned the [IOTA Community Utilities for LayerZero OFT V2 repository](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main), you should run the following command to install: + +``` +yarn +``` + +### Compile the Contracts + +If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: + +```bash +yarn compile +``` + +### Set Your Configuration + +You should copy the template [`.env.example`](https://github.com/iota-community/layerzero-oft-v2-utils/blob/main/.env.example) file to a file called `.env`, and edit any of the configuration options you see fit. + +```bash +cp .env.example .env +``` + +### Deploy the Contracts + +#### Deploy the OFT Adapter Contract On the Source Chain + +The OFT Adapter facilitates the expansion of an existing token to any supported blockchain as a native token, maintaining a unified global supply and inheriting all features of the OFT Standard. This intermediary contract manages the sending and receiving of pre-deployed tokens. + +For instance, when an ERC20 token is transferred from the source chain (Chain A), it gets locked in the OFT Adapter. Consequently, a corresponding token is minted on the destination chain (Chain B) through the paired OFT Contract. + +```bash +yarn deploy-oft-adapter-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_oft_adapter.ts --network sepolia +Deployed MyOFTAdapter contract address: 0x4daa81978576cB91a2e1919960e90e46c2a6D586 +Done in 6.67s. +``` + +#### Deploy OFT on the Destination Chain + +You can use the following command to deploy OFT on destination chain (e.g. BNB Testnet): + +```bash +yarn deploy-oft-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_oft.ts --network bnbTestnet +Deployed MyOFT contract address: 0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +Done in 6.68s. +``` + +### (optional) Set the Trusted Peers + +#### On OFTAdapter + +You can set the trusted peer in the source chain's OFT Adapter (e.g., Sepolia) using the following command: + +```bash +yarn set-peer-oft-adapter-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/set_peer_oft_adapter.ts --network sepolia +setPeerMyOFTAdapter - oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586, lzEndpointIdOnDestChain:40102, oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +MyOFTAdapter - setPeer tx: 0xc17e7a54d96325768b6427ce893d9b6b7ed04bd920089b63a3f96c005073e9c2 +Done in 14.10s. +``` + +#### On OFT + +You can add a trusted peer in the destination chain (e.g. BNB Testnet) using the following command: + +```bash +yarn set-peer-oft-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/set_peer_oft.ts --network bnbTestnet +setPeerMyOFT - oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1, lzEndpointIdOnSrcChain:40161, oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586 +MyOFT - setPeer tx: 0xb0012378ee14c9df5c9f86980dd9c96fc8aedb3c19d92c1d91a4259f3981ac35 +Done in 4.66s. +``` + +### Send the Origin Tokens from the Source Chain to the Destination Chain + + +You can use the following command to send tokens from the source chain to the destination chain: + +```bash +yarn send-oft-from-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/send_oft.ts --network sepolia +sendOFT - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57a4bd139fb673d364a6f12df9177a3f686625f3, amount:2 +sendOFT - approve tx: 0x8fa692edb47b1ad9d21f60b0fa30993e5cd3abd78c3c56fb4f38db5f9b8ac369 +sendOFT - estimated nativeFee: 0.000734209489447653 +sendOFT - send tx on source chain: 0xeb3e44310a09ae2ab2f0d6d6d3fdfd7c490f8ac536bb20a5e16999b23232ef67 +Wait for cross-chain tx finalization by LayerZero ... +sendOFT - received tx on destination chain: 0xc2e5a4be8ae67718e817ff585a32765e393835880068f408fd7724667a25a46c +``` + +### Send Oft-Wrapped Tokens Back From the Destination Chain to the Origin Chain + +You can use the following command to send the OFT-wrapped tokens back to the origin chain: + + +```bash +yarn send-oft-back-from-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/send_oft_back.ts --network bnbTestnet +sendOFTBack - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, amount:2 +sendOFTBack - estimated nativeFee: 0.054815809525020364 +sendOFTBack - send tx on source chain: 0x41bcf78b310dc1bbf9b4005f7412d995011c7815ad5af9cc26b37370e75bbfeb +Wait for cross-chain tx finalization by LayerZero ... +sendOFTBack - received tx on destination chain: 0xc1031694e92512a0189885ad6419e33196a65b8ae56baa9d555be8686d6d42fe +``` + diff --git a/docs/build/isc/v1.3-alpha/sidebars.js b/docs/build/isc/v1.3-alpha/sidebars.js index a01017561cc..43060c5651f 100644 --- a/docs/build/isc/v1.3-alpha/sidebars.js +++ b/docs/build/isc/v1.3-alpha/sidebars.js @@ -209,6 +209,11 @@ module.exports = { }, ], }, + { + type: 'doc', + label: 'Send ERC20 Tokens Across Chains', + id: 'how-tos/send-ERC20-across-chains', + }, ], }, { From 1b4fdf605f533222681309e780025470eba3c99a Mon Sep 17 00:00:00 2001 From: Dr-Electron Date: Mon, 3 Jun 2024 20:51:05 +0200 Subject: [PATCH 7/7] Update sidebars --- docs/build/isc/v1.1/sidebars.js | 10 +++++----- docs/build/isc/v1.3-alpha/sidebars.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/build/isc/v1.1/sidebars.js b/docs/build/isc/v1.1/sidebars.js index 43060c5651f..39cd7acbe06 100644 --- a/docs/build/isc/v1.1/sidebars.js +++ b/docs/build/isc/v1.1/sidebars.js @@ -84,6 +84,11 @@ module.exports = { label: 'Create Custom Tokens - ERC20', id: 'how-tos/ERC20', }, + { + type: 'doc', + label: 'Send ERC20 Tokens Across Chains', + id: 'how-tos/send-ERC20-across-chains', + }, { type: 'doc', label: 'Create NFTs - ERC721', @@ -209,11 +214,6 @@ module.exports = { }, ], }, - { - type: 'doc', - label: 'Send ERC20 Tokens Across Chains', - id: 'how-tos/send-ERC20-across-chains', - }, ], }, { diff --git a/docs/build/isc/v1.3-alpha/sidebars.js b/docs/build/isc/v1.3-alpha/sidebars.js index 43060c5651f..39cd7acbe06 100644 --- a/docs/build/isc/v1.3-alpha/sidebars.js +++ b/docs/build/isc/v1.3-alpha/sidebars.js @@ -84,6 +84,11 @@ module.exports = { label: 'Create Custom Tokens - ERC20', id: 'how-tos/ERC20', }, + { + type: 'doc', + label: 'Send ERC20 Tokens Across Chains', + id: 'how-tos/send-ERC20-across-chains', + }, { type: 'doc', label: 'Create NFTs - ERC721', @@ -209,11 +214,6 @@ module.exports = { }, ], }, - { - type: 'doc', - label: 'Send ERC20 Tokens Across Chains', - id: 'how-tos/send-ERC20-across-chains', - }, ], }, {