// Source: contracts/executable/AxelarExecutable.sol pragma solidity ^0.8.0; // SPDX-License-Identifier: MIT // File contracts/interfaces/IAxelarGateway.sol /** * @title IAxelarGateway * @dev Interface for the Axelar Gateway that supports general message passing and contract call execution. */ interface IAxelarGateway { /** * @notice Emitted when a contract call is made through the gateway. * @dev Logs the attempt to call a contract on another chain. * @param sender The address of the sender who initiated the contract call. * @param destinationChain The name of the destination chain. * @param destinationContractAddress The address of the contract on the destination chain. * @param payloadHash The keccak256 hash of the sent payload data. * @param payload The payload data used for the contract call. */ event ContractCall( address indexed sender, string destinationChain, string destinationContractAddress, bytes32 indexed payloadHash, bytes payload ); /** * @notice Sends a contract call to another chain. * @dev Initiates a cross-chain contract call through the gateway to the specified destination chain and contract. * @param destinationChain The name of the destination chain. * @param contractAddress The address of the contract on the destination chain. * @param payload The payload data to be used in the contract call. */ function callContract( string calldata destinationChain, string calldata contractAddress, bytes calldata payload ) external; /** * @notice Checks if a contract call is approved. * @dev Determines whether a given contract call, identified by the commandId and payloadHash, is approved. * @param commandId The identifier of the command to check. * @param sourceChain The name of the source chain. * @param sourceAddress The address of the sender on the source chain. * @param contractAddress The address of the contract where the call will be executed. * @param payloadHash The keccak256 hash of the payload data. * @return True if the contract call is approved, false otherwise. */ function isContractCallApproved( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, address contractAddress, bytes32 payloadHash ) external view returns (bool); /** * @notice Validates and approves a contract call. * @dev Validates the given contract call information and marks it as approved if valid. * @param commandId The identifier of the command to validate. * @param sourceChain The name of the source chain. * @param sourceAddress The address of the sender on the source chain. * @param payloadHash The keccak256 hash of the payload data. * @return True if the contract call is validated and approved, false otherwise. */ function validateContractCall( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes32 payloadHash ) external returns (bool); /** * @notice Checks if a command has been executed. * @dev Determines whether a command, identified by the commandId, has been executed. * @param commandId The identifier of the command to check. * @return True if the command has been executed, false otherwise. */ function isCommandExecuted(bytes32 commandId) external view returns (bool); } // File contracts/interfaces/IAxelarExecutable.sol /** * @title IAxelarExecutable * @dev Interface for a contract that is executable by Axelar Gateway's cross-chain message passing. * It defines a standard interface to execute commands sent from another chain. */ interface IAxelarExecutable { /** * @dev Thrown when a function is called with an invalid address. */ error InvalidAddress(); /** * @dev Thrown when the call is not approved by the Axelar Gateway. */ error NotApprovedByGateway(); /** * @notice Returns the address of the AxelarGateway contract. * @return The Axelar Gateway contract associated with this executable contract. */ function gateway() external view returns (IAxelarGateway); /** * @notice Executes the specified command sent from another chain. * @dev This function is called by the Axelar Gateway to carry out cross-chain commands. * Reverts if the call is not approved by the gateway or other checks fail. * @param commandId The identifier of the command to execute. * @param sourceChain The name of the source chain from where the command originated. * @param sourceAddress The address on the source chain that sent the command. * @param payload The payload of the command to be executed. This typically includes the function selector and encoded arguments. */ function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external; } // File contracts/executable/AxelarExecutable.sol /** * @title AxelarExecutable * @dev Abstract contract to be inherited by contracts that need to execute cross-chain commands via Axelar's Gateway. * It implements the IAxelarExecutable interface. */ abstract contract AxelarExecutable is IAxelarExecutable { /// @dev Reference to the Axelar Gateway contract. address internal immutable gatewayAddress; /** * @dev Contract constructor that sets the Axelar Gateway address. * Reverts if the provided address is the zero address. * @param gateway_ The address of the Axelar Gateway contract. */ constructor(address gateway_) { if (gateway_ == address(0)) revert InvalidAddress(); gatewayAddress = gateway_; } /** * @notice Executes the cross-chain command after validating it with the Axelar Gateway. * @dev This function ensures the call is approved by Axelar Gateway before execution. * It uses a hash of the payload for validation and internally calls _execute for the actual command execution. * Reverts if the validation fails. * @param commandId The unique identifier of the cross-chain message being executed. * @param sourceChain The name of the source chain from which the message originated. * @param sourceAddress The address on the source chain that sent the message. * @param payload The payload of the message payload. */ function execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) external virtual { bytes32 payloadHash = keccak256(payload); if (!gateway().validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway(); _execute(commandId, sourceChain, sourceAddress, payload); } /** * @dev Internal virtual function to be overridden by child contracts to execute the command. * It allows child contracts to define their custom command execution logic. * @param commandId The identifier of the command to execute. * @param sourceChain The name of the source chain from which the command originated. * @param sourceAddress The address on the source chain that sent the command. * @param payload The payload of the command to be executed. */ function _execute( bytes32 commandId, string calldata sourceChain, string calldata sourceAddress, bytes calldata payload ) internal virtual; /** * @notice Returns the address of the AxelarGateway contract. * @return The Axelar Gateway instance. */ function gateway() public view returns (IAxelarGateway) { return IAxelarGateway(gatewayAddress); } }