creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\nimport { CreateDeploy } from './CreateDeploy.sol';\n\npragma solidity ^0.8.0;\n\n/**\n * @title Create3Address contract\n * @notice This contract can be used to predict the deterministic deployment address of a contract deployed with the `CREATE3` technique.\n */\ncontract Create3Address {\n    /// @dev bytecode hash of the CreateDeploy helper contract\n    bytes32 internal immutable createDeployBytecodeHash;\n\n    constructor() {\n        createDeployBytecodeHash = keccak256(type(CreateDeploy).creationCode);\n    }\n\n    /**\n     * @notice Compute the deployed address that will result from the `CREATE3` method.\n     * @param deploySalt A salt to influence the contract address\n     * @return deployed The deterministic contract address if it was deployed\n     */\n    function _create3Address(bytes32 deploySalt) internal view returns (address deployed) {\n        address deployer = address(\n            uint160(uint256(keccak256(abi.encodePacked(hex'ff', address(this), deploySalt, createDeployBytecodeHash))))\n        );\n\n        deployed = address(uint160(uint256(keccak256(abi.encodePacked(hex'd6_94', deployer, hex'01')))));\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/CreateDeploy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title CreateDeploy Contract\n * @notice This contract deploys new contracts using the `CREATE` opcode and is used as part of\n * the `CREATE3` deployment method.\n */\ncontract CreateDeploy {\n    /**\n     * @dev Deploys a new contract with the specified bytecode using the `CREATE` opcode.\n     * @param bytecode The bytecode of the contract to be deployed\n     */\n    // slither-disable-next-line locked-ether\n    function deploy(bytes memory bytecode) external payable {\n        assembly {\n            if iszero(create(0, add(bytecode, 32), mload(bytecode))) {\n                revert(0, 0)\n            }\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarExpressExecutable } from '../interfaces/IAxelarExpressExecutable.sol';\n\nabstract contract ExpressExecutorTracker is IAxelarExpressExecutable {\n    bytes32 internal constant PREFIX_EXPRESS_EXECUTE = keccak256('express-execute');\n    bytes32 internal constant PREFIX_EXPRESS_EXECUTE_WITH_TOKEN = keccak256('express-execute-with-token');\n\n    function _expressExecuteSlot(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) internal pure returns (bytes32 slot) {\n        slot = keccak256(abi.encode(PREFIX_EXPRESS_EXECUTE, commandId, sourceChain, sourceAddress, payloadHash));\n    }\n\n    function _expressExecuteWithTokenSlot(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) internal pure returns (bytes32 slot) {\n        slot = keccak256(\n            abi.encode(\n                PREFIX_EXPRESS_EXECUTE_WITH_TOKEN,\n                commandId,\n                sourceChain,\n                sourceAddress,\n                payloadHash,\n                symbol,\n                amount\n            )\n        );\n    }\n\n    function getExpressExecutor(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) external view returns (address expressExecutor) {\n        bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash);\n\n        assembly {\n            expressExecutor := sload(slot)\n        }\n    }\n\n    function getExpressExecutorWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) external view returns (address expressExecutor) {\n        bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount);\n\n        assembly {\n            expressExecutor := sload(slot)\n        }\n    }\n\n    function _setExpressExecutor(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        address expressExecutor\n    ) internal {\n        bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash);\n        address currentExecutor;\n\n        assembly {\n            currentExecutor := sload(slot)\n        }\n\n        if (currentExecutor != address(0)) revert ExpressExecutorAlreadySet();\n\n        assembly {\n            sstore(slot, expressExecutor)\n        }\n    }\n\n    function _setExpressExecutorWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount,\n        address expressExecutor\n    ) internal {\n        bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount);\n        address currentExecutor;\n\n        assembly {\n            currentExecutor := sload(slot)\n        }\n\n        if (currentExecutor != address(0)) revert ExpressExecutorAlreadySet();\n\n        assembly {\n            sstore(slot, expressExecutor)\n        }\n    }\n\n    function _popExpressExecutor(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) internal returns (address expressExecutor) {\n        bytes32 slot = _expressExecuteSlot(commandId, sourceChain, sourceAddress, payloadHash);\n\n        assembly {\n            expressExecutor := sload(slot)\n            if expressExecutor {\n                sstore(slot, 0)\n            }\n        }\n    }\n\n    function _popExpressExecutorWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) internal returns (address expressExecutor) {\n        bytes32 slot = _expressExecuteWithTokenSlot(commandId, sourceChain, sourceAddress, payloadHash, symbol, amount);\n\n        assembly {\n            expressExecutor := sload(slot)\n            if expressExecutor {\n                sstore(slot, 0)\n            }\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarExecutable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarGateway } from './IAxelarGateway.sol';\n\ninterface IAxelarExecutable {\n    error InvalidAddress();\n    error NotApprovedByGateway();\n\n    function gateway() external view returns (IAxelarGateway);\n\n    function execute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external;\n\n    function executeWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload,\n        string calldata tokenSymbol,\n        uint256 amount\n    ) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarExpressExecutable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarExecutable } from './IAxelarExecutable.sol';\n\n/**\n * @title IAxelarExpressExecutable\n * @notice Interface for the Axelar Express Executable contract.\n */\ninterface IAxelarExpressExecutable is IAxelarExecutable {\n    // Custom errors\n    error AlreadyExecuted();\n    error InsufficientValue();\n    error ExpressExecutorAlreadySet();\n\n    /**\n     * @notice Emitted when an express execution is successfully performed.\n     * @param commandId The unique identifier for the command.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @param expressExecutor The address of the express executor.\n     */\n    event ExpressExecuted(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        bytes32 payloadHash,\n        address indexed expressExecutor\n    );\n\n    /**\n     * @notice Emitted when an express execution with a token is successfully performed.\n     * @param commandId The unique identifier for the command.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @param symbol The token symbol.\n     * @param amount The amount of tokens.\n     * @param expressExecutor The address of the express executor.\n     */\n    event ExpressExecutedWithToken(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        bytes32 payloadHash,\n        string symbol,\n        uint256 indexed amount,\n        address indexed expressExecutor\n    );\n\n    /**\n     * @notice Emitted when an express execution is fulfilled.\n     * @param commandId The commandId for the contractCall.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @param expressExecutor The address of the express executor.\n     */\n    event ExpressExecutionFulfilled(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        bytes32 payloadHash,\n        address indexed expressExecutor\n    );\n\n    /**\n     * @notice Emitted when an express execution with a token is fulfilled.\n     * @param commandId The commandId for the contractCallWithToken.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @param symbol The token symbol.\n     * @param amount The amount of tokens.\n     * @param expressExecutor The address of the express executor.\n     */\n    event ExpressExecutionWithTokenFulfilled(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        bytes32 payloadHash,\n        string symbol,\n        uint256 indexed amount,\n        address indexed expressExecutor\n    );\n\n    /**\n     * @notice Returns the express executor for a given command.\n     * @param commandId The commandId for the contractCall.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @return expressExecutor The address of the express executor.\n     */\n    function getExpressExecutor(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) external view returns (address expressExecutor);\n\n    /**\n     * @notice Returns the express executor with token for a given command.\n     * @param commandId The commandId for the contractCallWithToken.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payloadHash The hash of the payload.\n     * @param symbol The token symbol.\n     * @param amount The amount of tokens.\n     * @return expressExecutor The address of the express executor.\n     */\n    function getExpressExecutorWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) external view returns (address expressExecutor);\n\n    /**\n     * @notice Express executes a contract call.\n     * @param commandId The commandId for the contractCall.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payload The payload data.\n     */\n    function expressExecute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external payable;\n\n    /**\n     * @notice Express executes a contract call with token.\n     * @param commandId The commandId for the contractCallWithToken.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address.\n     * @param payload The payload data.\n     * @param symbol The token symbol.\n     * @param amount The amount of token.\n     */\n    function expressExecuteWithToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount\n    ) external payable;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IUpgradable } from '../interfaces/IUpgradable.sol';\n\n/**\n * @title IAxelarGasService Interface\n * @notice This is an interface for the AxelarGasService contract which manages gas payments\n * and refunds for cross-chain communication on the Axelar network.\n * @dev This interface inherits IUpgradable\n */\ninterface IAxelarGasService is IUpgradable {\n    error NothingReceived();\n    error InvalidAddress();\n    error NotCollector();\n    error InvalidAmounts();\n\n    event GasPaidForContractCall(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event GasPaidForContractCallWithToken(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        string symbol,\n        uint256 amount,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeGasPaidForContractCall(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeGasPaidForContractCallWithToken(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        string symbol,\n        uint256 amount,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event GasPaidForExpressCall(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event GasPaidForExpressCallWithToken(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        string symbol,\n        uint256 amount,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeGasPaidForExpressCall(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeGasPaidForExpressCallWithToken(\n        address indexed sourceAddress,\n        string destinationChain,\n        string destinationAddress,\n        bytes32 indexed payloadHash,\n        string symbol,\n        uint256 amount,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event GasAdded(\n        bytes32 indexed txHash,\n        uint256 indexed logIndex,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);\n\n    event ExpressGasAdded(\n        bytes32 indexed txHash,\n        uint256 indexed logIndex,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event NativeExpressGasAdded(\n        bytes32 indexed txHash,\n        uint256 indexed logIndex,\n        uint256 gasFeeAmount,\n        address refundAddress\n    );\n\n    event Refunded(\n        bytes32 indexed txHash,\n        uint256 indexed logIndex,\n        address payable receiver,\n        address token,\n        uint256 amount\n    );\n\n    /**\n     * @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call\n     * @param gasToken The address of the ERC20 token used to pay for gas\n     * @param gasFeeAmount The amount of tokens to pay for gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payGasForContractCall(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call with tokens will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call with tokens\n     * @param symbol The symbol of the token to be sent with the call\n     * @param amount The amount of tokens to be sent with the call\n     * @param gasToken The address of the ERC20 token used to pay for gas\n     * @param gasFeeAmount The amount of tokens to pay for gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payGasForContractCallWithToken(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Pay for gas using native currency for a contract call on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payNativeGasForContractCall(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Pay for gas using native currency for a contract call with tokens on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call with tokens will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call with tokens\n     * @param symbol The symbol of the token to be sent with the call\n     * @param amount The amount of tokens to be sent with the call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payNativeGasForContractCallWithToken(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call\n     * @param gasToken The address of the ERC20 token used to pay for gas\n     * @param gasFeeAmount The amount of tokens to pay for gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payGasForExpressCall(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call with tokens will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call with tokens\n     * @param symbol The symbol of the token to be sent with the call\n     * @param amount The amount of tokens to be sent with the call\n     * @param gasToken The address of the ERC20 token used to pay for gas\n     * @param gasFeeAmount The amount of tokens to pay for gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payGasForExpressCallWithToken(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Pay for gas using native currency for an express contract call on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payNativeGasForExpressCall(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.\n     * @param sender The address making the payment\n     * @param destinationChain The target chain where the contract call with tokens will be made\n     * @param destinationAddress The target address on the destination chain\n     * @param payload Data payload for the contract call with tokens\n     * @param symbol The symbol of the token to be sent with the call\n     * @param amount The amount of tokens to be sent with the call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function payNativeGasForExpressCallWithToken(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.\n     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.\n     * @param txHash The transaction hash of the cross-chain call\n     * @param logIndex The log index for the cross-chain call\n     * @param gasToken The ERC20 token address used to add gas\n     * @param gasFeeAmount The amount of tokens to add as gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function addGas(\n        bytes32 txHash,\n        uint256 logIndex,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Add additional gas payment using native currency after initiating a cross-chain call.\n     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.\n     * @param txHash The transaction hash of the cross-chain call\n     * @param logIndex The log index for the cross-chain call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function addNativeGas(\n        bytes32 txHash,\n        uint256 logIndex,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.\n     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.\n     * @param txHash The transaction hash of the cross-chain call\n     * @param logIndex The log index for the cross-chain call\n     * @param gasToken The ERC20 token address used to add gas\n     * @param gasFeeAmount The amount of tokens to add as gas\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function addExpressGas(\n        bytes32 txHash,\n        uint256 logIndex,\n        address gasToken,\n        uint256 gasFeeAmount,\n        address refundAddress\n    ) external;\n\n    /**\n     * @notice Add additional gas payment using native currency after initiating an express cross-chain call.\n     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.\n     * @param txHash The transaction hash of the cross-chain call\n     * @param logIndex The log index for the cross-chain call\n     * @param refundAddress The address where refunds, if any, should be sent\n     */\n    function addNativeExpressGas(\n        bytes32 txHash,\n        uint256 logIndex,\n        address refundAddress\n    ) external payable;\n\n    /**\n     * @notice Allows the gasCollector to collect accumulated fees from the contract.\n     * @dev Use address(0) as the token address for native currency.\n     * @param receiver The address to receive the collected fees\n     * @param tokens Array of token addresses to be collected\n     * @param amounts Array of amounts to be collected for each respective token address\n     */\n    function collectFees(\n        address payable receiver,\n        address[] calldata tokens,\n        uint256[] calldata amounts\n    ) external;\n\n    /**\n     * @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.\n     * @dev Only callable by the gasCollector.\n     * @dev Use address(0) as the token address to refund native currency.\n     * @param txHash The transaction hash of the cross-chain call\n     * @param logIndex The log index for the cross-chain call\n     * @param receiver The address to receive the refund\n     * @param token The token address to be refunded\n     * @param amount The amount to refund\n     */\n    function refund(\n        bytes32 txHash,\n        uint256 logIndex,\n        address payable receiver,\n        address token,\n        uint256 amount\n    ) external;\n\n    /**\n     * @notice Returns the address of the designated gas collector.\n     * @return address of the gas collector\n     */\n    function gasCollector() external returns (address);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IGovernable } from './IGovernable.sol';\nimport { IImplementation } from './IImplementation.sol';\n\ninterface IAxelarGateway is IImplementation, IGovernable {\n    /**********\\\n    |* Errors *|\n    \\**********/\n\n    error NotSelf();\n    error InvalidCodeHash();\n    error SetupFailed();\n    error InvalidAuthModule();\n    error InvalidTokenDeployer();\n    error InvalidAmount();\n    error InvalidChainId();\n    error InvalidCommands();\n    error TokenDoesNotExist(string symbol);\n    error TokenAlreadyExists(string symbol);\n    error TokenDeployFailed(string symbol);\n    error TokenContractDoesNotExist(address token);\n    error BurnFailed(string symbol);\n    error MintFailed(string symbol);\n    error InvalidSetMintLimitsParams();\n    error ExceedMintLimit(string symbol);\n\n    /**********\\\n    |* Events *|\n    \\**********/\n\n    event TokenSent(\n        address indexed sender,\n        string destinationChain,\n        string destinationAddress,\n        string symbol,\n        uint256 amount\n    );\n\n    event ContractCall(\n        address indexed sender,\n        string destinationChain,\n        string destinationContractAddress,\n        bytes32 indexed payloadHash,\n        bytes payload\n    );\n\n    event ContractCallWithToken(\n        address indexed sender,\n        string destinationChain,\n        string destinationContractAddress,\n        bytes32 indexed payloadHash,\n        bytes payload,\n        string symbol,\n        uint256 amount\n    );\n\n    event Executed(bytes32 indexed commandId);\n\n    event TokenDeployed(string symbol, address tokenAddresses);\n\n    event ContractCallApproved(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        address indexed contractAddress,\n        bytes32 indexed payloadHash,\n        bytes32 sourceTxHash,\n        uint256 sourceEventIndex\n    );\n\n    event ContractCallApprovedWithMint(\n        bytes32 indexed commandId,\n        string sourceChain,\n        string sourceAddress,\n        address indexed contractAddress,\n        bytes32 indexed payloadHash,\n        string symbol,\n        uint256 amount,\n        bytes32 sourceTxHash,\n        uint256 sourceEventIndex\n    );\n\n    event ContractCallExecuted(bytes32 indexed commandId);\n\n    event TokenMintLimitUpdated(string symbol, uint256 limit);\n\n    event OperatorshipTransferred(bytes newOperatorsData);\n\n    event Upgraded(address indexed implementation);\n\n    /********************\\\n    |* Public Functions *|\n    \\********************/\n\n    function sendToken(\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        string calldata symbol,\n        uint256 amount\n    ) external;\n\n    function callContract(\n        string calldata destinationChain,\n        string calldata contractAddress,\n        bytes calldata payload\n    ) external;\n\n    function callContractWithToken(\n        string calldata destinationChain,\n        string calldata contractAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount\n    ) external;\n\n    function isContractCallApproved(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        address contractAddress,\n        bytes32 payloadHash\n    ) external view returns (bool);\n\n    function isContractCallAndMintApproved(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        address contractAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) external view returns (bool);\n\n    function validateContractCall(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) external returns (bool);\n\n    function validateContractCallAndMint(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash,\n        string calldata symbol,\n        uint256 amount\n    ) external returns (bool);\n\n    /***********\\\n    |* Getters *|\n    \\***********/\n\n    function authModule() external view returns (address);\n\n    function tokenDeployer() external view returns (address);\n\n    function tokenMintLimit(string memory symbol) external view returns (uint256);\n\n    function tokenMintAmount(string memory symbol) external view returns (uint256);\n\n    function allTokensFrozen() external view returns (bool);\n\n    function implementation() external view returns (address);\n\n    function tokenAddresses(string memory symbol) external view returns (address);\n\n    function tokenFrozen(string memory symbol) external view returns (bool);\n\n    function isCommandExecuted(bytes32 commandId) external view returns (bool);\n\n    /************************\\\n    |* Governance Functions *|\n    \\************************/\n\n    function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;\n\n    function upgrade(\n        address newImplementation,\n        bytes32 newImplementationCodeHash,\n        bytes calldata setupParams\n    ) external;\n\n    /**********************\\\n    |* External Functions *|\n    \\**********************/\n\n    function execute(bytes calldata input) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarExpressExecutable } from './IAxelarExpressExecutable.sol';\n\n/**\n * @title IAxelarValuedExpressExecutable\n * @dev Interface for the Axelar Valued Express Executable contract.\n */\ninterface IAxelarValuedExpressExecutable is IAxelarExpressExecutable {\n    /**\n     * @dev Returns the value (token address and amount) associated with a contract call\n     * @param sourceChain The source blockchain.\n     * @param sourceAddress The source address.\n     * @param payload The payload data.\n     * @return tokenAddress The address of the token used.\n     * @return value The value associated with the contract call.\n     */\n    function contractCallValue(\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external view returns (address tokenAddress, uint256 value);\n\n    /**\n     * @dev Returns the value (token address and amount) associated with a contract call with token.\n     * @param sourceChain The source blockchain.\n     * @param sourceAddress The source address.\n     * @param payload The payload data.\n     * @param symbol The token symbol.\n     * @param amount The amount of tokens.\n     * @return tokenAddress The address of the token used.\n     * @return value The value associated with the contract call.\n     */\n    function contractCallWithTokenValue(\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload,\n        string calldata symbol,\n        uint256 amount\n    ) external view returns (address tokenAddress, uint256 value);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IContractIdentifier.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// General interface for upgradable contracts\ninterface IContractIdentifier {\n    /**\n     * @notice Returns the contract ID. It can be used as a check during upgrades.\n     * @dev Meant to be overridden in derived contracts.\n     * @return bytes32 The contract ID\n     */\n    function contractId() external pure returns (bytes32);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    error InvalidAccount();\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IGovernable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IGovernable Interface\n * @notice This is an interface used by the AxelarGateway contract to manage governance and mint limiter roles.\n */\ninterface IGovernable {\n    error NotGovernance();\n    error NotMintLimiter();\n    error InvalidGovernance();\n    error InvalidMintLimiter();\n\n    event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance);\n    event MintLimiterTransferred(address indexed previousGovernance, address indexed newGovernance);\n\n    /**\n     * @notice Returns the governance address.\n     * @return address of the governance\n     */\n    function governance() external view returns (address);\n\n    /**\n     * @notice Returns the mint limiter address.\n     * @return address of the mint limiter\n     */\n    function mintLimiter() external view returns (address);\n\n    /**\n     * @notice Transfer the governance role to another address.\n     * @param newGovernance The new governance address\n     */\n    function transferGovernance(address newGovernance) external;\n\n    /**\n     * @notice Transfer the mint limiter role to another address.\n     * @param newGovernance The new mint limiter address\n     */\n    function transferMintLimiter(address newGovernance) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IImplementation.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IContractIdentifier } from './IContractIdentifier.sol';\n\ninterface IImplementation is IContractIdentifier {\n    error NotProxy();\n\n    function setup(bytes calldata data) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IInterchainAddressTracker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IContractIdentifier } from './IContractIdentifier.sol';\n\n/**\n * @title IInterchainAddressTracker\n * @dev Manages trusted addresses by chain, keeps track of addresses supported by the Axelar gateway contract\n */\ninterface IInterchainAddressTracker {\n    error ZeroAddress();\n    error LengthMismatch();\n    error ZeroStringLength();\n    error UntrustedChain();\n\n    event TrustedAddressSet(string chain, string address_);\n    event TrustedAddressRemoved(string chain);\n\n    /**\n     * @dev Gets the name of the chain this is deployed at\n     */\n    function chainName() external view returns (string memory);\n\n    /**\n     * @dev Gets the trusted address at a remote chain\n     * @param chain Chain name of the remote chain\n     * @return trustedAddress_ The trusted address for the chain. Returns '' if the chain is untrusted\n     */\n    function trustedAddress(string memory chain) external view returns (string memory trustedAddress_);\n\n    /**\n     * @dev Gets the trusted address hash for a chain\n     * @param chain Chain name\n     * @return trustedAddressHash_ the hash of the trusted address for that chain\n     */\n    function trustedAddressHash(string memory chain) external view returns (bytes32 trustedAddressHash_);\n\n    /**\n     * @dev Checks whether the interchain sender is a trusted address\n     * @param chain Chain name of the sender\n     * @param address_ Address of the sender\n     * @return bool true if the sender chain/address are trusted, false otherwise\n     */\n    function isTrustedAddress(string calldata chain, string calldata address_) external view returns (bool);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IMulticall\n * @notice This contract is a multi-functional smart contract which allows for multiple\n * contract calls in a single transaction.\n */\ninterface IMulticall {\n    error MulticallFailed();\n\n    /**\n     * @notice Performs multiple delegate calls and returns the results of all calls as an array\n     * @dev This function requires that the contract has sufficient balance for the delegate calls.\n     * If any of the calls fail, the function will revert with the failure message.\n     * @param data An array of encoded function calls\n     * @return results An bytes array with the return data of each function call\n     */\n    function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IOwnable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IOwnable Interface\n * @notice IOwnable is an interface that abstracts the implementation of a\n * contract with ownership control features. It's commonly used in upgradable\n * contracts and includes the functionality to get current owner, transfer\n * ownership, and propose and accept ownership.\n */\ninterface IOwnable {\n    error NotOwner();\n    error InvalidOwner();\n    error InvalidOwnerAddress();\n\n    event OwnershipTransferStarted(address indexed newOwner);\n    event OwnershipTransferred(address indexed newOwner);\n\n    /**\n     * @notice Returns the current owner of the contract.\n     * @return address The address of the current owner\n     */\n    function owner() external view returns (address);\n\n    /**\n     * @notice Returns the address of the pending owner of the contract.\n     * @return address The address of the pending owner\n     */\n    function pendingOwner() external view returns (address);\n\n    /**\n     * @notice Transfers ownership of the contract to a new address\n     * @param newOwner The address to transfer ownership to\n     */\n    function transferOwnership(address newOwner) external;\n\n    /**\n     * @notice Proposes to transfer the contract's ownership to a new address.\n     * The new owner needs to accept the ownership explicitly.\n     * @param newOwner The address to transfer ownership to\n     */\n    function proposeOwnership(address newOwner) external;\n\n    /**\n     * @notice Transfers ownership to the pending owner.\n     * @dev Can only be called by the pending owner\n     */\n    function acceptOwnership() external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title Pausable\n * @notice This contract provides a mechanism to halt the execution of specific functions\n * if a pause condition is activated.\n */\ninterface IPausable {\n    event Paused(address indexed account);\n    event Unpaused(address indexed account);\n\n    error Pause();\n    error NotPaused();\n\n    /**\n     * @notice Check if the contract is paused\n     * @return paused A boolean representing the pause status. True if paused, false otherwise.\n     */\n    function paused() external view returns (bool);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// General interface for upgradable contracts\ninterface IProxy {\n    error InvalidOwner();\n    error InvalidImplementation();\n    error SetupFailed();\n    error NotOwner();\n    error AlreadyInitialized();\n\n    function implementation() external view returns (address);\n\n    function setup(bytes calldata setupParams) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IRolesBase Interface\n * @notice IRolesBase is an interface that abstracts the implementation of a\n * contract with role control internal functions.\n */\ninterface IRolesBase {\n    error MissingRole(address account, uint8 role);\n    error MissingAllRoles(address account, uint256 accountRoles);\n    error MissingAnyOfRoles(address account, uint256 accountRoles);\n\n    error InvalidProposedRoles(address fromAccount, address toAccount, uint256 accountRoles);\n\n    event RolesProposed(address indexed fromAccount, address indexed toAccount, uint256 accountRoles);\n    event RolesAdded(address indexed account, uint256 accountRoles);\n    event RolesRemoved(address indexed account, uint256 accountRoles);\n\n    /**\n     * @notice Checks if an account has a role.\n     * @param account The address to check\n     * @param role The role to check\n     * @return True if the account has the role, false otherwise\n     */\n    function hasRole(address account, uint8 role) external view returns (bool);\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IOwnable } from './IOwnable.sol';\nimport { IImplementation } from './IImplementation.sol';\n\n// General interface for upgradable contracts\ninterface IUpgradable is IOwnable, IImplementation {\n    error InvalidCodeHash();\n    error InvalidImplementation();\n    error SetupFailed();\n\n    event Upgraded(address indexed newImplementation);\n\n    function implementation() external view returns (address);\n\n    function upgrade(\n        address newImplementation,\n        bytes32 newImplementationCodeHash,\n        bytes calldata params\n    ) external;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title AddressBytesUtils\n * @dev This library provides utility functions to convert between `address` and `bytes`.\n */\nlibrary AddressBytes {\n    error InvalidBytesLength(bytes bytesAddress);\n\n    /**\n     * @dev Converts a bytes address to an address type.\n     * @param bytesAddress The bytes representation of an address\n     * @return addr The converted address\n     */\n    function toAddress(bytes memory bytesAddress) internal pure returns (address addr) {\n        if (bytesAddress.length != 20) revert InvalidBytesLength(bytesAddress);\n\n        assembly {\n            addr := mload(add(bytesAddress, 20))\n        }\n    }\n\n    /**\n     * @dev Converts an address to bytes.\n     * @param addr The address to be converted\n     * @return bytesAddress The bytes representation of the address\n     */\n    function toBytes(address addr) internal pure returns (bytes memory bytesAddress) {\n        bytesAddress = new bytes(20);\n        // we can test if using a single 32 byte variable that is the address with the length together and using one mstore would be slightly cheaper.\n        assembly {\n            mstore(add(bytesAddress, 20), addr)\n            mstore(bytesAddress, 20)\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/Bytes32String.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary StringToBytes32 {\n    error InvalidStringLength();\n\n    function toBytes32(string memory str) internal pure returns (bytes32) {\n        // Converting a string to bytes32 for immutable storage\n        bytes memory stringBytes = bytes(str);\n\n        // We can store up to 31 bytes of data as 1 byte is for encoding length\n        if (stringBytes.length == 0 || stringBytes.length > 31) revert InvalidStringLength();\n\n        uint256 stringNumber = uint256(bytes32(stringBytes));\n\n        // Storing string length as the last byte of the data\n        stringNumber |= 0xff & stringBytes.length;\n        return bytes32(stringNumber);\n    }\n}\n\nlibrary Bytes32ToString {\n    function toTrimmedString(bytes32 stringData) internal pure returns (string memory converted) {\n        // recovering string length as the last byte of the data\n        uint256 length = 0xff & uint256(stringData);\n\n        // restoring the string with the correct length\n        assembly {\n            converted := mload(0x40)\n            // new \"memory end\" including padding (the string isn't larger than 32 bytes)\n            mstore(0x40, add(converted, 0x40))\n            // store length in memory\n            mstore(converted, length)\n            // write actual data\n            mstore(add(converted, 0x20), stringData)\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from '../interfaces/IERC20.sol';\n\nerror TokenTransferFailed();\n\n/*\n * @title SafeTokenCall\n * @dev This library is used for performing safe token transfers.\n */\nlibrary SafeTokenCall {\n    /*\n     * @notice Make a safe call to a token contract.\n     * @param token The token contract to interact with.\n     * @param callData The function call data.\n     * @throws TokenTransferFailed error if transfer of token is not successful.\n     */\n    function safeCall(IERC20 token, bytes memory callData) internal {\n        (bool success, bytes memory returnData) = address(token).call(callData);\n        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));\n\n        if (!transferred || address(token).code.length == 0) revert TokenTransferFailed();\n    }\n}\n\n/*\n * @title SafeTokenTransfer\n * @dev This library safely transfers tokens from the contract to a recipient.\n */\nlibrary SafeTokenTransfer {\n    /*\n     * @notice Transfer tokens to a recipient.\n     * @param token The token contract.\n     * @param receiver The recipient of the tokens.\n     * @param amount The amount of tokens to transfer.\n     */\n    function safeTransfer(\n        IERC20 token,\n        address receiver,\n        uint256 amount\n    ) internal {\n        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount));\n    }\n}\n\n/*\n * @title SafeTokenTransferFrom\n * @dev This library helps to safely transfer tokens on behalf of a token holder.\n */\nlibrary SafeTokenTransferFrom {\n    /*\n     * @notice Transfer tokens on behalf of a token holder.\n     * @param token The token contract.\n     * @param from The address of the token holder.\n     * @param to The address the tokens are to be sent to.\n     * @param amount The amount of tokens to be transferred.\n     */\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal {\n        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount));\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/StringStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary StringStorage {\n    struct Wrapper {\n        string value;\n    }\n\n    function set(bytes32 slot, string memory value) internal {\n        _getStorageStruct(slot).value = value;\n    }\n\n    function get(bytes32 slot) internal view returns (string memory value) {\n        value = _getStorageStruct(slot).value;\n    }\n\n    function clear(bytes32 slot) internal {\n        delete _getStorageStruct(slot).value;\n    }\n\n    function _getStorageStruct(bytes32 slot) internal pure returns (Wrapper storage wrapper) {\n        assembly {\n            wrapper.slot := slot\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Implementation.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IImplementation } from '../interfaces/IImplementation.sol';\n\n/**\n * @title Implementation\n * @notice This contract serves as a base for other contracts and enforces a proxy-first access restriction.\n * @dev Derived contracts must implement the setup function.\n */\nabstract contract Implementation is IImplementation {\n    address private immutable implementationAddress;\n\n    /**\n     * @dev Contract constructor that sets the implementation address to the address of this contract.\n     */\n    constructor() {\n        implementationAddress = address(this);\n    }\n\n    /**\n     * @dev Modifier to require the caller to be the proxy contract.\n     * Reverts if the caller is the current contract (i.e., the implementation contract itself).\n     */\n    modifier onlyProxy() {\n        if (implementationAddress == address(this)) revert NotProxy();\n        _;\n    }\n\n    /**\n     * @notice Initializes contract parameters.\n     * This function is intended to be overridden by derived contracts.\n     * The overriding function must have the onlyProxy modifier.\n     * @param params The parameters to be used for initialization\n     */\n    function setup(bytes calldata params) external virtual;\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IImplementation } from '../interfaces/IImplementation.sol';\nimport { IUpgradable } from '../interfaces/IUpgradable.sol';\nimport { Ownable } from '../utils/Ownable.sol';\nimport { Implementation } from './Implementation.sol';\n\n/**\n * @title Upgradable Contract\n * @notice This contract provides an interface for upgradable smart contracts and includes the functionality to perform upgrades.\n */\nabstract contract Upgradable is Ownable, Implementation, IUpgradable {\n    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @notice Constructor sets the implementation address to the address of the contract itself\n     * @dev This is used in the onlyProxy modifier to prevent certain functions from being called directly\n     * on the implementation contract itself.\n     * @dev The owner is initially set as address(1) because the actual owner is set within the proxy. It is not\n     * set as the zero address because Ownable is designed to throw an error for ownership transfers to the zero address.\n     */\n    constructor() Ownable(address(1)) {}\n\n    /**\n     * @notice Returns the address of the current implementation\n     * @return implementation_ Address of the current implementation\n     */\n    function implementation() public view returns (address implementation_) {\n        assembly {\n            implementation_ := sload(_IMPLEMENTATION_SLOT)\n        }\n    }\n\n    /**\n     * @notice Upgrades the contract to a new implementation\n     * @param newImplementation The address of the new implementation contract\n     * @param newImplementationCodeHash The codehash of the new implementation contract\n     * @param params Optional setup parameters for the new implementation contract\n     * @dev This function is only callable by the owner.\n     */\n    function upgrade(\n        address newImplementation,\n        bytes32 newImplementationCodeHash,\n        bytes calldata params\n    ) external override onlyOwner {\n        if (IUpgradable(newImplementation).contractId() != IUpgradable(implementation()).contractId())\n            revert InvalidImplementation();\n\n        if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash();\n\n        emit Upgraded(newImplementation);\n\n        if (params.length > 0) {\n            // slither-disable-next-line controlled-delegatecall\n            (bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params));\n\n            if (!success) revert SetupFailed();\n        }\n\n        assembly {\n            sstore(_IMPLEMENTATION_SLOT, newImplementation)\n        }\n    }\n\n    /**\n     * @notice Sets up the contract with initial data\n     * @param data Initialization data for the contract\n     * @dev This function is only callable by the proxy contract.\n     */\n    function setup(bytes calldata data) external override(IImplementation, Implementation) onlyProxy {\n        _setup(data);\n    }\n\n    /**\n     * @notice Internal function to set up the contract with initial data\n     * @param data Initialization data for the contract\n     * @dev This function should be implemented in derived contracts.\n     */\n    function _setup(bytes calldata data) internal virtual {}\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/InterchainAddressTracker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IInterchainAddressTracker } from '../interfaces/IInterchainAddressTracker.sol';\nimport { StringStorage } from '../libs/StringStorage.sol';\n\n/**\n * @title InterchainAddressTracker\n * @dev Manages and validates trusted interchain addresses of an application.\n */\ncontract InterchainAddressTracker is IInterchainAddressTracker {\n    bytes32 internal constant PREFIX_ADDRESS_MAPPING = keccak256('interchain-address-tracker-address-mapping');\n    bytes32 internal constant PREFIX_ADDRESS_HASH_MAPPING =\n        keccak256('interchain-address-tracker-address-hash-mapping');\n    // bytes32(uint256(keccak256('interchain-address-tracker-chain-name')) - 1)\n    bytes32 internal constant _CHAIN_NAME_SLOT = 0x0e2c162a1f4b5cff9fdbd6b34678a9bcb9898a0b9fbca695b112d61688d8b2ac;\n\n    function _setChainName(string memory chainName_) internal {\n        StringStorage.set(_CHAIN_NAME_SLOT, chainName_);\n    }\n\n    /**\n     * @dev Gets the name of the chain this is deployed at\n     */\n    function chainName() external view returns (string memory chainName_) {\n        chainName_ = StringStorage.get(_CHAIN_NAME_SLOT);\n    }\n\n    /**\n     * @dev Gets the trusted address at a remote chain\n     * @param chain Chain name of the remote chain\n     * @return trustedAddress_ The trusted address for the chain. Returns '' if the chain is untrusted\n     */\n    function trustedAddress(string memory chain) public view returns (string memory trustedAddress_) {\n        trustedAddress_ = StringStorage.get(_getTrustedAddressSlot(chain));\n    }\n\n    /**\n     * @dev Gets the trusted address hash for a chain\n     * @param chain Chain name\n     * @return trustedAddressHash_ the hash of the trusted address for that chain\n     */\n    function trustedAddressHash(string memory chain) public view returns (bytes32 trustedAddressHash_) {\n        bytes32 slot = _getTrustedAddressHashSlot(chain);\n        assembly {\n            trustedAddressHash_ := sload(slot)\n        }\n    }\n\n    /**\n     * @dev Checks whether the interchain sender is a trusted address\n     * @param chain Chain name of the sender\n     * @param address_ Address of the sender\n     * @return bool true if the sender chain/address are trusted, false otherwise\n     */\n    function isTrustedAddress(string calldata chain, string calldata address_) public view returns (bool) {\n        bytes32 addressHash = keccak256(bytes(address_));\n\n        return addressHash == trustedAddressHash(chain);\n    }\n\n    /**\n     * @dev Gets the key for the trusted address at a remote chain\n     * @param chain Chain name of the remote chain\n     * @return slot the slot to store the trusted address in\n     */\n    function _getTrustedAddressSlot(string memory chain) internal pure returns (bytes32 slot) {\n        slot = keccak256(abi.encode(PREFIX_ADDRESS_MAPPING, chain));\n    }\n\n    /**\n     * @dev Gets the key for the trusted address at a remote chain\n     * @param chain Chain name of the remote chain\n     * @return slot the slot to store the trusted address hash in\n     */\n    function _getTrustedAddressHashSlot(string memory chain) internal pure returns (bytes32 slot) {\n        slot = keccak256(abi.encode(PREFIX_ADDRESS_HASH_MAPPING, chain));\n    }\n\n    /**\n     * @dev Sets the trusted address and its hash for a remote chain\n     * @param chain Chain name of the remote chain\n     * @param address_ the string representation of the trusted address\n     */\n    function _setTrustedAddress(string memory chain, string memory address_) internal {\n        if (bytes(chain).length == 0) revert ZeroStringLength();\n        if (bytes(address_).length == 0) revert ZeroStringLength();\n\n        StringStorage.set(_getTrustedAddressSlot(chain), address_);\n\n        bytes32 slot = _getTrustedAddressHashSlot(chain);\n        bytes32 addressHash = keccak256(bytes(address_));\n        assembly {\n            sstore(slot, addressHash)\n        }\n\n        emit TrustedAddressSet(chain, address_);\n    }\n\n    /**\n     * @dev Remove the trusted address of the chain.\n     * @param chain Chain name that should be made untrusted\n     */\n    function _removeTrustedAddress(string memory chain) internal {\n        if (bytes(chain).length == 0) revert ZeroStringLength();\n\n        StringStorage.clear(_getTrustedAddressSlot(chain));\n\n        bytes32 slot = _getTrustedAddressHashSlot(chain);\n        assembly {\n            sstore(slot, 0)\n        }\n\n        emit TrustedAddressRemoved(chain);\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IMulticall } from '../interfaces/IMulticall.sol';\n\n/**\n * @title Multicall\n * @notice This contract is a multi-functional smart contract which allows for multiple\n * contract calls in a single transaction.\n */\ncontract Multicall is IMulticall {\n    /**\n     * @notice Performs multiple delegate calls and returns the results of all calls as an array\n     * @dev This function requires that the contract has sufficient balance for the delegate calls.\n     * If any of the calls fail, the function will revert with the failure message.\n     * @param data An array of encoded function calls\n     * @return results An bytes array with the return data of each function call\n     */\n    function multicall(bytes[] calldata data) public payable returns (bytes[] memory results) {\n        results = new bytes[](data.length);\n        bool success;\n        bytes memory result;\n        for (uint256 i = 0; i < data.length; ++i) {\n            // slither-disable-next-line calls-loop,delegatecall-loop\n            (success, result) = address(this).delegatecall(data[i]);\n\n            if (!success) {\n                if (result.length == 0) revert MulticallFailed();\n                assembly {\n                    revert(add(32, result), mload(result))\n                }\n            }\n\n            results[i] = result;\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IOwnable } from '../interfaces/IOwnable.sol';\n\n/**\n * @title Ownable\n * @notice A contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The owner account is set through ownership transfer. This module makes\n * it possible to transfer the ownership of the contract to a new account in one\n * step, as well as to an interim pending owner. In the second flow the ownership does not\n * change until the pending owner accepts the ownership transfer.\n */\nabstract contract Ownable is IOwnable {\n    // keccak256('owner')\n    bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;\n    // keccak256('ownership-transfer')\n    bytes32 internal constant _OWNERSHIP_TRANSFER_SLOT =\n        0x9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1;\n\n    /**\n     * @notice Initializes the contract by transferring ownership to the owner parameter.\n     * @param _owner Address to set as the initial owner of the contract\n     */\n    constructor(address _owner) {\n        _transferOwnership(_owner);\n    }\n\n    /**\n     * @notice Modifier that throws an error if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        if (owner() != msg.sender) revert NotOwner();\n\n        _;\n    }\n\n    /**\n     * @notice Returns the current owner of the contract.\n     * @return owner_ The current owner of the contract\n     */\n    function owner() public view returns (address owner_) {\n        assembly {\n            owner_ := sload(_OWNER_SLOT)\n        }\n    }\n\n    /**\n     * @notice Returns the pending owner of the contract.\n     * @return owner_ The pending owner of the contract\n     */\n    function pendingOwner() public view returns (address owner_) {\n        assembly {\n            owner_ := sload(_OWNERSHIP_TRANSFER_SLOT)\n        }\n    }\n\n    /**\n     * @notice Transfers ownership of the contract to a new account `newOwner`.\n     * @dev Can only be called by the current owner.\n     * @param newOwner The address to transfer ownership to\n     */\n    function transferOwnership(address newOwner) external virtual onlyOwner {\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @notice Propose to transfer ownership of the contract to a new account `newOwner`.\n     * @dev Can only be called by the current owner. The ownership does not change\n     * until the new owner accepts the ownership transfer.\n     * @param newOwner The address to transfer ownership to\n     */\n    function proposeOwnership(address newOwner) external virtual onlyOwner {\n        if (newOwner == address(0)) revert InvalidOwnerAddress();\n\n        emit OwnershipTransferStarted(newOwner);\n\n        assembly {\n            sstore(_OWNERSHIP_TRANSFER_SLOT, newOwner)\n        }\n    }\n\n    /**\n     * @notice Accepts ownership of the contract.\n     * @dev Can only be called by the pending owner\n     */\n    function acceptOwnership() external virtual {\n        address newOwner = pendingOwner();\n        if (newOwner != msg.sender) revert InvalidOwner();\n\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @notice Internal function to transfer ownership of the contract to a new account `newOwner`.\n     * @dev Called in the constructor to set the initial owner.\n     * @param newOwner The address to transfer ownership to\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        if (newOwner == address(0)) revert InvalidOwnerAddress();\n\n        emit OwnershipTransferred(newOwner);\n\n        assembly {\n            sstore(_OWNER_SLOT, newOwner)\n            sstore(_OWNERSHIP_TRANSFER_SLOT, 0)\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Pausable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IPausable } from '../interfaces/IPausable.sol';\n\n/**\n * @title Pausable\n * @notice This contract provides a mechanism to halt the execution of specific functions\n * if a pause condition is activated.\n */\ncontract Pausable is IPausable {\n    // uint256(keccak256('paused')) - 1\n    uint256 internal constant PAUSE_SLOT = 0xee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d8;\n\n    /**\n     * @notice A modifier that throws a Paused custom error if the contract is paused\n     * @dev This modifier should be used with functions that can be paused\n     */\n    modifier whenNotPaused() {\n        if (paused()) revert Pause();\n        _;\n    }\n\n    modifier whenPaused() {\n        if (!paused()) revert NotPaused();\n        _;\n    }\n\n    /**\n     * @notice Check if the contract is paused\n     * @return paused_ A boolean representing the pause status. True if paused, false otherwise.\n     */\n    function paused() public view returns (bool paused_) {\n        assembly {\n            paused_ := sload(PAUSE_SLOT)\n        }\n    }\n\n    /**\n     * @notice Pauses the contract\n     * @dev This function should be callable by the owner/governance.\n     */\n    function _pause() internal {\n        _setPaused(true);\n        emit Paused(msg.sender);\n    }\n\n    /**\n     * @notice Unpauses the contract\n     * @dev This function should be callable by the owner/governance.\n     */\n    function _unpause() internal {\n        _setPaused(false);\n        emit Unpaused(msg.sender);\n    }\n\n    /**\n     * @notice Sets the pause status of the contract\n     * @dev This is an internal function, meaning it can only be called from within the contract itself\n     * or from derived contracts.\n     * @param paused_ The new pause status\n     */\n    function _setPaused(bool paused_) internal {\n        assembly {\n            sstore(PAUSE_SLOT, paused_)\n        }\n    }\n}\n"
      },
      "@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/RolesBase.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IRolesBase } from '../interfaces/IRolesBase.sol';\n\n/**\n * @title RolesBase\n * @notice A contract module which provides a set if internal functions\n * for implementing role control features.\n */\ncontract RolesBase is IRolesBase {\n    bytes32 internal constant ROLES_PREFIX = keccak256('roles');\n    bytes32 internal constant PROPOSE_ROLES_PREFIX = keccak256('propose-roles');\n\n    /**\n     * @notice Modifier that throws an error if called by any account missing the role.\n     */\n    modifier onlyRole(uint8 role) {\n        if (!_hasRole(_getRoles(msg.sender), role)) revert MissingRole(msg.sender, role);\n\n        _;\n    }\n\n    /**\n     * @notice Modifier that throws an error if called by an account without all the roles.\n     */\n    modifier withEveryRole(uint8[] memory roles) {\n        uint256 accountRoles = _toAccountRoles(roles);\n        if (!_hasAllTheRoles(_getRoles(msg.sender), accountRoles)) revert MissingAllRoles(msg.sender, accountRoles);\n\n        _;\n    }\n\n    /**\n     * @notice Modifier that throws an error if called by an account without any of the roles.\n     */\n    modifier withAnyRole(uint8[] memory roles) {\n        uint256 accountRoles = _toAccountRoles(roles);\n        if (!_hasAnyOfRoles(_getRoles(msg.sender), accountRoles)) revert MissingAnyOfRoles(msg.sender, accountRoles);\n\n        _;\n    }\n\n    /**\n     * @notice Checks if an account has a role.\n     * @param account The address to check\n     * @param role The role to check\n     * @return True if the account has the role, false otherwise\n     */\n    function hasRole(address account, uint8 role) public view returns (bool) {\n        return _hasRole(_getRoles(account), role);\n    }\n\n    /**\n     * @notice Internal function to convert an array of roles to a uint256.\n     * @param roles The roles to convert\n     * @return accountRoles The roles in uint256 format\n     */\n    function _toAccountRoles(uint8[] memory roles) internal pure returns (uint256) {\n        uint256 length = roles.length;\n        uint256 accountRoles;\n\n        for (uint256 i = 0; i < length; ++i) {\n            accountRoles |= (1 << roles[i]);\n        }\n\n        return accountRoles;\n    }\n\n    /**\n     * @notice Internal function to get the key of the roles mapping.\n     * @param account The address to get the key for\n     * @return key The key of the roles mapping\n     */\n    function _rolesKey(address account) internal view virtual returns (bytes32 key) {\n        return keccak256(abi.encodePacked(ROLES_PREFIX, account));\n    }\n\n    /**\n     * @notice Internal function to get the roles of an account.\n     * @param account The address to get the roles for\n     * @return accountRoles The roles of the account in uint256 format\n     */\n    function _getRoles(address account) internal view returns (uint256 accountRoles) {\n        bytes32 key = _rolesKey(account);\n        assembly {\n            accountRoles := sload(key)\n        }\n    }\n\n    /**\n     * @notice Internal function to set the roles of an account.\n     * @param account The address to set the roles for\n     * @param accountRoles The roles to set\n     */\n    function _setRoles(address account, uint256 accountRoles) private {\n        bytes32 key = _rolesKey(account);\n        assembly {\n            sstore(key, accountRoles)\n        }\n    }\n\n    /**\n     * @notice Internal function to get the key of the proposed roles mapping.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address of the pending role\n     * @return key The key of the proposed roles mapping\n     */\n    function _proposalKey(address fromAccount, address toAccount) internal view virtual returns (bytes32 key) {\n        return keccak256(abi.encodePacked(PROPOSE_ROLES_PREFIX, fromAccount, toAccount));\n    }\n\n    /**\n     * @notice Internal function to get the proposed roles of an account.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address of the pending role\n     * @return proposedRoles_ The proposed roles of the account in uint256 format\n     */\n    function _getProposedRoles(address fromAccount, address toAccount) internal view returns (uint256 proposedRoles_) {\n        bytes32 key = _proposalKey(fromAccount, toAccount);\n        assembly {\n            proposedRoles_ := sload(key)\n        }\n    }\n\n    /**\n     * @notice Internal function to set the proposed roles of an account.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address of the pending role\n     * @param proposedRoles_ The proposed roles to set in uint256 format\n     */\n    function _setProposedRoles(\n        address fromAccount,\n        address toAccount,\n        uint256 proposedRoles_\n    ) private {\n        bytes32 key = _proposalKey(fromAccount, toAccount);\n        assembly {\n            sstore(key, proposedRoles_)\n        }\n    }\n\n    /**\n     * @notice Internal function to add a role to an account.\n     * @dev emits a RolesAdded event.\n     * @param account The address to add the role to\n     * @param role The role to add\n     */\n    function _addRole(address account, uint8 role) internal {\n        _addAccountRoles(account, 1 << role);\n    }\n\n    /**\n     * @notice Internal function to add roles to an account.\n     * @dev emits a RolesAdded event.\n     * @dev Called in the constructor to set the initial roles.\n     * @param account The address to add roles to\n     * @param roles The roles to add\n     */\n    function _addRoles(address account, uint8[] memory roles) internal {\n        _addAccountRoles(account, _toAccountRoles(roles));\n    }\n\n    /**\n     * @notice Internal function to add roles to an account.\n     * @dev emits a RolesAdded event.\n     * @dev Called in the constructor to set the initial roles.\n     * @param account The address to add roles to\n     * @param accountRoles The roles to add\n     */\n    function _addAccountRoles(address account, uint256 accountRoles) internal {\n        uint256 newAccountRoles = _getRoles(account) | accountRoles;\n\n        _setRoles(account, newAccountRoles);\n\n        emit RolesAdded(account, accountRoles);\n    }\n\n    /**\n     * @notice Internal function to remove a role from an account.\n     * @dev emits a RolesRemoved event.\n     * @param account The address to remove the role from\n     * @param role The role to remove\n     */\n    function _removeRole(address account, uint8 role) internal {\n        _removeAccountRoles(account, 1 << role);\n    }\n\n    /**\n     * @notice Internal function to remove roles from an account.\n     * @dev emits a RolesRemoved event.\n     * @param account The address to remove roles from\n     * @param roles The roles to remove\n     */\n    function _removeRoles(address account, uint8[] memory roles) internal {\n        _removeAccountRoles(account, _toAccountRoles(roles));\n    }\n\n    /**\n     * @notice Internal function to remove roles from an account.\n     * @dev emits a RolesRemoved event.\n     * @param account The address to remove roles from\n     * @param accountRoles The roles to remove\n     */\n    function _removeAccountRoles(address account, uint256 accountRoles) internal {\n        uint256 newAccountRoles = _getRoles(account) & ~accountRoles;\n\n        _setRoles(account, newAccountRoles);\n\n        emit RolesRemoved(account, accountRoles);\n    }\n\n    /**\n     * @notice Internal function to check if an account has a role.\n     * @param accountRoles The roles of the account in uint256 format\n     * @param role The role to check\n     * @return True if the account has the role, false otherwise\n     */\n    function _hasRole(uint256 accountRoles, uint8 role) internal pure returns (bool) {\n        return accountRoles & (1 << role) != 0;\n    }\n\n    /**\n     * @notice Internal function to check if an account has all the roles.\n     * @param hasAccountRoles The roles of the account in uint256 format\n     * @param mustHaveAccountRoles The roles the account must have\n     * @return True if the account has all the roles, false otherwise\n     */\n    function _hasAllTheRoles(uint256 hasAccountRoles, uint256 mustHaveAccountRoles) internal pure returns (bool) {\n        return (hasAccountRoles & mustHaveAccountRoles) == mustHaveAccountRoles;\n    }\n\n    /**\n     * @notice Internal function to check if an account has any of the roles.\n     * @param hasAccountRoles The roles of the account in uint256 format\n     * @param mustHaveAnyAccountRoles The roles to check in uint256 format\n     * @return True if the account has any of the roles, false otherwise\n     */\n    function _hasAnyOfRoles(uint256 hasAccountRoles, uint256 mustHaveAnyAccountRoles) internal pure returns (bool) {\n        return (hasAccountRoles & mustHaveAnyAccountRoles) != 0;\n    }\n\n    /**\n     * @notice Internal function to propose to transfer roles of message sender to a new account.\n     * @dev Original account must have all the proposed roles.\n     * @dev Emits a RolesProposed event.\n     * @dev Roles are not transferred until the new role accepts the role transfer.\n     * @param fromAccount The address of the current roles\n     * @param toAccount The address to transfer roles to\n     * @param role The role to transfer\n     */\n    function _proposeRole(\n        address fromAccount,\n        address toAccount,\n        uint8 role\n    ) internal {\n        _proposeAccountRoles(fromAccount, toAccount, 1 << role);\n    }\n\n    /**\n     * @notice Internal function to propose to transfer roles of message sender to a new account.\n     * @dev Original account must have all the proposed roles.\n     * @dev Emits a RolesProposed event.\n     * @dev Roles are not transferred until the new role accepts the role transfer.\n     * @param fromAccount The address of the current roles\n     * @param toAccount The address to transfer roles to\n     * @param roles The roles to transfer\n     */\n    function _proposeRoles(\n        address fromAccount,\n        address toAccount,\n        uint8[] memory roles\n    ) internal {\n        _proposeAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));\n    }\n\n    /**\n     * @notice Internal function to propose to transfer roles of message sender to a new account.\n     * @dev Original account must have all the proposed roles.\n     * @dev Emits a RolesProposed event.\n     * @dev Roles are not transferred until the new role accepts the role transfer.\n     * @param fromAccount The address of the current roles\n     * @param toAccount The address to transfer roles to\n     * @param accountRoles The account roles to transfer\n     */\n    function _proposeAccountRoles(\n        address fromAccount,\n        address toAccount,\n        uint256 accountRoles\n    ) internal {\n        if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles);\n\n        _setProposedRoles(fromAccount, toAccount, accountRoles);\n\n        emit RolesProposed(fromAccount, toAccount, accountRoles);\n    }\n\n    /**\n     * @notice Internal function to accept roles transferred from another account.\n     * @dev Pending account needs to pass all the proposed roles.\n     * @dev Emits RolesRemoved and RolesAdded events.\n     * @param fromAccount The address of the current role\n     * @param role The role to accept\n     */\n    function _acceptRole(\n        address fromAccount,\n        address toAccount,\n        uint8 role\n    ) internal virtual {\n        _acceptAccountRoles(fromAccount, toAccount, 1 << role);\n    }\n\n    /**\n     * @notice Internal function to accept roles transferred from another account.\n     * @dev Pending account needs to pass all the proposed roles.\n     * @dev Emits RolesRemoved and RolesAdded events.\n     * @param fromAccount The address of the current role\n     * @param roles The roles to accept\n     */\n    function _acceptRoles(\n        address fromAccount,\n        address toAccount,\n        uint8[] memory roles\n    ) internal virtual {\n        _acceptAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));\n    }\n\n    /**\n     * @notice Internal function to accept roles transferred from another account.\n     * @dev Pending account needs to pass all the proposed roles.\n     * @dev Emits RolesRemoved and RolesAdded events.\n     * @param fromAccount The address of the current role\n     * @param accountRoles The account roles to accept\n     */\n    function _acceptAccountRoles(\n        address fromAccount,\n        address toAccount,\n        uint256 accountRoles\n    ) internal virtual {\n        if (_getProposedRoles(fromAccount, toAccount) != accountRoles) {\n            revert InvalidProposedRoles(fromAccount, toAccount, accountRoles);\n        }\n\n        _setProposedRoles(fromAccount, toAccount, 0);\n        _transferAccountRoles(fromAccount, toAccount, accountRoles);\n    }\n\n    /**\n     * @notice Internal function to transfer roles from one account to another.\n     * @dev Original account must have all the proposed roles.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address to transfer role to\n     * @param role The role to transfer\n     */\n    function _transferRole(\n        address fromAccount,\n        address toAccount,\n        uint8 role\n    ) internal {\n        _transferAccountRoles(fromAccount, toAccount, 1 << role);\n    }\n\n    /**\n     * @notice Internal function to transfer roles from one account to another.\n     * @dev Original account must have all the proposed roles.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address to transfer role to\n     * @param roles The roles to transfer\n     */\n    function _transferRoles(\n        address fromAccount,\n        address toAccount,\n        uint8[] memory roles\n    ) internal {\n        _transferAccountRoles(fromAccount, toAccount, _toAccountRoles(roles));\n    }\n\n    /**\n     * @notice Internal function to transfer roles from one account to another.\n     * @dev Original account must have all the proposed roles.\n     * @param fromAccount The address of the current role\n     * @param toAccount The address to transfer role to\n     * @param accountRoles The account roles to transfer\n     */\n    function _transferAccountRoles(\n        address fromAccount,\n        address toAccount,\n        uint256 accountRoles\n    ) internal {\n        if (!_hasAllTheRoles(_getRoles(fromAccount), accountRoles)) revert MissingAllRoles(fromAccount, accountRoles);\n\n        _removeAccountRoles(fromAccount, accountRoles);\n        _addAccountRoles(toAccount, accountRoles);\n    }\n}\n"
      },
      "contracts/InterchainTokenService.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';\nimport { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';\nimport { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';\nimport { ExpressExecutorTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/express/ExpressExecutorTracker.sol';\nimport { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol';\nimport { Create3Address } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/deploy/Create3Address.sol';\nimport { SafeTokenTransferFrom } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol';\nimport { AddressBytes } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressBytes.sol';\nimport { StringToBytes32, Bytes32ToString } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/Bytes32String.sol';\nimport { Multicall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Multicall.sol';\nimport { Pausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/Pausable.sol';\nimport { InterchainAddressTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/InterchainAddressTracker.sol';\n\nimport { IInterchainTokenService } from './interfaces/IInterchainTokenService.sol';\nimport { ITokenManagerProxy } from './interfaces/ITokenManagerProxy.sol';\nimport { ITokenHandler } from './interfaces/ITokenHandler.sol';\nimport { ITokenManagerDeployer } from './interfaces/ITokenManagerDeployer.sol';\nimport { IInterchainTokenDeployer } from './interfaces/IInterchainTokenDeployer.sol';\nimport { IInterchainTokenExecutable } from './interfaces/IInterchainTokenExecutable.sol';\nimport { IInterchainTokenExpressExecutable } from './interfaces/IInterchainTokenExpressExecutable.sol';\nimport { ITokenManager } from './interfaces/ITokenManager.sol';\n\nimport { Operator } from './utils/Operator.sol';\n\n/**\n * @title The Interchain Token Service\n * @notice This contract is responsible for facilitating interchain token transfers.\n * It (mostly) does not handle tokens, but is responsible for the messaging that needs to occur for interchain transfers to happen.\n * @dev The only storage used in this contract is for Express calls.\n * Furthermore, no ether is intended to or should be sent to this contract except as part of deploy/interchainTransfer payable methods for gas payment.\n */\ncontract InterchainTokenService is\n    Upgradable,\n    Operator,\n    Pausable,\n    Multicall,\n    Create3Address,\n    ExpressExecutorTracker,\n    InterchainAddressTracker,\n    IInterchainTokenService\n{\n    using StringToBytes32 for string;\n    using Bytes32ToString for bytes32;\n    using AddressBytes for bytes;\n    using AddressBytes for address;\n    using SafeTokenTransferFrom for IERC20;\n\n    IAxelarGateway public immutable gateway;\n    IAxelarGasService public immutable gasService;\n    address public immutable interchainTokenFactory;\n    bytes32 public immutable chainNameHash;\n\n    address public immutable interchainTokenDeployer;\n    address public immutable tokenManagerDeployer;\n\n    /**\n     * @dev Token manager implementation addresses\n     */\n    address public immutable tokenManager;\n    address public immutable tokenHandler;\n\n    bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_ID = keccak256('its-interchain-token-id');\n    bytes32 internal constant PREFIX_INTERCHAIN_TOKEN_SALT = keccak256('its-interchain-token-salt');\n\n    bytes32 private constant CONTRACT_ID = keccak256('interchain-token-service');\n    bytes32 private constant EXECUTE_SUCCESS = keccak256('its-execute-success');\n    bytes32 private constant EXPRESS_EXECUTE_SUCCESS = keccak256('its-express-execute-success');\n\n    /**\n     * @dev The message types that are sent between InterchainTokenService on different chains.\n     */\n\n    uint256 private constant MESSAGE_TYPE_INTERCHAIN_TRANSFER = 0;\n    uint256 private constant MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN = 1;\n    uint256 private constant MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER = 2;\n\n    /**\n     * @dev Tokens and token managers deployed via the Token Factory contract use a special deployer address.\n     * This removes the dependency on the address the token factory was deployed too to be able to derive the same tokenId.\n     */\n    address internal constant TOKEN_FACTORY_DEPLOYER = address(0);\n\n    /**\n     * @dev Latest version of metadata that's supported.\n     */\n\n    enum MetadataVersion {\n        CONTRACT_CALL,\n        EXPRESS_CALL\n    }\n\n    uint32 internal constant LATEST_METADATA_VERSION = 1;\n\n    /**\n     * @notice Constructor for the Interchain Token Service.\n     * @dev All of the variables passed here are stored as immutable variables.\n     * @param tokenManagerDeployer_ The address of the TokenManagerDeployer.\n     * @param interchainTokenDeployer_ The address of the InterchainTokenDeployer.\n     * @param gateway_ The address of the AxelarGateway.\n     * @param gasService_ The address of the AxelarGasService.\n     * @param interchainTokenFactory_ The address of the InterchainTokenFactory.\n     * @param chainName_ The name of the chain that this contract is deployed on.\n     * @param tokenManagerImplementation_ The tokenManager implementation.\n     * @param tokenHandler_ The tokenHandler implementation.\n     */\n    constructor(\n        address tokenManagerDeployer_,\n        address interchainTokenDeployer_,\n        address gateway_,\n        address gasService_,\n        address interchainTokenFactory_,\n        string memory chainName_,\n        address tokenManagerImplementation_,\n        address tokenHandler_\n    ) {\n        if (\n            gasService_ == address(0) ||\n            tokenManagerDeployer_ == address(0) ||\n            interchainTokenDeployer_ == address(0) ||\n            gateway_ == address(0) ||\n            interchainTokenFactory_ == address(0) ||\n            tokenManagerImplementation_ == address(0) ||\n            tokenHandler_ == address(0)\n        ) revert ZeroAddress();\n\n        gateway = IAxelarGateway(gateway_);\n        gasService = IAxelarGasService(gasService_);\n        tokenManagerDeployer = tokenManagerDeployer_;\n        interchainTokenDeployer = interchainTokenDeployer_;\n        interchainTokenFactory = interchainTokenFactory_;\n\n        if (bytes(chainName_).length == 0) revert InvalidChainName();\n        chainNameHash = keccak256(bytes(chainName_));\n\n        tokenManager = tokenManagerImplementation_;\n        tokenHandler = tokenHandler_;\n    }\n\n    /*******\\\n    MODIFIERS\n    \\*******/\n\n    /**\n     * @notice This modifier is used to ensure that only a remote InterchainTokenService can invoke the execute function.\n     * @param sourceChain The source chain of the contract call.\n     * @param sourceAddress The source address that the call came from.\n     */\n    modifier onlyRemoteService(string calldata sourceChain, string calldata sourceAddress) {\n        if (!isTrustedAddress(sourceChain, sourceAddress)) revert NotRemoteService();\n\n        _;\n    }\n\n    /*****\\\n    GETTERS\n    \\*****/\n\n    /**\n     * @notice Getter for the contract id.\n     * @return bytes32 The contract id of this contract.\n     */\n    function contractId() external pure returns (bytes32) {\n        return CONTRACT_ID;\n    }\n\n    /**\n     * @notice Calculates the address of a TokenManager from a specific tokenId.\n     * @dev The TokenManager does not need to exist already.\n     * @param tokenId The tokenId.\n     * @return tokenManagerAddress_ The deployment address of the TokenManager.\n     */\n    function tokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) {\n        tokenManagerAddress_ = _create3Address(tokenId);\n    }\n\n    /**\n     * @notice Returns the address of a TokenManager from a specific tokenId.\n     * @dev The TokenManager needs to exist already.\n     * @param tokenId The tokenId.\n     * @return tokenManagerAddress_ The deployment address of the TokenManager.\n     */\n    function validTokenManagerAddress(bytes32 tokenId) public view returns (address tokenManagerAddress_) {\n        tokenManagerAddress_ = tokenManagerAddress(tokenId);\n        if (tokenManagerAddress_.code.length == 0) revert TokenManagerDoesNotExist(tokenId);\n    }\n\n    /**\n     * @notice Returns the address of the token that an existing tokenManager points to.\n     * @param tokenId The tokenId.\n     * @return tokenAddress The address of the token.\n     */\n    function validTokenAddress(bytes32 tokenId) public view returns (address tokenAddress) {\n        address tokenManagerAddress_ = validTokenManagerAddress(tokenId);\n        tokenAddress = ITokenManager(tokenManagerAddress_).tokenAddress();\n    }\n\n    /**\n     * @notice Returns the address of the interchain token associated with the given tokenId.\n     * @dev The token does not need to exist.\n     * @param tokenId The tokenId of the interchain token.\n     * @return tokenAddress The address of the interchain token.\n     */\n    function interchainTokenAddress(bytes32 tokenId) public view returns (address tokenAddress) {\n        tokenId = _getInterchainTokenSalt(tokenId);\n        tokenAddress = _create3Address(tokenId);\n    }\n\n    /**\n     * @notice Calculates the tokenId that would correspond to a link for a given deployer with a specified salt.\n     * @param sender The address of the TokenManager deployer.\n     * @param salt The salt that the deployer uses for the deployment.\n     * @return tokenId The tokenId that the custom TokenManager would get (or has gotten).\n     */\n    function interchainTokenId(address sender, bytes32 salt) public pure returns (bytes32 tokenId) {\n        tokenId = keccak256(abi.encode(PREFIX_INTERCHAIN_TOKEN_ID, sender, salt));\n    }\n\n    /**\n     * @notice Getter function for TokenManager implementation. This will mainly be called by TokenManager proxies\n     * to figure out their implementations.\n     * @return tokenManagerAddress The address of the TokenManager implementation.\n     */\n    function tokenManagerImplementation(uint256 /*tokenManagerType*/) external view returns (address) {\n        return tokenManager;\n    }\n\n    /**\n     * @notice Getter function for the flow limit of an existing TokenManager with a given tokenId.\n     * @param tokenId The tokenId of the TokenManager.\n     * @return flowLimit_ The flow limit.\n     */\n    function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_) {\n        ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId));\n        flowLimit_ = tokenManager_.flowLimit();\n    }\n\n    /**\n     * @notice Getter function for the flow out amount of an existing TokenManager with a given tokenId.\n     * @param tokenId The tokenId of the TokenManager.\n     * @return flowOutAmount_ The flow out amount.\n     */\n    function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_) {\n        ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId));\n        flowOutAmount_ = tokenManager_.flowOutAmount();\n    }\n\n    /**\n     * @notice Getter function for the flow in amount of an existing TokenManager with a given tokenId.\n     * @param tokenId The tokenId of the TokenManager.\n     * @return flowInAmount_ The flow in amount.\n     */\n    function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_) {\n        ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenId));\n        flowInAmount_ = tokenManager_.flowInAmount();\n    }\n\n    /************\\\n    USER FUNCTIONS\n    \\************/\n\n    /**\n     * @notice Used to deploy remote custom TokenManagers.\n     * @dev At least the `gasValue` amount of native token must be passed to the function call. `gasValue` exists because this function can be\n     * part of a multicall involving multiple functions that could make remote contract calls.\n     * @param salt The salt to be used during deployment.\n     * @param destinationChain The name of the chain to deploy the TokenManager and standardized token to.\n     * @param tokenManagerType The type of token manager to be deployed. Cannot be NATIVE_INTERCHAIN_TOKEN.\n     * @param params The params that will be used to initialize the TokenManager.\n     * @param gasValue The amount of native tokens to be used to pay for gas for the remote deployment.\n     * @return tokenId The tokenId corresponding to the deployed TokenManager.\n     */\n    function deployTokenManager(\n        bytes32 salt,\n        string calldata destinationChain,\n        TokenManagerType tokenManagerType,\n        bytes calldata params,\n        uint256 gasValue\n    ) external payable whenNotPaused returns (bytes32 tokenId) {\n        // Custom token managers can't be deployed with Interchain token mint burn type, which is reserved for interchain tokens\n        if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType);\n\n        address deployer = msg.sender;\n\n        if (deployer == interchainTokenFactory) {\n            deployer = TOKEN_FACTORY_DEPLOYER;\n        }\n\n        tokenId = interchainTokenId(deployer, salt);\n\n        emit InterchainTokenIdClaimed(tokenId, deployer, salt);\n\n        if (bytes(destinationChain).length == 0) {\n            _deployTokenManager(tokenId, tokenManagerType, params);\n        } else {\n            _deployRemoteTokenManager(tokenId, destinationChain, gasValue, tokenManagerType, params);\n        }\n    }\n\n    /**\n     * @notice Used to deploy an interchain token alongside a TokenManager in another chain.\n     * @dev At least the `gasValue` amount of native token must be passed to the function call. `gasValue` exists because this function can be\n     * part of a multicall involving multiple functions that could make remote contract calls. If the `minter` parameter is empty bytes then\n     * a mint/burn TokenManager is used, otherwise a lock/unlock TokenManager is used.\n     * @param salt The salt to be used during deployment.\n     * @param destinationChain The name of the destination chain to deploy to.\n     * @param name The name of the token to be deployed.\n     * @param symbol The symbol of the token to be deployed.\n     * @param decimals The decimals of the token to be deployed.\n     * @param minter The address that will be able to mint and burn the deployed token.\n     * @param gasValue The amount of native tokens to be used to pay for gas for the remote deployment.\n     * @return tokenId The tokenId corresponding to the deployed InterchainToken.\n     */\n    function deployInterchainToken(\n        bytes32 salt,\n        string calldata destinationChain,\n        string memory name,\n        string memory symbol,\n        uint8 decimals,\n        bytes memory minter,\n        uint256 gasValue\n    ) external payable whenNotPaused returns (bytes32 tokenId) {\n        address deployer = msg.sender;\n\n        if (deployer == interchainTokenFactory) deployer = TOKEN_FACTORY_DEPLOYER;\n\n        tokenId = interchainTokenId(deployer, salt);\n\n        if (bytes(destinationChain).length == 0) {\n            address tokenAddress = _deployInterchainToken(tokenId, minter, name, symbol, decimals);\n\n            _deployTokenManager(tokenId, TokenManagerType.NATIVE_INTERCHAIN_TOKEN, abi.encode(minter, tokenAddress));\n        } else {\n            _deployRemoteInterchainToken(tokenId, name, symbol, decimals, minter, destinationChain, gasValue);\n        }\n    }\n\n    /**\n     * @notice Returns the amount of token that this call is worth.\n     * @dev If `tokenAddress` is `0`, then value is in terms of the native token, otherwise it's in terms of the token address.\n     * @param sourceChain The source chain.\n     * @param sourceAddress The source address on the source chain.\n     * @param payload The payload sent with the call.\n     * @return address The token address.\n     * @return uint256 The value the call is worth.\n     */\n    function contractCallValue(\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) public view virtual onlyRemoteService(sourceChain, sourceAddress) whenNotPaused returns (address, uint256) {\n        (uint256 messageType, bytes32 tokenId, , uint256 amount) = abi.decode(payload, (uint256, bytes32, bytes, uint256));\n\n        if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) {\n            revert InvalidExpressMessageType(messageType);\n        }\n\n        return (validTokenAddress(tokenId), amount);\n    }\n\n    /**\n     * @notice Express executes operations based on the payload and selector.\n     * @param commandId The unique message id.\n     * @param sourceChain The chain where the transaction originates from.\n     * @param sourceAddress The address of the remote ITS where the transaction originates from.\n     * @param payload The encoded data payload for the transaction.\n     */\n    function expressExecute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external payable whenNotPaused {\n        uint256 messageType = abi.decode(payload, (uint256));\n        if (messageType != MESSAGE_TYPE_INTERCHAIN_TRANSFER) {\n            revert InvalidExpressMessageType(messageType);\n        }\n\n        if (gateway.isCommandExecuted(commandId)) revert AlreadyExecuted();\n\n        address expressExecutor = msg.sender;\n        bytes32 payloadHash = keccak256(payload);\n\n        emit ExpressExecuted(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor);\n\n        _setExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor);\n\n        _expressExecute(commandId, sourceChain, payload);\n    }\n\n    /**\n     * @notice Uses the caller's tokens to fullfill a sendCall ahead of time. Use this only if you have detected an outgoing\n     * interchainTransfer that matches the parameters passed here.\n     * @param commandId The unique message id of the transfer being expressed.\n     * @param sourceChain the name of the chain where the interchainTransfer originated from.\n     * @param payload the payload of the receive token\n     */\n    function _expressExecute(bytes32 commandId, string calldata sourceChain, bytes calldata payload) internal {\n        (, bytes32 tokenId, bytes memory sourceAddress, bytes memory destinationAddressBytes, uint256 amount, bytes memory data) = abi\n            .decode(payload, (uint256, bytes32, bytes, bytes, uint256, bytes));\n        address destinationAddress = destinationAddressBytes.toAddress();\n\n        IERC20 token;\n        {\n            ITokenManager tokenManager_ = ITokenManager(tokenManagerAddress(tokenId));\n            token = IERC20(tokenManager_.tokenAddress());\n\n            (bool success, bytes memory returnData) = tokenHandler.delegatecall(\n                abi.encodeWithSelector(\n                    ITokenHandler.transferTokenFrom.selector,\n                    tokenManager_.implementationType(),\n                    address(token),\n                    msg.sender,\n                    destinationAddress,\n                    amount\n                )\n            );\n            if (!success) revert TokenHandlerFailed(returnData);\n            amount = abi.decode(returnData, (uint256));\n        }\n\n        // slither-disable-next-line reentrancy-events\n        emit InterchainTransferReceived(\n            commandId,\n            tokenId,\n            sourceChain,\n            sourceAddress,\n            destinationAddress,\n            amount,\n            data.length == 0 ? bytes32(0) : keccak256(data)\n        );\n\n        if (data.length != 0) {\n            bytes32 result = IInterchainTokenExpressExecutable(destinationAddress).expressExecuteWithInterchainToken(\n                commandId,\n                sourceChain,\n                sourceAddress,\n                data,\n                tokenId,\n                address(token),\n                amount\n            );\n\n            if (result != EXPRESS_EXECUTE_SUCCESS) revert ExpressExecuteWithInterchainTokenFailed(destinationAddress);\n        }\n    }\n\n    /**\n     * @notice Initiates an interchain transfer of a specified token to a destination chain.\n     * @dev The function retrieves the TokenManager associated with the tokenId.\n     * @param tokenId The unique identifier of the token to be transferred.\n     * @param destinationChain The destination chain to send the tokens to.\n     * @param destinationAddress The address on the destination chain to send the tokens to.\n     * @param amount The amount of tokens to be transferred.\n     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).\n     */\n    function interchainTransfer(\n        bytes32 tokenId,\n        string calldata destinationChain,\n        bytes calldata destinationAddress,\n        uint256 amount,\n        bytes calldata metadata,\n        uint256 gasValue\n    ) external payable whenNotPaused {\n        amount = _takeToken(tokenId, msg.sender, amount, false);\n\n        (MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata);\n\n        _transmitInterchainTransfer(tokenId, msg.sender, destinationChain, destinationAddress, amount, metadataVersion, data, gasValue);\n    }\n\n    /**\n     * @notice Initiates an interchain call contract with interchain token to a destination chain.\n     * @param tokenId The unique identifier of the token to be transferred.\n     * @param destinationChain The destination chain to send the tokens to.\n     * @param destinationAddress The address on the destination chain to send the tokens to.\n     * @param amount The amount of tokens to be transferred.\n     * @param data Additional data to be passed along with the transfer.\n     */\n    function callContractWithInterchainToken(\n        bytes32 tokenId,\n        string calldata destinationChain,\n        bytes calldata destinationAddress,\n        uint256 amount,\n        bytes memory data,\n        uint256 gasValue\n    ) external payable whenNotPaused {\n        if (data.length == 0) revert EmptyData();\n\n        amount = _takeToken(tokenId, msg.sender, amount, false);\n\n        _transmitInterchainTransfer(\n            tokenId,\n            msg.sender,\n            destinationChain,\n            destinationAddress,\n            amount,\n            MetadataVersion.CONTRACT_CALL,\n            data,\n            gasValue\n        );\n    }\n\n    /******************\\\n    TOKEN ONLY FUNCTIONS\n    \\******************/\n\n    /**\n     * @notice Transmit an interchain transfer for the given tokenId.\n     * @dev Only callable by a token registered under a tokenId.\n     * @param tokenId The tokenId of the token (which must be the msg.sender).\n     * @param sourceAddress The address where the token is coming from.\n     * @param destinationChain The name of the chain to send tokens to.\n     * @param destinationAddress The destinationAddress for the interchainTransfer.\n     * @param amount The amount of token to give.\n     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).\n     */\n    function transmitInterchainTransfer(\n        bytes32 tokenId,\n        address sourceAddress,\n        string calldata destinationChain,\n        bytes memory destinationAddress,\n        uint256 amount,\n        bytes calldata metadata\n    ) external payable whenNotPaused {\n        amount = _takeToken(tokenId, sourceAddress, amount, true);\n\n        (MetadataVersion metadataVersion, bytes memory data) = _decodeMetadata(metadata);\n\n        _transmitInterchainTransfer(tokenId, sourceAddress, destinationChain, destinationAddress, amount, metadataVersion, data, msg.value);\n    }\n\n    /*************\\\n    OWNER FUNCTIONS\n    \\*************/\n\n    /**\n     * @notice Used to set a flow limit for a token manager that has the service as its operator.\n     * @param tokenIds An array of the tokenIds of the tokenManagers to set the flow limits of.\n     * @param flowLimits The flowLimits to set.\n     */\n    function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external onlyRole(uint8(Roles.OPERATOR)) {\n        uint256 length = tokenIds.length;\n        if (length != flowLimits.length) revert LengthMismatch();\n\n        for (uint256 i; i < length; ++i) {\n            ITokenManager tokenManager_ = ITokenManager(validTokenManagerAddress(tokenIds[i]));\n            // slither-disable-next-line calls-loop\n            tokenManager_.setFlowLimit(flowLimits[i]);\n        }\n    }\n\n    /**\n     * @notice Used to set a trusted address for a chain.\n     * @param chain The chain to set the trusted address of.\n     * @param address_ The address to set as trusted.\n     */\n    function setTrustedAddress(string memory chain, string memory address_) external onlyOwner {\n        _setTrustedAddress(chain, address_);\n    }\n\n    /**\n     * @notice Used to remove a trusted address for a chain.\n     * @param chain The chain to set the trusted address of.\n     */\n    function removeTrustedAddress(string memory chain) external onlyOwner {\n        _removeTrustedAddress(chain);\n    }\n\n    /**\n     * @notice Allows the owner to pause/unpause the token service.\n     * @param paused Boolean value representing whether to pause or unpause.\n     */\n    function setPauseStatus(bool paused) external onlyOwner {\n        if (paused) {\n            _pause();\n        } else {\n            _unpause();\n        }\n    }\n\n    /****************\\\n    INTERNAL FUNCTIONS\n    \\****************/\n\n    function _setup(bytes calldata params) internal override {\n        (address operator, string memory chainName_, string[] memory trustedChainNames, string[] memory trustedAddresses) = abi.decode(\n            params,\n            (address, string, string[], string[])\n        );\n        uint256 length = trustedChainNames.length;\n\n        if (operator == address(0)) revert ZeroAddress();\n        if (bytes(chainName_).length == 0 || keccak256(bytes(chainName_)) != chainNameHash) revert InvalidChainName();\n        if (length != trustedAddresses.length) revert LengthMismatch();\n\n        _addOperator(operator);\n        _setChainName(chainName_);\n\n        for (uint256 i; i < length; ++i) {\n            _setTrustedAddress(trustedChainNames[i], trustedAddresses[i]);\n        }\n    }\n\n    /**\n     * @notice Executes operations based on the payload and selector.\n     * @param commandId The unique message id.\n     * @param sourceChain The chain where the transaction originates from.\n     * @param sourceAddress The address of the remote ITS where the transaction originates from.\n     * @param payload The encoded data payload for the transaction.\n     */\n    function execute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external onlyRemoteService(sourceChain, sourceAddress) whenNotPaused {\n        bytes32 payloadHash = keccak256(payload);\n\n        if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash)) revert NotApprovedByGateway();\n\n        uint256 messageType = abi.decode(payload, (uint256));\n        if (messageType == MESSAGE_TYPE_INTERCHAIN_TRANSFER) {\n            address expressExecutor = _popExpressExecutor(commandId, sourceChain, sourceAddress, payloadHash);\n\n            _processInterchainTransferPayload(commandId, expressExecutor, sourceChain, payload);\n\n            if (expressExecutor != address(0)) {\n                emit ExpressExecutionFulfilled(commandId, sourceChain, sourceAddress, payloadHash, expressExecutor);\n            }\n        } else if (messageType == MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER) {\n            _processDeployTokenManagerPayload(payload);\n        } else if (messageType == MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN) {\n            _processDeployInterchainTokenPayload(payload);\n        } else {\n            revert InvalidMessageType(messageType);\n        }\n    }\n\n    function contractCallWithTokenValue(\n        string calldata /*sourceChain*/,\n        string calldata /*sourceAddress*/,\n        bytes calldata /*payload*/,\n        string calldata /*symbol*/,\n        uint256 /*amount*/\n    ) public view virtual returns (address, uint256) {\n        revert ExecuteWithTokenNotSupported();\n    }\n\n    function expressExecuteWithToken(\n        bytes32 /*commandId*/,\n        string calldata /*sourceChain*/,\n        string calldata /*sourceAddress*/,\n        bytes calldata /*payload*/,\n        string calldata /*tokenSymbol*/,\n        uint256 /*amount*/\n    ) external payable {\n        revert ExecuteWithTokenNotSupported();\n    }\n\n    function executeWithToken(\n        bytes32 /*commandId*/,\n        string calldata /*sourceChain*/,\n        string calldata /*sourceAddress*/,\n        bytes calldata /*payload*/,\n        string calldata /*tokenSymbol*/,\n        uint256 /*amount*/\n    ) external pure {\n        revert ExecuteWithTokenNotSupported();\n    }\n\n    /**\n     * @notice Processes the payload data for a send token call.\n     * @param commandId The unique message id.\n     * @param expressExecutor The address of the express executor. Equals `address(0)` if it wasn't expressed.\n     * @param sourceChain The chain where the transaction originates from.\n     * @param payload The encoded data payload to be processed.\n     */\n    function _processInterchainTransferPayload(\n        bytes32 commandId,\n        address expressExecutor,\n        string calldata sourceChain,\n        bytes calldata payload\n    ) internal {\n        bytes32 tokenId;\n        bytes memory sourceAddress;\n        address destinationAddress;\n        uint256 amount;\n        bytes memory data;\n        {\n            bytes memory destinationAddressBytes;\n            (, tokenId, sourceAddress, destinationAddressBytes, amount, data) = abi.decode(\n                payload,\n                (uint256, bytes32, bytes, bytes, uint256, bytes)\n            );\n            destinationAddress = destinationAddressBytes.toAddress();\n        }\n\n        // Return token to the existing express caller\n        if (expressExecutor != address(0)) {\n            // slither-disable-next-line unused-return\n            _giveToken(tokenId, expressExecutor, amount);\n\n            return;\n        }\n\n        address tokenAddress;\n        (amount, tokenAddress) = _giveToken(tokenId, destinationAddress, amount);\n\n        // slither-disable-next-line reentrancy-events\n        emit InterchainTransferReceived(\n            commandId,\n            tokenId,\n            sourceChain,\n            sourceAddress,\n            destinationAddress,\n            amount,\n            data.length == 0 ? bytes32(0) : keccak256(data)\n        );\n\n        if (data.length != 0) {\n            bytes32 result = IInterchainTokenExecutable(destinationAddress).executeWithInterchainToken(\n                commandId,\n                sourceChain,\n                sourceAddress,\n                data,\n                tokenId,\n                tokenAddress,\n                amount\n            );\n\n            if (result != EXECUTE_SUCCESS) revert ExecuteWithInterchainTokenFailed(destinationAddress);\n        }\n    }\n\n    /**\n     * @notice Processes a deploy token manager payload.\n     */\n    function _processDeployTokenManagerPayload(bytes calldata payload) internal {\n        (, bytes32 tokenId, TokenManagerType tokenManagerType, bytes memory params) = abi.decode(\n            payload,\n            (uint256, bytes32, TokenManagerType, bytes)\n        );\n\n        if (tokenManagerType == TokenManagerType.NATIVE_INTERCHAIN_TOKEN) revert CannotDeploy(tokenManagerType);\n\n        _deployTokenManager(tokenId, tokenManagerType, params);\n    }\n\n    /**\n     * @notice Processes a deploy interchain token manager payload.\n     * @param payload The encoded data payload to be processed.\n     */\n    function _processDeployInterchainTokenPayload(bytes calldata payload) internal {\n        (, bytes32 tokenId, string memory name, string memory symbol, uint8 decimals, bytes memory minterBytes) = abi.decode(\n            payload,\n            (uint256, bytes32, string, string, uint8, bytes)\n        );\n        address tokenAddress;\n\n        tokenAddress = _deployInterchainToken(tokenId, minterBytes, name, symbol, decimals);\n\n        _deployTokenManager(tokenId, TokenManagerType.NATIVE_INTERCHAIN_TOKEN, abi.encode(minterBytes, tokenAddress));\n    }\n\n    /**\n     * @notice Calls a contract on a specific destination chain with the given payload\n     * @param destinationChain The target chain where the contract will be called.\n     * @param payload The data payload for the transaction.\n     * @param gasValue The amount of gas to be paid for the transaction.\n     */\n    function _callContract(\n        string calldata destinationChain,\n        bytes memory payload,\n        MetadataVersion metadataVersion,\n        uint256 gasValue\n    ) internal {\n        string memory destinationAddress = trustedAddress(destinationChain);\n        if (bytes(destinationAddress).length == 0) revert UntrustedChain();\n\n        if (gasValue > 0) {\n            if (metadataVersion == MetadataVersion.CONTRACT_CALL) {\n                gasService.payNativeGasForContractCall{ value: gasValue }(\n                    address(this),\n                    destinationChain,\n                    destinationAddress,\n                    payload, // solhint-disable-next-line avoid-tx-origin\n                    tx.origin\n                );\n            } else if (metadataVersion == MetadataVersion.EXPRESS_CALL) {\n                gasService.payNativeGasForExpressCall{ value: gasValue }(\n                    address(this),\n                    destinationChain,\n                    destinationAddress,\n                    payload, // solhint-disable-next-line avoid-tx-origin\n                    tx.origin\n                );\n            } else {\n                revert InvalidMetadataVersion(uint32(metadataVersion));\n            }\n        }\n\n        gateway.callContract(destinationChain, destinationAddress, payload);\n    }\n\n    /**\n     * @notice Deploys a token manager on a destination chain.\n     * @param tokenId The ID of the token.\n     * @param destinationChain The chain where the token manager will be deployed.\n     * @param gasValue The amount of gas to be paid for the transaction.\n     * @param tokenManagerType The type of token manager to be deployed.\n     * @param params Additional parameters for the token manager deployment.\n     */\n    function _deployRemoteTokenManager(\n        bytes32 tokenId,\n        string calldata destinationChain,\n        uint256 gasValue,\n        TokenManagerType tokenManagerType,\n        bytes memory params\n    ) internal {\n        // slither-disable-next-line unused-return\n        validTokenManagerAddress(tokenId);\n\n        emit TokenManagerDeploymentStarted(tokenId, destinationChain, tokenManagerType, params);\n\n        bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_TOKEN_MANAGER, tokenId, tokenManagerType, params);\n\n        _callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue);\n    }\n\n    /**\n     * @notice Deploys an interchain token on a destination chain.\n     * @param tokenId The ID of the token.\n     * @param name The name of the token.\n     * @param symbol The symbol of the token.\n     * @param decimals The number of decimals of the token.\n     * @param minter The minter address for the token.\n     * @param destinationChain The destination chain where the token will be deployed.\n     * @param gasValue The amount of gas to be paid for the transaction.\n     */\n    function _deployRemoteInterchainToken(\n        bytes32 tokenId,\n        string memory name,\n        string memory symbol,\n        uint8 decimals,\n        bytes memory minter,\n        string calldata destinationChain,\n        uint256 gasValue\n    ) internal {\n        // slither-disable-next-line unused-return\n        validTokenManagerAddress(tokenId);\n\n        // slither-disable-next-line reentrancy-events\n        emit InterchainTokenDeploymentStarted(tokenId, name, symbol, decimals, minter, destinationChain);\n\n        bytes memory payload = abi.encode(MESSAGE_TYPE_DEPLOY_INTERCHAIN_TOKEN, tokenId, name, symbol, decimals, minter);\n\n        _callContract(destinationChain, payload, MetadataVersion.CONTRACT_CALL, gasValue);\n    }\n\n    /**\n     * @notice Deploys a token manager.\n     * @param tokenId The ID of the token.\n     * @param tokenManagerType The type of the token manager to be deployed.\n     * @param params Additional parameters for the token manager deployment.\n     */\n    function _deployTokenManager(bytes32 tokenId, TokenManagerType tokenManagerType, bytes memory params) internal {\n        (bool success, bytes memory returnData) = tokenManagerDeployer.delegatecall(\n            abi.encodeWithSelector(ITokenManagerDeployer.deployTokenManager.selector, tokenId, tokenManagerType, params)\n        );\n        if (!success) revert TokenManagerDeploymentFailed(returnData);\n\n        address tokenManager_;\n        assembly {\n            tokenManager_ := mload(add(returnData, 0x20))\n        }\n\n        if (tokenManagerType == TokenManagerType.LOCK_UNLOCK || tokenManagerType == TokenManagerType.LOCK_UNLOCK_FEE) {\n            ITokenManager(tokenManager_).approveService();\n        }\n\n        // slither-disable-next-line reentrancy-events\n        emit TokenManagerDeployed(tokenId, tokenManager_, tokenManagerType, params);\n    }\n\n    /**\n     * @notice Computes the salt for an interchain token deployment.\n     * @param tokenId The ID of the token.\n     * @return salt The computed salt for the token deployment.\n     */\n    function _getInterchainTokenSalt(bytes32 tokenId) internal pure returns (bytes32 salt) {\n        return keccak256(abi.encode(PREFIX_INTERCHAIN_TOKEN_SALT, tokenId));\n    }\n\n    /**\n     * @notice Deploys an interchain token.\n     * @param tokenId The ID of the token.\n     * @param minterBytes The minter address for the token.\n     * @param name The name of the token.\n     * @param symbol The symbol of the token.\n     * @param decimals The number of decimals of the token.\n     */\n    function _deployInterchainToken(\n        bytes32 tokenId,\n        bytes memory minterBytes,\n        string memory name,\n        string memory symbol,\n        uint8 decimals\n    ) internal returns (address tokenAddress) {\n        bytes32 salt = _getInterchainTokenSalt(tokenId);\n\n        address minter;\n        if (bytes(minterBytes).length != 0) minter = minterBytes.toAddress();\n\n        (bool success, bytes memory returnData) = interchainTokenDeployer.delegatecall(\n            abi.encodeWithSelector(IInterchainTokenDeployer.deployInterchainToken.selector, salt, tokenId, minter, name, symbol, decimals)\n        );\n        if (!success) {\n            revert InterchainTokenDeploymentFailed(returnData);\n        }\n\n        assembly {\n            tokenAddress := mload(add(returnData, 0x20))\n        }\n\n        // slither-disable-next-line reentrancy-events\n        emit InterchainTokenDeployed(tokenId, tokenAddress, minter, name, symbol, decimals);\n    }\n\n    /**\n     * @notice Decodes the metadata into a version number and data bytes.\n     * @dev The function expects the metadata to have the version in the first 4 bytes, followed by the actual data.\n     * @param metadata The bytes containing the metadata to decode.\n     * @return version The version number extracted from the metadata.\n     * @return data The data bytes extracted from the metadata.\n     */\n    function _decodeMetadata(bytes calldata metadata) internal pure returns (MetadataVersion version, bytes memory data) {\n        if (metadata.length < 4) return (MetadataVersion.CONTRACT_CALL, data);\n\n        uint32 versionUint = uint32(bytes4(metadata[:4]));\n        if (versionUint > LATEST_METADATA_VERSION) revert InvalidMetadataVersion(versionUint);\n\n        version = MetadataVersion(versionUint);\n\n        if (metadata.length == 4) return (version, data);\n\n        data = metadata[4:];\n    }\n\n    /**\n     * @notice Transmit a callContractWithInterchainToken for the given tokenId.\n     * @param tokenId The tokenId of the TokenManager (which must be the msg.sender).\n     * @param sourceAddress The address where the token is coming from, which will also be used for gas reimbursement.\n     * @param destinationChain The name of the chain to send tokens to.\n     * @param destinationAddress The destinationAddress for the interchainTransfer.\n     * @param amount The amount of tokens to send.\n     * @param metadataVersion The version of the metadata.\n     * @param data The data to be passed with the token transfer.\n     */\n    function _transmitInterchainTransfer(\n        bytes32 tokenId,\n        address sourceAddress,\n        string calldata destinationChain,\n        bytes memory destinationAddress,\n        uint256 amount,\n        MetadataVersion metadataVersion,\n        bytes memory data,\n        uint256 gasValue\n    ) internal {\n        // slither-disable-next-line reentrancy-events\n        emit InterchainTransfer(\n            tokenId,\n            sourceAddress,\n            destinationChain,\n            destinationAddress,\n            amount,\n            data.length == 0 ? bytes32(0) : keccak256(data)\n        );\n\n        bytes memory payload = abi.encode(\n            MESSAGE_TYPE_INTERCHAIN_TRANSFER,\n            tokenId,\n            sourceAddress.toBytes(),\n            destinationAddress,\n            amount,\n            data\n        );\n\n        _callContract(destinationChain, payload, metadataVersion, gasValue);\n    }\n\n    /**\n     * @dev Takes token from a sender via the token service. `tokenOnly` indicates if the caller should be restricted to the token only.\n     */\n    function _takeToken(bytes32 tokenId, address from, uint256 amount, bool tokenOnly) internal returns (uint256) {\n        address tokenManager_ = tokenManagerAddress(tokenId);\n        uint256 tokenManagerType;\n        address tokenAddress;\n\n        (tokenManagerType, tokenAddress) = ITokenManagerProxy(tokenManager_).getImplementationTypeAndTokenAddress();\n\n        if (tokenOnly && msg.sender != tokenAddress) revert NotToken(msg.sender, tokenAddress);\n\n        (bool success, bytes memory data) = tokenHandler.delegatecall(\n            abi.encodeWithSelector(ITokenHandler.takeToken.selector, tokenManagerType, tokenAddress, tokenManager_, from, amount)\n        );\n        if (!success) revert TakeTokenFailed(data);\n        amount = abi.decode(data, (uint256));\n\n        /// @dev Track the flow amount being sent out as a message\n        ITokenManager(tokenManager_).addFlowOut(amount);\n\n        return amount;\n    }\n\n    /**\n     * @dev Gives token to recipient via the token service.\n     */\n    function _giveToken(bytes32 tokenId, address to, uint256 amount) internal returns (uint256, address) {\n        address tokenManager_ = tokenManagerAddress(tokenId);\n\n        (uint256 tokenManagerType, address tokenAddress) = ITokenManagerProxy(tokenManager_).getImplementationTypeAndTokenAddress();\n\n        /// @dev Track the flow amount being received via the message\n        ITokenManager(tokenManager_).addFlowIn(amount);\n\n        (bool success, bytes memory data) = tokenHandler.delegatecall(\n            abi.encodeWithSelector(ITokenHandler.giveToken.selector, tokenManagerType, tokenAddress, tokenManager_, to, amount)\n        );\n        if (!success) revert GiveTokenFailed(data);\n        amount = abi.decode(data, (uint256));\n\n        return (amount, tokenAddress);\n    }\n}\n"
      },
      "contracts/interfaces/IAddressTracker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IInterchainAddressTracker } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IInterchainAddressTracker.sol';\n\n/**\n * @title IAddressTracker Interface\n * @notice This interface allows setting and removing a trusted address for a specific chain.\n * @dev Extends the IInterchainAddressTracker interface.\n */\ninterface IAddressTracker is IInterchainAddressTracker {\n    /**\n     * @notice Sets the trusted address for the specified chain.\n     * @param chain Chain name to be trusted.\n     * @param address_ Trusted address to be added for the chain.\n     */\n    function setTrustedAddress(string memory chain, string memory address_) external;\n\n    /**\n     * @notice Remove the trusted address of the chain.\n     * @param chain Chain name to remove the trusted address for.\n     */\n    function removeTrustedAddress(string calldata chain) external;\n}\n"
      },
      "contracts/interfaces/IBaseTokenManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IBaseTokenManager\n * @notice This contract is defines the base token manager interface implemented by all token managers.\n */\ninterface IBaseTokenManager {\n    /**\n     * @notice A function that returns the token id.\n     */\n    function interchainTokenId() external view returns (bytes32);\n\n    /**\n     * @notice A function that should return the address of the token.\n     * Must be overridden in the inheriting contract.\n     * @return address address of the token.\n     */\n    function tokenAddress() external view returns (address);\n\n    /**\n     * @notice A function that should return the token address from the init params.\n     */\n    function getTokenAddressFromParams(bytes calldata params) external pure returns (address);\n}\n"
      },
      "contracts/interfaces/IFlowLimit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title FlowLimit Interface\n * @notice Interface for flow limit logic for interchain token transfers.\n */\ninterface IFlowLimit {\n    error FlowLimitExceeded(uint256 limit, uint256 flowAmount, address tokenManager);\n\n    event FlowLimitSet(bytes32 indexed tokenId, address operator, uint256 flowLimit_);\n\n    /**\n     * @notice Returns the current flow limit.\n     * @return flowLimit_ The current flow limit value.\n     */\n    function flowLimit() external view returns (uint256 flowLimit_);\n\n    /**\n     * @notice Returns the current flow out amount.\n     * @return flowOutAmount_ The current flow out amount.\n     */\n    function flowOutAmount() external view returns (uint256 flowOutAmount_);\n\n    /**\n     * @notice Returns the current flow in amount.\n     * @return flowInAmount_ The current flow in amount.\n     */\n    function flowInAmount() external view returns (uint256 flowInAmount_);\n}\n"
      },
      "contracts/interfaces/IInterchainTokenDeployer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IInterchainTokenDeployer\n * @notice This interface is used to deploy new instances of the InterchainTokenProxy contract.\n */\ninterface IInterchainTokenDeployer {\n    error AddressZero();\n    error TokenDeploymentFailed();\n\n    /**\n     * @notice Returns the interchain token implementation address.\n     * @return address The interchain token implementation address.\n     */\n    function implementationAddress() external view returns (address);\n\n    /**\n     * @notice Returns the interchain token deployment address.\n     * @param salt The deployment salt.\n     * @return tokenAddress The token address.\n     */\n    function deployedAddress(bytes32 salt) external view returns (address tokenAddress);\n\n    /**\n     * @notice Deploys a new instance of the InterchainTokenProxy contract.\n     * @param salt The salt used by Create3Deployer.\n     * @param tokenId tokenId of the token.\n     * @param minter Address of the minter.\n     * @param name Name of the token.\n     * @param symbol Symbol of the token.\n     * @param decimals Decimals of the token.\n     * @return tokenAddress Address of the deployed token.\n     */\n    function deployInterchainToken(\n        bytes32 salt,\n        bytes32 tokenId,\n        address minter,\n        string calldata name,\n        string calldata symbol,\n        uint8 decimals\n    ) external returns (address tokenAddress);\n}\n"
      },
      "contracts/interfaces/IInterchainTokenExecutable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IInterchainTokenExecutable\n * @notice Contracts should implement this interface to accept calls from the InterchainTokenService.\n */\ninterface IInterchainTokenExecutable {\n    /**\n     * @notice This will be called after the tokens are sent to this contract.\n     * @dev Execution should revert unless the msg.sender is the InterchainTokenService\n     * @param commandId The unique message id for the call.\n     * @param sourceChain The name of the source chain.\n     * @param sourceAddress The address that sent the contract call.\n     * @param data The data to be processed.\n     * @param tokenId The tokenId of the token manager managing the token.\n     * @param token The address of the token.\n     * @param amount The amount of tokens that were sent.\n     * @return bytes32 Hash indicating success of the execution.\n     */\n    function executeWithInterchainToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        bytes calldata sourceAddress,\n        bytes calldata data,\n        bytes32 tokenId,\n        address token,\n        uint256 amount\n    ) external returns (bytes32);\n}\n"
      },
      "contracts/interfaces/IInterchainTokenExpressExecutable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IInterchainTokenExecutable } from './IInterchainTokenExecutable.sol';\n\n/**\n * @title IInterchainTokenExpressExecutable\n * @notice Contracts should implement this interface to accept express calls from the InterchainTokenService.\n */\ninterface IInterchainTokenExpressExecutable is IInterchainTokenExecutable {\n    /**\n     * @notice Executes express logic in the context of an interchain token transfer.\n     * @dev Only callable by the interchain token service.\n     * @param commandId The unique message id for the call.\n     * @param sourceChain The source chain of the token transfer.\n     * @param sourceAddress The source address of the token transfer.\n     * @param data The data associated with the token transfer.\n     * @param tokenId The token ID.\n     * @param token The token address.\n     * @param amount The amount of tokens to be transferred.\n     * @return bytes32 Hash indicating success of the express execution.\n     */\n    function expressExecuteWithInterchainToken(\n        bytes32 commandId,\n        string calldata sourceChain,\n        bytes calldata sourceAddress,\n        bytes calldata data,\n        bytes32 tokenId,\n        address token,\n        uint256 amount\n    ) external returns (bytes32);\n}\n"
      },
      "contracts/interfaces/IInterchainTokenService.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarValuedExpressExecutable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarValuedExpressExecutable.sol';\nimport { IMulticall } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IMulticall.sol';\nimport { IPausable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IPausable.sol';\nimport { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol';\n\nimport { ITransmitInterchainToken } from './ITransmitInterchainToken.sol';\nimport { ITokenManagerType } from './ITokenManagerType.sol';\nimport { ITokenManagerImplementation } from './ITokenManagerImplementation.sol';\nimport { IOperator } from './IOperator.sol';\nimport { IAddressTracker } from './IAddressTracker.sol';\n\n/**\n * @title IInterchainTokenService Interface\n * @notice Interface for the Interchain Token Service\n */\ninterface IInterchainTokenService is\n    ITransmitInterchainToken,\n    ITokenManagerType,\n    ITokenManagerImplementation,\n    IAxelarValuedExpressExecutable,\n    IOperator,\n    IPausable,\n    IMulticall,\n    IAddressTracker,\n    IUpgradable\n{\n    error InvalidTokenManagerImplementationType(address implementation);\n    error InvalidChainName();\n    error NotRemoteService();\n    error TokenManagerDoesNotExist(bytes32 tokenId);\n    error NotToken(address caller, address token);\n    error ExecuteWithInterchainTokenFailed(address contractAddress);\n    error ExpressExecuteWithInterchainTokenFailed(address contractAddress);\n    error GatewayToken();\n    error TokenManagerDeploymentFailed(bytes error);\n    error InterchainTokenDeploymentFailed(bytes error);\n    error InvalidMessageType(uint256 messageType);\n    error InvalidMetadataVersion(uint32 version);\n    error ExecuteWithTokenNotSupported();\n    error InvalidExpressMessageType(uint256 messageType);\n    error TakeTokenFailed(bytes data);\n    error GiveTokenFailed(bytes data);\n    error TokenHandlerFailed(bytes data);\n    error EmptyData();\n    error CannotDeploy(TokenManagerType);\n\n    event InterchainTransfer(\n        bytes32 indexed tokenId,\n        address indexed sourceAddress,\n        string destinationChain,\n        bytes destinationAddress,\n        uint256 amount,\n        bytes32 indexed dataHash\n    );\n    event InterchainTransferReceived(\n        bytes32 indexed commandId,\n        bytes32 indexed tokenId,\n        string sourceChain,\n        bytes sourceAddress,\n        address indexed destinationAddress,\n        uint256 amount,\n        bytes32 dataHash\n    );\n    event TokenManagerDeploymentStarted(\n        bytes32 indexed tokenId,\n        string destinationChain,\n        TokenManagerType indexed tokenManagerType,\n        bytes params\n    );\n    event InterchainTokenDeploymentStarted(\n        bytes32 indexed tokenId,\n        string tokenName,\n        string tokenSymbol,\n        uint8 tokenDecimals,\n        bytes minter,\n        string destinationChain\n    );\n    event TokenManagerDeployed(bytes32 indexed tokenId, address tokenManager, TokenManagerType indexed tokenManagerType, bytes params);\n    event InterchainTokenDeployed(\n        bytes32 indexed tokenId,\n        address tokenAddress,\n        address indexed minter,\n        string name,\n        string symbol,\n        uint8 decimals\n    );\n    event InterchainTokenIdClaimed(bytes32 indexed tokenId, address indexed deployer, bytes32 indexed salt);\n\n    /**\n     * @notice Returns the address of the token manager deployer contract.\n     * @return tokenManagerDeployerAddress The address of the token manager deployer contract.\n     */\n    function tokenManagerDeployer() external view returns (address tokenManagerDeployerAddress);\n\n    /**\n     * @notice Returns the address of the interchain token deployer contract.\n     * @return interchainTokenDeployerAddress The address of the interchain token deployer contract.\n     */\n    function interchainTokenDeployer() external view returns (address interchainTokenDeployerAddress);\n\n    /**\n     * @notice Returns the address of TokenManager implementation.\n     * @return tokenManagerAddress_ The address of the token manager contract.\n     */\n    function tokenManager() external view returns (address tokenManagerAddress_);\n\n    /**\n     * @notice Returns the address of TokenHandler implementation.\n     * @return tokenHandlerAddress The address of the token handler contract.\n     */\n    function tokenHandler() external view returns (address tokenHandlerAddress);\n\n    /**\n     * @notice Returns the address of the interchain token factory.\n     * @return address The address of the interchain token factory.\n     */\n    function interchainTokenFactory() external view returns (address);\n\n    /**\n     * @notice Returns the hash of the chain name.\n     * @return bytes32 The hash of the chain name.\n     */\n    function chainNameHash() external view returns (bytes32);\n\n    /**\n     * @notice Returns the address of the token manager associated with the given tokenId.\n     * @param tokenId The tokenId of the token manager.\n     * @return tokenManagerAddress_ The address of the token manager.\n     */\n    function tokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_);\n\n    /**\n     * @notice Returns the address of the valid token manager associated with the given tokenId.\n     * @param tokenId The tokenId of the token manager.\n     * @return tokenManagerAddress_ The address of the valid token manager.\n     */\n    function validTokenManagerAddress(bytes32 tokenId) external view returns (address tokenManagerAddress_);\n\n    /**\n     * @notice Returns the address of the token that an existing tokenManager points to.\n     * @param tokenId The tokenId of the token manager.\n     * @return tokenAddress The address of the token.\n     */\n    function validTokenAddress(bytes32 tokenId) external view returns (address tokenAddress);\n\n    /**\n     * @notice Returns the address of the interchain token associated with the given tokenId.\n     * @param tokenId The tokenId of the interchain token.\n     * @return tokenAddress The address of the interchain token.\n     */\n    function interchainTokenAddress(bytes32 tokenId) external view returns (address tokenAddress);\n\n    /**\n     * @notice Returns the custom tokenId associated with the given operator and salt.\n     * @param operator_ The operator address.\n     * @param salt The salt used for token id calculation.\n     * @return tokenId The custom tokenId associated with the operator and salt.\n     */\n    function interchainTokenId(address operator_, bytes32 salt) external view returns (bytes32 tokenId);\n\n    /**\n     * @notice Deploys a custom token manager contract on a remote chain.\n     * @param salt The salt used for token manager deployment.\n     * @param destinationChain The name of the destination chain.\n     * @param tokenManagerType The type of token manager. Cannot be NATIVE_INTERCHAIN_TOKEN.\n     * @param params The deployment parameters.\n     * @param gasValue The gas value for deployment.\n     * @return tokenId The tokenId associated with the token manager.\n     */\n    function deployTokenManager(\n        bytes32 salt,\n        string calldata destinationChain,\n        TokenManagerType tokenManagerType,\n        bytes calldata params,\n        uint256 gasValue\n    ) external payable returns (bytes32 tokenId);\n\n    /**\n     * @notice Deploys and registers an interchain token on a remote chain.\n     * @param salt The salt used for token deployment.\n     * @param destinationChain The name of the destination chain. Use '' for this chain.\n     * @param name The name of the interchain tokens.\n     * @param symbol The symbol of the interchain tokens.\n     * @param decimals The number of decimals for the interchain tokens.\n     * @param minter The minter data for mint/burn operations.\n     * @param gasValue The gas value for deployment.\n     * @return tokenId The tokenId corresponding to the deployed InterchainToken.\n     */\n    function deployInterchainToken(\n        bytes32 salt,\n        string calldata destinationChain,\n        string memory name,\n        string memory symbol,\n        uint8 decimals,\n        bytes memory minter,\n        uint256 gasValue\n    ) external payable returns (bytes32 tokenId);\n\n    /**\n     * @notice Initiates an interchain transfer of a specified token to a destination chain.\n     * @param tokenId The unique identifier of the token to be transferred.\n     * @param destinationChain The destination chain to send the tokens to.\n     * @param destinationAddress The address on the destination chain to send the tokens to.\n     * @param amount The amount of tokens to be transferred.\n     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).\n     */\n    function interchainTransfer(\n        bytes32 tokenId,\n        string calldata destinationChain,\n        bytes calldata destinationAddress,\n        uint256 amount,\n        bytes calldata metadata,\n        uint256 gasValue\n    ) external payable;\n\n    /**\n     * @notice Initiates an interchain call contract with interchain token to a destination chain.\n     * @param tokenId The unique identifier of the token to be transferred.\n     * @param destinationChain The destination chain to send the tokens to.\n     * @param destinationAddress The address on the destination chain to send the tokens to.\n     * @param amount The amount of tokens to be transferred.\n     * @param data Additional data to be passed along with the transfer.\n     */\n    function callContractWithInterchainToken(\n        bytes32 tokenId,\n        string calldata destinationChain,\n        bytes calldata destinationAddress,\n        uint256 amount,\n        bytes calldata data,\n        uint256 gasValue\n    ) external payable;\n\n    /**\n     * @notice Sets the flow limits for multiple tokens.\n     * @param tokenIds An array of tokenIds.\n     * @param flowLimits An array of flow limits corresponding to the tokenIds.\n     */\n    function setFlowLimits(bytes32[] calldata tokenIds, uint256[] calldata flowLimits) external;\n\n    /**\n     * @notice Returns the flow limit for a specific token.\n     * @param tokenId The tokenId of the token.\n     * @return flowLimit_ The flow limit for the token.\n     */\n    function flowLimit(bytes32 tokenId) external view returns (uint256 flowLimit_);\n\n    /**\n     * @notice Returns the total amount of outgoing flow for a specific token.\n     * @param tokenId The tokenId of the token.\n     * @return flowOutAmount_ The total amount of outgoing flow for the token.\n     */\n    function flowOutAmount(bytes32 tokenId) external view returns (uint256 flowOutAmount_);\n\n    /**\n     * @notice Returns the total amount of incoming flow for a specific token.\n     * @param tokenId The tokenId of the token.\n     * @return flowInAmount_ The total amount of incoming flow for the token.\n     */\n    function flowInAmount(bytes32 tokenId) external view returns (uint256 flowInAmount_);\n\n    /**\n     * @notice Allows the owner to pause/unpause the token service.\n     * @param paused whether to pause or unpause.\n     */\n    function setPauseStatus(bool paused) external;\n}\n"
      },
      "contracts/interfaces/IOperator.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IRolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IRolesBase.sol';\n\n/**\n * @title IOperator Interface\n * @notice An interface for a contract module which provides a basic access control mechanism, where\n * there is an account (a operator) that can be granted exclusive access to specific functions.\n */\ninterface IOperator is IRolesBase {\n    /**\n     * @notice Change the operator of the contract.\n     * @dev Can only be called by the current operator.\n     * @param operator_ The address of the new operator.\n     */\n    function transferOperatorship(address operator_) external;\n\n    /**\n     * @notice Proposed a change of the operator of the contract.\n     * @dev Can only be called by the current operator.\n     * @param operator_ The address of the new operator.\n     */\n    function proposeOperatorship(address operator_) external;\n\n    /**\n     * @notice Accept a proposed change of operatorship.\n     * @dev Can only be called by the proposed operator.\n     * @param fromOperator The previous operator of the contract.\n     */\n    function acceptOperatorship(address fromOperator) external;\n\n    /**\n     * @notice Query if an address is a operator.\n     * @param addr The address to query for.\n     * @return bool Boolean value representing whether or not the address is an operator.\n     */\n    function isOperator(address addr) external view returns (bool);\n}\n"
      },
      "contracts/interfaces/ITokenHandler.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITokenHandler Interface\n * @notice This interface is responsible for handling tokens before initiating an interchain token transfer, or after receiving one.\n */\ninterface ITokenHandler {\n    error UnsupportedTokenManagerType(uint256 tokenManagerType);\n\n    /**\n     * @notice This function gives token to a specified address from the token manager.\n     * @param tokenManagerType The token manager type.\n     * @param tokenAddress The address of the token to give.\n     * @param tokenManager The address of the token manager.\n     * @param to The address to give tokens to.\n     * @param amount The amount of tokens to give.\n     * @return uint256 The amount of token actually given, which could be different for certain token type.\n     */\n    function giveToken(\n        uint256 tokenManagerType,\n        address tokenAddress,\n        address tokenManager,\n        address to,\n        uint256 amount\n    ) external payable returns (uint256);\n\n    /**\n     * @notice This function takes token from a specified address to the token manager.\n     * @param tokenManagerType The token manager type.\n     * @param tokenAddress The address of the token to give.\n     * @param tokenManager The address of the token manager.\n     * @param from The address to take tokens from.\n     * @param amount The amount of token to take.\n     * @return uint256 The amount of token actually taken, which could be different for certain token type.\n     */\n    function takeToken(\n        uint256 tokenManagerType,\n        address tokenAddress,\n        address tokenManager,\n        address from,\n        uint256 amount\n    ) external payable returns (uint256);\n\n    /**\n     * @notice This function transfers token from and to a specified address.\n     * @param tokenManagerType The token manager type.\n     * @param tokenAddress the address of the token to give.\n     * @param from The address to transfer tokens from.\n     * @param to The address to transfer tokens to.\n     * @param amount The amount of token to transfer.\n     * @return uint256 The amount of token actually transferred, which could be different for certain token type.\n     */\n    function transferTokenFrom(\n        uint256 tokenManagerType,\n        address tokenAddress,\n        address from,\n        address to,\n        uint256 amount\n    ) external payable returns (uint256);\n}\n"
      },
      "contracts/interfaces/ITokenManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IImplementation } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IImplementation.sol';\n\nimport { IBaseTokenManager } from './IBaseTokenManager.sol';\nimport { IOperator } from './IOperator.sol';\nimport { IFlowLimit } from './IFlowLimit.sol';\n\n/**\n * @title ITokenManager Interface\n * @notice This contract is responsible for managing tokens, such as setting locking token balances, or setting flow limits, for interchain transfers.\n */\ninterface ITokenManager is IBaseTokenManager, IOperator, IFlowLimit, IImplementation {\n    error TokenLinkerZeroAddress();\n    error NotService(address caller);\n    error TakeTokenFailed();\n    error GiveTokenFailed();\n    error NotToken(address caller);\n    error ZeroAddress();\n    error AlreadyFlowLimiter(address flowLimiter);\n    error NotFlowLimiter(address flowLimiter);\n    error NotSupported();\n\n    /**\n     * @notice Returns implementation type of this token manager.\n     * @return uint256 The implementation type of this token manager.\n     */\n    function implementationType() external view returns (uint256);\n\n    function addFlowIn(uint256 amount) external;\n\n    function addFlowOut(uint256 amount) external;\n\n    /**\n     * @notice This function adds a flow limiter for this TokenManager.\n     * @dev Can only be called by the operator.\n     * @param flowLimiter the address of the new flow limiter.\n     */\n    function addFlowLimiter(address flowLimiter) external;\n\n    /**\n     * @notice This function removes a flow limiter for this TokenManager.\n     * @dev Can only be called by the operator.\n     * @param flowLimiter the address of an existing flow limiter.\n     */\n    function removeFlowLimiter(address flowLimiter) external;\n\n    /**\n     * @notice Query if an address is a flow limiter.\n     * @param addr The address to query for.\n     * @return bool Boolean value representing whether or not the address is a flow limiter.\n     */\n    function isFlowLimiter(address addr) external view returns (bool);\n\n    /**\n     * @notice This function sets the flow limit for this TokenManager.\n     * @dev Can only be called by the flow limiters.\n     * @param flowLimit_ The maximum difference between the tokens flowing in and/or out at any given interval of time (6h).\n     */\n    function setFlowLimit(uint256 flowLimit_) external;\n\n    /**\n     * @notice A function to renew approval to the service if we need to.\n     */\n    function approveService() external;\n\n    /**\n     * @notice Getter function for the parameters of a lock/unlock TokenManager.\n     * @dev This function will be mainly used by frontends.\n     * @param operator_ The operator of the TokenManager.\n     * @param tokenAddress_ The token to be managed.\n     * @return params_ The resulting params to be passed to custom TokenManager deployments.\n     */\n    function params(bytes calldata operator_, address tokenAddress_) external pure returns (bytes memory params_);\n\n    /**\n     * @notice External function to allow the service to mint tokens through the tokenManager\n     * @dev This function should revert if called by anyone but the service.\n     * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager.\n     * @param to The recipient.\n     * @param amount The amount to mint.\n     */\n    function mintToken(address tokenAddress_, address to, uint256 amount) external;\n\n    /**\n     * @notice External function to allow the service to burn tokens through the tokenManager\n     * @dev This function should revert if called by anyone but the service.\n     * @param tokenAddress_ The address of the token, since its cheaper to pass it in instead of reading it as the token manager.\n     * @param from The address to burn the token from.\n     * @param amount The amount to burn.\n     */\n    function burnToken(address tokenAddress_, address from, uint256 amount) external;\n}\n"
      },
      "contracts/interfaces/ITokenManagerDeployer.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITokenManagerDeployer Interface\n * @notice This interface is used to deploy new instances of the TokenManagerProxy contract.\n */\ninterface ITokenManagerDeployer {\n    error AddressZero();\n    error TokenManagerDeploymentFailed();\n\n    /**\n     * @notice Deploys a new instance of the TokenManagerProxy contract.\n     * @param tokenId The token ID.\n     * @param implementationType Token manager implementation type.\n     * @param params Additional parameters used in the setup of the token manager.\n     * @return tokenManager Address of the deployed tokenManager.\n     */\n    function deployTokenManager(\n        bytes32 tokenId,\n        uint256 implementationType,\n        bytes calldata params\n    ) external payable returns (address tokenManager);\n}\n"
      },
      "contracts/interfaces/ITokenManagerImplementation.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITokenManagerImplementation Interface\n * @notice Interface for returning the token manager implementation type.\n */\ninterface ITokenManagerImplementation {\n    /**\n     * @notice Returns the implementation address for a given token manager type.\n     * @param tokenManagerType The type of token manager.\n     * @return tokenManagerAddress_ The address of the token manager implementation.\n     */\n    function tokenManagerImplementation(uint256 tokenManagerType) external view returns (address tokenManagerAddress_);\n}\n"
      },
      "contracts/interfaces/ITokenManagerProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IProxy } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IProxy.sol';\n\n/**\n * @title ITokenManagerProxy Interface\n * @notice This interface is for a proxy for token manager contracts.\n */\ninterface ITokenManagerProxy is IProxy {\n    error ZeroAddress();\n\n    /**\n     * @notice Returns implementation type of this token manager.\n     * @return uint256 The implementation type of this token manager.\n     */\n    function implementationType() external view returns (uint256);\n\n    /**\n     * @notice Returns the interchain token ID of the token manager.\n     * @return bytes32 The interchain token ID of the token manager.\n     */\n    function interchainTokenId() external view returns (bytes32);\n\n    /**\n     * @notice Returns token address that this token manager manages.\n     * @return address The token address.\n     */\n    function tokenAddress() external view returns (address);\n\n    /**\n     * @notice Returns implementation type and token address.\n     * @return uint256 The implementation type.\n     * @return address The token address.\n     */\n    function getImplementationTypeAndTokenAddress() external view returns (uint256, address);\n}\n"
      },
      "contracts/interfaces/ITokenManagerType.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITokenManagerType Interface\n * @notice A simple interface that defines all the token manager types.\n */\ninterface ITokenManagerType {\n    enum TokenManagerType {\n        NATIVE_INTERCHAIN_TOKEN, // This type is reserved for interchain tokens deployed by ITS, and can't be used by custom token managers.\n        MINT_BURN_FROM, // The token will be minted/burned on transfers. The token needs to give mint permission to the token manager, but burning happens via an approval.\n        LOCK_UNLOCK, // The token will be locked/unlocked at the token manager.\n        LOCK_UNLOCK_FEE, // The token will be locked/unlocked at the token manager, which will account for any fee-on-transfer behaviour.\n        MINT_BURN // The token will be minted/burned on transfers. The token needs to give mint and burn permission to the token manager.\n    }\n}\n"
      },
      "contracts/interfaces/ITransmitInterchainToken.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title ITransmitInterchainToken Interface\n * @notice Interface for transmiting interchain tokens via the interchain token service\n */\ninterface ITransmitInterchainToken {\n    /**\n     * @notice Transmit an interchain transfer for the given tokenId.\n     * @dev Only callable by a token registered under a tokenId.\n     * @param tokenId The tokenId of the token (which must be the msg.sender).\n     * @param sourceAddress The address where the token is coming from.\n     * @param destinationChain The name of the chain to send tokens to.\n     * @param destinationAddress The destinationAddress for the interchainTransfer.\n     * @param amount The amount of token to give.\n     * @param metadata Optional metadata for the call for additional effects (such as calling a destination contract).\n     */\n    function transmitInterchainTransfer(\n        bytes32 tokenId,\n        address sourceAddress,\n        string calldata destinationChain,\n        bytes memory destinationAddress,\n        uint256 amount,\n        bytes calldata metadata\n    ) external payable;\n}\n"
      },
      "contracts/utils/Operator.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { RolesBase } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/utils/RolesBase.sol';\n\nimport { IOperator } from '../interfaces/IOperator.sol';\n\nimport { RolesConstants } from './RolesConstants.sol';\n\n/**\n * @title Operator Contract\n * @notice A contract module which provides a basic access control mechanism, where\n * there is an account (a operator) that can be granted exclusive access to\n * specific functions.\n * @dev This module is used through inheritance.\n */\ncontract Operator is IOperator, RolesBase, RolesConstants {\n    /**\n     * @notice Internal function that stores the new operator address in the correct storage slot\n     * @param operator The address of the new operator\n     */\n    function _addOperator(address operator) internal {\n        _addRole(operator, uint8(Roles.OPERATOR));\n    }\n\n    /**\n     * @notice Change the operator of the contract.\n     * @dev Can only be called by the current operator.\n     * @param operator The address of the new operator.\n     */\n    function transferOperatorship(address operator) external onlyRole(uint8(Roles.OPERATOR)) {\n        _transferRole(msg.sender, operator, uint8(Roles.OPERATOR));\n    }\n\n    /**\n     * @notice Propose a change of the operator of the contract.\n     * @dev Can only be called by the current operator.\n     * @param operator The address of the new operator.\n     */\n    function proposeOperatorship(address operator) external onlyRole(uint8(Roles.OPERATOR)) {\n        _proposeRole(msg.sender, operator, uint8(Roles.OPERATOR));\n    }\n\n    /**\n     * @notice Accept a proposed change of operatorship.\n     * @dev Can only be called by the proposed operator.\n     * @param fromOperator The previous operator of the contract.\n     */\n    function acceptOperatorship(address fromOperator) external {\n        _acceptRole(fromOperator, msg.sender, uint8(Roles.OPERATOR));\n    }\n\n    /**\n     * @notice Query if an address is a operator.\n     * @param addr The address to query for.\n     * @return bool Boolean value representing whether or not the address is an operator.\n     */\n    function isOperator(address addr) external view returns (bool) {\n        return hasRole(addr, uint8(Roles.OPERATOR));\n    }\n}\n"
      },
      "contracts/utils/RolesConstants.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title RolesConstants\n * @notice This contract contains enum values representing different contract roles.\n */\ncontract RolesConstants {\n    enum Roles {\n        MINTER,\n        OPERATOR,\n        FLOW_LIMITER\n    }\n}\n"
      }
    },
    "settings": {
      "evmVersion": "london",
      "optimizer": {
        "enabled": true,
        "runs": 1000,
        "details": {
          "peephole": true,
          "inliner": true,
          "jumpdestRemover": true,
          "orderLiterals": true,
          "deduplicate": true,
          "cse": true,
          "constantOptimizer": true,
          "yul": true,
          "yulDetails": {
            "stackAllocation": true
          }
        }
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}