From 7d710eb26b131a1a554a182700c9eb108e29768a Mon Sep 17 00:00:00 2001 From: Stanley Date: Tue, 8 Oct 2024 14:09:06 -0400 Subject: [PATCH 1/3] forge install: devtools --- .gitmodules | 3 +++ lib/devtools | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/devtools diff --git a/.gitmodules b/.gitmodules index 86d572d1..cb2027d0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "lib/PermitC"] path = lib/PermitC url = https://github.com/limitbreakinc/PermitC +[submodule "lib/devtools"] + path = lib/devtools + url = https://github.com/LayerZero-Labs/devtools diff --git a/lib/devtools b/lib/devtools new file mode 160000 index 00000000..811a692b --- /dev/null +++ b/lib/devtools @@ -0,0 +1 @@ +Subproject commit 811a692b34348845de0ec55d5c79d8a244346795 From 18b3b9b7aa69827d82691af8f108de0a885a0f53 Mon Sep 17 00:00:00 2001 From: Stanley Date: Tue, 8 Oct 2024 14:09:29 -0400 Subject: [PATCH 2/3] forge install: layerzero-v2 --- .gitmodules | 3 +++ lib/layerzero-v2 | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/layerzero-v2 diff --git a/.gitmodules b/.gitmodules index cb2027d0..8f5bc21f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "lib/devtools"] path = lib/devtools url = https://github.com/LayerZero-Labs/devtools +[submodule "lib/layerzero-v2"] + path = lib/layerzero-v2 + url = https://github.com/LayerZero-Labs/layerzero-v2 diff --git a/lib/layerzero-v2 b/lib/layerzero-v2 new file mode 160000 index 00000000..7aebbd7c --- /dev/null +++ b/lib/layerzero-v2 @@ -0,0 +1 @@ +Subproject commit 7aebbd7c79b2dc818f7bb054aed2405ca076b9d6 From 5fd34d2ffb1393766136f8a27f0b09915988b3b7 Mon Sep 17 00:00:00 2001 From: Stanley Date: Tue, 8 Oct 2024 14:39:31 -0400 Subject: [PATCH 3/3] PoC setup of CrossChain LayerZero Module --- remappings.txt | 2 + src/module/token/crosschain/LayerZero.sol | 94 +++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/module/token/crosschain/LayerZero.sol diff --git a/remappings.txt b/remappings.txt index 413cecc2..7a7073ab 100644 --- a/remappings.txt +++ b/remappings.txt @@ -5,3 +5,5 @@ forge-std/=lib/forge-std/src/ @erc721a-upgradeable/=lib/ERC721A-Upgradeable/contracts/ @limitbreak/creator-token-standards/=lib/creator-token-standards/src/ @limitbreak/permit-c/=lib/PermitC/src/ +@layerzerolabs/oapp-evm/=lib/devtools/packages/oapp-evm/ +@layerzerolabs/lz-evm-protocol-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/protocol diff --git a/src/module/token/crosschain/LayerZero.sol b/src/module/token/crosschain/LayerZero.sol new file mode 100644 index 00000000..9911ff30 --- /dev/null +++ b/src/module/token/crosschain/LayerZero.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +import {Module} from "../../../Module.sol"; + +import {Role} from "../../../Role.sol"; +import {IInstallationCallback} from "../../../interface/IInstallationCallback.sol"; + +import {CrossChain} from "./CrossChain.sol"; + +import {MessagingFee, OApp, Origin} from "@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol"; +import {OwnableRoles} from "@solady/auth/OwnableRoles.sol"; + +contract LayerZeroCrossChain is Module, OApp, CrossChain { + + constructor(address _endpoint, address _owner) OApp(_endpoint, _owner) {} + + /// @notice Returns all implemented callback and fallback functions. + function getModuleConfig() external pure override returns (ModuleConfig memory config) { + config.fallbackFunctions = new FallbackFunction[](3); + + config.fallbackFunctions[0] = FallbackFunction({selector: this.getRouter.selector, permissionBits: 0}); + config.fallbackFunctions[1] = + FallbackFunction({selector: this.setRouter.selector, permissionBits: Role._MANAGER_ROLE}); + config.fallbackFunctions[2] = + FallbackFunction({selector: this.sendCrossChainTransaction.selector, permissionBits: 0}); + } + + /*////////////////////////////////////////////////////////////// + FALLBACK FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function getRouter() external view override returns (address) { + return address(endpoint); + } + + function setRouter(address _router) external override {} + + function sendCrossChainTransaction( + uint64 _destinationChain, + address _callAddress, + bytes calldata _payload, + bytes calldata _extraArgs + ) external payable override { + (bytes memory options, uint256 zroTokenAmount) = abi.decode(_extraArgs, (bytes, uint256)); + + _lzSend( + uint32(_destinationChain), + _payload, + options, + // Fee in native gas and ZRO token. + MessagingFee(msg.value, zroTokenAmount), + // Refund address in case of failed source message. + payable(msg.sender) + ); + + onCrossChainTransactionSent(_destinationChain, _callAddress, _payload, _extraArgs); + } + + function _lzReceive( + Origin calldata _origin, + bytes32 _guid, + bytes calldata payload, + address _sourceAddress, // Executor address as specified by the OApp. + bytes calldata _extraArgs // Any extra data or options to trigger on receipt. + ) internal override { + bytes memory extraArgs = abi.encode(_origin, _guid, _extraArgs); + + onCrossChainTransactionReceived(_origin.srcEid, _sourceAddress, payload, extraArgs); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function onCrossChainTransactionSent( + uint64 _destinationChain, + address _callAddress, + bytes calldata _payload, + bytes calldata _extraArgs + ) internal override { + /// post cross chain transaction sent logic goes here + } + + function onCrossChainTransactionReceived( + uint64 _sourceChain, + address _sourceAddress, + bytes memory _payload, + bytes memory _extraArgs + ) internal override { + /// post cross chain transaction received logic goes here + } + +}