From 0405189fcd9e9884c70ea82b569784161256d532 Mon Sep 17 00:00:00 2001 From: Stanley Date: Tue, 8 Oct 2024 12:56:04 -0400 Subject: [PATCH 1/2] forge install: axelar-gmp-sdk-solidity v5.10.0 --- .gitmodules | 3 +++ lib/axelar-gmp-sdk-solidity | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/axelar-gmp-sdk-solidity diff --git a/.gitmodules b/.gitmodules index 86d572d1..059299e4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "lib/PermitC"] path = lib/PermitC url = https://github.com/limitbreakinc/PermitC +[submodule "lib/axelar-gmp-sdk-solidity"] + path = lib/axelar-gmp-sdk-solidity + url = https://github.com/axelarnetwork/axelar-gmp-sdk-solidity diff --git a/lib/axelar-gmp-sdk-solidity b/lib/axelar-gmp-sdk-solidity new file mode 160000 index 00000000..3157ba4f --- /dev/null +++ b/lib/axelar-gmp-sdk-solidity @@ -0,0 +1 @@ +Subproject commit 3157ba4f704de408e356ad8236b5d81bbc82d7cb From 9c85757e444ff91e3c5a19799ede921d36062f62 Mon Sep 17 00:00:00 2001 From: Stanley Date: Tue, 8 Oct 2024 13:39:20 -0400 Subject: [PATCH 2/2] PoC setup of CrossChain Axelar Module --- remappings.txt | 1 + src/module/token/crosschain/Axelar.sol | 98 ++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/module/token/crosschain/Axelar.sol diff --git a/remappings.txt b/remappings.txt index 413cecc2..c3f9c4b3 100644 --- a/remappings.txt +++ b/remappings.txt @@ -5,3 +5,4 @@ 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/ +@axelar-network/sdk-solidity/=lib/axelar-gmp-sdk-solidity/contracts/ diff --git a/src/module/token/crosschain/Axelar.sol b/src/module/token/crosschain/Axelar.sol new file mode 100644 index 00000000..5d21195a --- /dev/null +++ b/src/module/token/crosschain/Axelar.sol @@ -0,0 +1,98 @@ +// 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 {AxelarExecutable} from "@axelar-network/sdk-solidity/executable/AxelarExecutable.sol"; +import {IAxelarGateway} from "@axelar-network/sdk-solidity/interfaces/IAxelarGateway.sol"; +import {OwnableRoles} from "@solady/auth/OwnableRoles.sol"; + +contract AxelarCrossChain is Module, AxelarExecutable, CrossChain { + + constructor(address _axelarGateway) AxelarExecutable(_axelarGateway) {} + + /// @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(gateway); + } + + function setRouter(address _router) external override {} + + function sendCrossChainTransaction( + uint64 _destinationChain, + address _callAddress, + bytes calldata _payload, + bytes calldata _extraArgs + ) external payable override { + (string memory destinationChain, string memory contractAddress, bytes memory tokenData) = + abi.decode(_extraArgs, (string, string, bytes)); + + if (tokenData.length > 0) { + (string memory symbol, uint256 amount) = abi.decode(tokenData, (string, uint256)); + gateway.callContractWithToken(destinationChain, contractAddress, _payload, symbol, amount); + } else { + gateway.callContract(destinationChain, contractAddress, _payload); + } + + onCrossChainTransactionSent(_destinationChain, _callAddress, _payload, _extraArgs); + } + + function _execute(string calldata sourceChain, string calldata sourceAddress, bytes calldata payload) + internal + override + { + onCrossChainTransactionReceived(0, address(0), payload, ""); + } + + function _executeWithToken( + string calldata sourceChain, + string calldata sourceAddress, + bytes calldata payload, + string calldata tokenSymbol, + uint256 amount + ) internal override { + bytes memory extraArgs = abi.encode(tokenSymbol, amount); + onCrossChainTransactionReceived(0, address(0), 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 + } + +}