{"ok":true,"contract":{"address":"0x8a10e7110b72e5bd12967dd32513f2e5d9f13a00","contract_name":"UniversalSwapAndBridgeV3","deployed":"1769781071","fund":"0","fund_usd":"0.00000000","native_balance":"0","network":"ethereum","first_seen":"1771581604","verified":true,"is_proxy":false,"implementation_address":null,"proxy_contract_name":"UniversalSwapAndBridgeV3","implementation_contract_name":null,"deploy_tx_hash":"0xf4d7f00d175214ca89479a297e94b4e562d62af835f5ac1036fa19e02557c914","deployer_address":"0x673236c3e2ca96c6d3ce787c333a43673958dc7e","deploy_block_number":"24348097","deployed_at_timestamp":"1769781071","deployed_at":"2026-01-30T13:51:11.000Z","confidence":"precise","fetched_at":"2026-02-20T10:23:00.496Z","source_code":"// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/executable/AxelarExecutable.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';\nimport { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';\n\n/**\n * @title AxelarExecutable\n * @dev Abstract contract to be inherited by contracts that need to execute cross-chain commands via Axelar's Gateway.\n * It implements the IAxelarExecutable interface.\n */\nabstract contract AxelarExecutable is IAxelarExecutable {\n    /// @dev Reference to the Axelar Gateway contract.\n    address internal immutable gatewayAddress;\n\n    /**\n     * @dev Contract constructor that sets the Axelar Gateway address.\n     * Reverts if the provided address is the zero address.\n     * @param gateway_ The address of the Axelar Gateway contract.\n     */\n    constructor(address gateway_) {\n        if (gateway_ == address(0)) revert InvalidAddress();\n\n        gatewayAddress = gateway_;\n    }\n\n    /**\n     * @notice Executes the cross-chain command after validating it with the Axelar Gateway.\n     * @dev This function ensures the call is approved by Axelar Gateway before execution.\n     * It uses a hash of the payload for validation and internally calls _execute for the actual command execution.\n     * Reverts if the validation fails.\n     * @param commandId The unique identifier of the cross-chain message being executed.\n     * @param sourceChain The name of the source chain from which the message originated.\n     * @param sourceAddress The address on the source chain that sent the message.\n     * @param payload The payload of the message payload.\n     */\n    function execute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external virtual {\n        bytes32 payloadHash = keccak256(payload);\n\n        if (!gateway().validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))\n            revert NotApprovedByGateway();\n\n        _execute(commandId, sourceChain, sourceAddress, payload);\n    }\n\n    /**\n     * @dev Internal virtual function to be overridden by child contracts to execute the command.\n     * It allows child contracts to define their custom command execution logic.\n     * @param commandId The identifier of the command to execute.\n     * @param sourceChain The name of the source chain from which the command originated.\n     * @param sourceAddress The address on the source chain that sent the command.\n     * @param payload The payload of the command to be executed.\n     */\n    function _execute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) internal virtual;\n\n    /**\n     * @notice Returns the address of the AxelarGateway contract.\n     * @return The Axelar Gateway instance.\n     */\n    function gateway() public view returns (IAxelarGateway) {\n        return IAxelarGateway(gatewayAddress);\n    }\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/executable/AxelarExecutableWithToken.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarGatewayWithToken } from '../interfaces/IAxelarGatewayWithToken.sol';\nimport { IAxelarExecutableWithToken } from '../interfaces/IAxelarExecutableWithToken.sol';\nimport { AxelarExecutable } from './AxelarExecutable.sol';\n\n/**\n * @title AxelarExecutableWithToken\n * @dev Abstract contract to be inherited by contracts that need to execute cross-chain commands involving tokens via Axelar's Gateway.\n * It extends AxelarExecutable and implements the IAxelarExecutableWithToken interface.\n */\nabstract contract AxelarExecutableWithToken is IAxelarExecutableWithToken, AxelarExecutable {\n    /**\n     * @dev Contract constructor that sets the Axelar Gateway With Token address and initializes AxelarExecutable.\n     * @param gateway_ The address of the Axelar Gateway With Token contract.\n     */\n    constructor(address gateway_) AxelarExecutable(gateway_) {}\n\n    /**\n     * @notice Executes the cross-chain command with token transfer after validating it with the Axelar Gateway.\n     * @dev This function ensures the call is approved by Axelar Gateway With Token before execution.\n     * It uses a hash of the payload for validation and calls _executeWithToken for the actual command execution.\n     * Reverts if the validation fails.\n     * @param commandId The unique identifier of the cross-chain message being executed.\n     * @param sourceChain The name of the source chain from which the message originated.\n     * @param sourceAddress The address on the source chain that sent the message.\n     * @param payload The payload of the message payload.\n     * @param tokenSymbol The symbol of the token to be transferred.\n     * @param amount The amount of tokens to be transferred.\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 virtual {\n        bytes32 payloadHash = keccak256(payload);\n\n        if (\n            !gatewayWithToken().validateContractCallAndMint(\n                commandId,\n                sourceChain,\n                sourceAddress,\n                payloadHash,\n                tokenSymbol,\n                amount\n            )\n        ) revert NotApprovedByGateway();\n\n        _executeWithToken(commandId, sourceChain, sourceAddress, payload, tokenSymbol, amount);\n    }\n\n    /**\n     * @dev Internal virtual function to be overridden by child contracts to execute the command with token transfer.\n     * It allows child contracts to define their custom command execution logic involving tokens.\n     * @param commandId The unique identifier of the cross-chain message being executed.\n     * @param sourceChain The name of the source chain from which the message originated.\n     * @param sourceAddress The address on the source chain that sent the message.\n     * @param payload The payload of the message payload.\n     * @param tokenSymbol The symbol of the token to be transferred.\n     * @param amount The amount of tokens to be transferred.\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    ) internal virtual;\n\n    /**\n     * @notice Returns the address of the IAxelarGatewayWithToken contract.\n     * @return The Axelar Gateway with Token instance.\n     */\n    function gatewayWithToken() internal view returns (IAxelarGatewayWithToken) {\n        return IAxelarGatewayWithToken(gatewayAddress);\n    }\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IAxelarExecutable.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarGateway } from './IAxelarGateway.sol';\n\n/**\n * @title IAxelarExecutable\n * @dev Interface for a contract that is executable by Axelar Gateway's cross-chain message passing.\n * It defines a standard interface to execute commands sent from another chain.\n */\ninterface IAxelarExecutable {\n    /**\n     * @dev Thrown when a function is called with an invalid address.\n     */\n    error InvalidAddress();\n\n    /**\n     * @dev Thrown when the call is not approved by the Axelar Gateway.\n     */\n    error NotApprovedByGateway();\n\n    /**\n     * @notice Returns the address of the AxelarGateway contract.\n     * @return The Axelar Gateway contract associated with this executable contract.\n     */\n    function gateway() external view returns (IAxelarGateway);\n\n    /**\n     * @notice Executes the specified command sent from another chain.\n     * @dev This function is called by the Axelar Gateway to carry out cross-chain commands.\n     * Reverts if the call is not approved by the gateway or other checks fail.\n     * @param commandId The identifier of the command to execute.\n     * @param sourceChain The name of the source chain from where the command originated.\n     * @param sourceAddress The address on the source chain that sent the command.\n     * @param payload The payload of the command to be executed. This typically includes the function selector and encoded arguments.\n     */\n    function execute(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes calldata payload\n    ) external;\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IAxelarExecutableWithToken.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarExecutable } from './IAxelarExecutable.sol';\n\n/**\n * @title IAxelarExecutableWithToken\n * @dev Interface for a contract that can execute commands from Axelar Gateway involving token transfers.\n * It extends IAxelarExecutable to include token-related functionality.\n */\ninterface IAxelarExecutableWithToken is IAxelarExecutable {\n    /**\n     * @notice Executes the specified command sent from another chain and includes a token transfer.\n     * @dev This function should be implemented to handle incoming commands that include token transfers.\n     * It will be called by an implementation of `IAxelarGatewayWithToken`.\n     * @param commandId The identifier of the command to execute.\n     * @param sourceChain The name of the source chain from where the command originated.\n     * @param sourceAddress The address on the source chain that sent the command.\n     * @param payload The payload of the command to be executed.\n     * @param tokenSymbol The symbol of the token to be transferred with this command.\n     * @param amount The amount of tokens to be transferred with this command.\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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IAxelarGasService.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { GasInfo } from '../types/GasEstimationTypes.sol';\nimport { IInterchainGasEstimation } from './IInterchainGasEstimation.sol';\nimport { IUpgradable } from './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 IInterchainGasEstimation, IUpgradable {\n    error InvalidAddress();\n    error NotCollector();\n    error InvalidAmounts();\n    error InvalidGasUpdates();\n    error InvalidParams();\n    error InsufficientGasPayment(uint256 required, uint256 provided);\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 for any type of contract execution on a destination chain.\n     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.\n     * @dev If estimateOnChain is true, the function will estimate the gas cost and revert if the payment is insufficient.\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 executionGasLimit The gas limit for the contract call\n     * @param estimateOnChain Flag to enable on-chain gas estimation\n     * @param refundAddress The address where refunds, if any, should be sent\n     * @param params Additional parameters for gas payment. This can be left empty for normal contract call payments.\n     */\n    function payGas(\n        address sender,\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        uint256 executionGasLimit,\n        bool estimateOnChain,\n        address refundAddress,\n        bytes calldata params\n    ) external payable;\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 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 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 Updates the gas price for a specific chain.\n     * @dev This function is called by the gas oracle to update the gas prices for a specific chains.\n     * @param chains Array of chain names\n     * @param gasUpdates Array of gas updates\n     */\n    function updateGasInfo(string[] calldata chains, GasInfo[] calldata gasUpdates) external;\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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IAxelarGateway.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title IAxelarGateway\n * @dev Interface for the Axelar Gateway that supports general message passing and contract call execution.\n */\ninterface IAxelarGateway {\n    /**\n     * @notice Emitted when a contract call is made through the gateway.\n     * @dev Logs the attempt to call a contract on another chain.\n     * @param sender The address of the sender who initiated the contract call.\n     * @param destinationChain The name of the destination chain.\n     * @param destinationContractAddress The address of the contract on the destination chain.\n     * @param payloadHash The keccak256 hash of the sent payload data.\n     * @param payload The payload data used for the contract call.\n     */\n    event ContractCall(\n        address indexed sender,\n        string destinationChain,\n        string destinationContractAddress,\n        bytes32 indexed payloadHash,\n        bytes payload\n    );\n\n    /**\n     * @notice Sends a contract call to another chain.\n     * @dev Initiates a cross-chain contract call through the gateway to the specified destination chain and contract.\n     * @param destinationChain The name of the destination chain.\n     * @param contractAddress The address of the contract on the destination chain.\n     * @param payload The payload data to be used in the contract call.\n     */\n    function callContract(\n        string calldata destinationChain,\n        string calldata contractAddress,\n        bytes calldata payload\n    ) external;\n\n    /**\n     * @notice Checks if a contract call is approved.\n     * @dev Determines whether a given contract call, identified by the commandId and payloadHash, is approved.\n     * @param commandId The identifier of the command to check.\n     * @param sourceChain The name of the source chain.\n     * @param sourceAddress The address of the sender on the source chain.\n     * @param contractAddress The address of the contract where the call will be executed.\n     * @param payloadHash The keccak256 hash of the payload data.\n     * @return True if the contract call is approved, false otherwise.\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    /**\n     * @notice Validates and approves a contract call.\n     * @dev Validates the given contract call information and marks it as approved if valid.\n     * @param commandId The identifier of the command to validate.\n     * @param sourceChain The name of the source chain.\n     * @param sourceAddress The address of the sender on the source chain.\n     * @param payloadHash The keccak256 hash of the payload data.\n     * @return True if the contract call is validated and approved, false otherwise.\n     */\n    function validateContractCall(\n        bytes32 commandId,\n        string calldata sourceChain,\n        string calldata sourceAddress,\n        bytes32 payloadHash\n    ) external returns (bool);\n\n    /**\n     * @notice Checks if a command has been executed.\n     * @dev Determines whether a command, identified by the commandId, has been executed.\n     * @param commandId The identifier of the command to check.\n     * @return True if the command has been executed, false otherwise.\n     */\n    function isCommandExecuted(bytes32 commandId) external view returns (bool);\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IAxelarGatewayWithToken.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { IAxelarGateway } from './IAxelarGateway.sol';\n\n/**\n * @title IAxelarGatewayWithToken\n * @dev Interface for the Axelar Gateway that supports cross-chain token transfers coupled with general message passing.\n * It extends IAxelarGateway to include token-related functionality.\n */\ninterface IAxelarGatewayWithToken is IAxelarGateway {\n    /**\n     * @notice Emitted when a token is sent to another chain.\n     * @dev Logs the attempt to send tokens to a recipient on another chain.\n     * @param sender The address of the sender who initiated the token transfer.\n     * @param destinationChain The name of the destination chain.\n     * @param destinationAddress The address of the recipient on the destination chain.\n     * @param symbol The symbol of the token being transferred.\n     * @param amount The amount of the tokens being transferred.\n     */\n    event TokenSent(\n        address indexed sender,\n        string destinationChain,\n        string destinationAddress,\n        string symbol,\n        uint256 amount\n    );\n\n    /**\n     * @notice Emitted when a contract call is made through the gateway along with a token transfer.\n     * @dev Logs the attempt to call a contract on another chain with an associated token transfer.\n     * @param sender The address of the sender who initiated the contract call with token.\n     * @param destinationChain The name of the destination chain.\n     * @param destinationContractAddress The address of the contract on the destination chain.\n     * @param payloadHash The keccak256 hash of the sent payload data.\n     * @param payload The payload data used for the contract call.\n     * @param symbol The symbol of the token being transferred.\n     * @param amount The amount of the tokens being transferred.\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    /**\n     * @notice Emitted when a contract call with a token minting is approved.\n     * @dev Logs the approval of a contract call that originated from another chain and involves a token minting process.\n     * @param commandId The identifier of the command to execute.\n     * @param sourceChain The name of the source chain from whence the command came.\n     * @param sourceAddress The address of the sender on the source chain.\n     * @param contractAddress The address of the contract where the call will be executed.\n     * @param payloadHash The keccak256 hash of the approved payload data.\n     * @param symbol The symbol of the token being minted.\n     * @param amount The amount of the tokens being minted.\n     * @param sourceTxHash The hash of the source transaction on the source chain.\n     * @param sourceEventIndex The index of the event in the source transaction logs.\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    /**\n     * @notice Sends tokens to another chain.\n     * @dev Initiates a cross-chain token transfer through the gateway to the specified destination chain and recipient.\n     * @param destinationChain The name of the destination chain.\n     * @param destinationAddress The address of the recipient on the destination chain.\n     * @param symbol The symbol of the token being transferred.\n     * @param amount The amount of the tokens being transferred.\n     */\n    function sendToken(\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        string calldata symbol,\n        uint256 amount\n    ) external;\n\n    /**\n     * @notice Makes a contract call on another chain with an associated token transfer.\n     * @dev Initiates a cross-chain contract call through the gateway that includes a token transfer to the specified contract on the destination chain.\n     * @param destinationChain The name of the destination chain.\n     * @param contractAddress The address of the contract on the destination chain.\n     * @param payload The payload data to be used in the contract call.\n     * @param symbol The symbol of the token being transferred.\n     * @param amount The amount of the tokens being transferred.\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    /**\n     * @notice Checks if a contract call with token minting is approved.\n     * @dev Determines whether a given contract call, identified by the commandId and payloadHash, involving token minting is approved.\n     * @param commandId The identifier of the command to check.\n     * @param sourceChain The name of the source chain.\n     * @param sourceAddress The address of the sender on the source chain.\n     * @param contractAddress The address of the contract where the call will be executed.\n     * @param payloadHash The keccak256 hash of the payload data.\n     * @param symbol The symbol of the token associated with the minting.\n     * @param amount The amount of the tokens to be minted.\n     * @return True if the contract call with token minting is approved, false otherwise.\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    /**\n     * @notice Validates and approves a contract call with token minting.\n     * @dev Validates the given contract call information and marks it as approved if valid. It also involves the minting of tokens.\n     * @param commandId The identifier of the command to validate.\n     * @param sourceChain The name of the source chain.\n     * @param sourceAddress The address of the sender on the source chain.\n     * @param payloadHash The keccak256 hash of the payload data.\n     * @param symbol The symbol of the token associated with the minting.\n     * @param amount The amount of the tokens to be minted.\n     * @return True if the contract call with token minting is validated and approved, false otherwise.\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     * @notice Retrieves the address of a token given its symbol.\n     * @dev Gets the contract address of the token registered with the given symbol.\n     * @param symbol The symbol of the token to retrieve the address for.\n     * @return The contract address of the token corresponding to the given symbol.\n     */\n    function tokenAddresses(string memory symbol) external view returns (address);\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IContractIdentifier.sol\n// 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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IImplementation.sol\n// 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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IInterchainGasEstimation.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { GasEstimationType, GasInfo } from '../types/GasEstimationTypes.sol';\n\n/**\n * @title IInterchainGasEstimation Interface\n * @notice This is an interface for the InterchainGasEstimation contract\n * which allows for estimating gas fees for cross-chain communication on the Axelar network.\n */\ninterface IInterchainGasEstimation {\n    error UnsupportedEstimationType(GasEstimationType gasEstimationType);\n\n    /**\n     * @notice Event emitted when the gas price for a specific chain is updated.\n     * @param chain The name of the chain\n     * @param info The gas info for the chain\n     */\n    event GasInfoUpdated(string chain, GasInfo info);\n\n    /**\n     * @notice Returns the gas price for a specific chain.\n     * @param chain The name of the chain\n     * @return gasInfo The gas info for the chain\n     */\n    function getGasInfo(string calldata chain) external view returns (GasInfo memory);\n\n    /**\n     * @notice Estimates the gas fee for a cross-chain contract call.\n     * @param destinationChain Axelar registered name of the destination chain\n     * @param destinationAddress Destination contract address being called\n     * @param executionGasLimit The gas limit to be used for the destination contract execution,\n     *        e.g. pass in 200k if your app consumes needs upto 200k for this contract call\n     * @param params Additional parameters for the gas estimation\n     * @return gasEstimate The cross-chain gas estimate, in terms of source chain's native gas token that should be forwarded to the gas service.\n     */\n    function estimateGasFee(\n        string calldata destinationChain,\n        string calldata destinationAddress,\n        bytes calldata payload,\n        uint256 executionGasLimit,\n        bytes calldata params\n    ) external view returns (uint256 gasEstimate);\n}\n\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IOwnable.sol\n// 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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/interfaces/IUpgradable.sol\n// 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\n\n// File: npm/@axelar-network/axelar-gmp-sdk-solidity@6.0.6/contracts/types/GasEstimationTypes.sol\n// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @title GasEstimationType\n * @notice This enum represents the gas estimation types for different chains.\n */\nenum GasEstimationType {\n    Default,\n    OptimismEcotone,\n    OptimismBedrock,\n    Arbitrum,\n    Scroll\n}\n\n/**\n * @title GasInfo\n * @notice This struct represents the gas pricing information for a specific chain.\n * @dev Smaller uint types are used for efficient struct packing to save storage costs.\n */\nstruct GasInfo {\n    /// @dev Custom gas pricing rule, such as L1 data fee on L2s\n    uint64 gasEstimationType;\n    /// @dev Scalar value needed for specific gas estimation types, expected to be less than 1e10\n    uint64 l1FeeScalar;\n    /// @dev Axelar base fee for cross-chain message approval on destination, in terms of source native gas token\n    uint128 axelarBaseFee;\n    /// @dev Gas price of destination chain, in terms of the source chain token, i.e dest_gas_price * dest_token_market_price / src_token_market_price\n    uint128 relativeGasPrice;\n    /// @dev Needed for specific gas estimation types. Blob base fee of destination chain, in terms of the source chain token, i.e dest_blob_base_fee * dest_token_market_price / src_token_market_price\n    uint128 relativeBlobBaseFee;\n    /// @dev Axelar express fee for express execution, in terms of source chain token\n    uint128 expressFee;\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/access/Ownable.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev 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 * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/security/ReentrancyGuard.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    constructor() {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/token/ERC20/extensions/IERC20Permit.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/token/ERC20/IERC20.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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    /**\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 `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, 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 `from` to `to` 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(address from, address to, uint256 amount) external returns (bool);\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/token/ERC20/utils/SafeERC20.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/utils/Address.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n\n\n// File: npm/@openzeppelin/contracts@4.9.6/utils/Context.sol\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n\n\n// File: project/contracts/libs/OFTComposeMsgCodec.sol\n// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.20;\r\n\r\nlibrary OFTComposeMsgCodec {\r\n    // Offset constants for decoding composed messages\r\n    uint8 private constant NONCE_OFFSET = 8;\r\n    uint8 private constant SRC_EID_OFFSET = 12;\r\n    uint8 private constant AMOUNT_LD_OFFSET = 44;\r\n    uint8 private constant COMPOSE_FROM_OFFSET = 76;\r\n\r\n    /**\r\n     * @dev Encodes a OFT composed message.\r\n     * @param _nonce The nonce value.\r\n     * @param _srcEid The source endpoint ID.\r\n     * @param _amountLD The amount in local decimals.\r\n     * @param _composeMsg The composed message.\r\n     * @return _msg The encoded Composed message.\r\n     */\r\n    function encode(\r\n        uint64 _nonce,\r\n        uint32 _srcEid,\r\n        uint256 _amountLD,\r\n        bytes memory _composeMsg // 0x[composeFrom][composeMsg]\r\n    ) internal pure returns (bytes memory _msg) {\r\n        _msg = abi.encodePacked(_nonce, _srcEid, _amountLD, _composeMsg);\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves the nonce for the composed message.\r\n     * @param _msg The message.\r\n     * @return The nonce value.\r\n     */\r\n    function nonce(bytes calldata _msg) internal pure returns (uint64) {\r\n        return uint64(bytes8(_msg[:NONCE_OFFSET]));\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves the source endpoint ID for the composed message.\r\n     * @param _msg The message.\r\n     * @return The source endpoint ID.\r\n     */\r\n    function srcEid(bytes calldata _msg) internal pure returns (uint32) {\r\n        return uint32(bytes4(_msg[NONCE_OFFSET:SRC_EID_OFFSET]));\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves the amount in local decimals from the composed message.\r\n     * @param _msg The message.\r\n     * @return The amount in local decimals.\r\n     */\r\n    function amountLD(bytes calldata _msg) internal pure returns (uint256) {\r\n        return uint256(bytes32(_msg[SRC_EID_OFFSET:AMOUNT_LD_OFFSET]));\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves the composeFrom value from the composed message.\r\n     * @param _msg The message.\r\n     * @return The composeFrom value.\r\n     */\r\n    function composeFrom(bytes calldata _msg) internal pure returns (bytes32) {\r\n        return bytes32(_msg[AMOUNT_LD_OFFSET:COMPOSE_FROM_OFFSET]);\r\n    }\r\n\r\n    /**\r\n     * @dev Retrieves the composed message.\r\n     * @param _msg The message.\r\n     * @return The composed message.\r\n     */\r\n    function composeMsg(bytes calldata _msg) internal pure returns (bytes memory) {\r\n        return _msg[COMPOSE_FROM_OFFSET:];\r\n    }\r\n\r\n    /**\r\n     * @dev Converts an address to bytes32.\r\n     * @param _addr The address to convert.\r\n     * @return The bytes32 representation of the address.\r\n     */\r\n    function addressToBytes32(address _addr) internal pure returns (bytes32) {\r\n        return bytes32(uint256(uint160(_addr)));\r\n    }\r\n\r\n    /**\r\n     * @dev Converts bytes32 to an address.\r\n     * @param _b The bytes32 value to convert.\r\n     * @return The address representation of bytes32.\r\n     */\r\n    function bytes32ToAddress(bytes32 _b) internal pure returns (address) {\r\n        return address(uint160(uint256(_b)));\r\n    }\r\n}\r\n\n\n// File: project/contracts/MultiChainBridgeV3.sol\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\r\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\nimport \"@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGatewayWithToken.sol\";\r\nimport \"@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol\";\r\nimport \"@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutableWithToken.sol\";\r\n\r\ninterface IERC20Decimals {\r\n    function decimals() external view returns (uint8);\r\n}\r\n\r\ninterface ISwapRouter {\r\n    struct ExactInputParams {\r\n        bytes path;\r\n        address recipient;\r\n        uint256 deadline;\r\n        uint256 amountIn;\r\n        uint256 amountOutMinimum;\r\n    }\r\n    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\r\n}\r\n\r\ncontract UniversalSwapAndBridgeV3 is AxelarExecutableWithToken, ReentrancyGuard, Ownable {\r\n    \r\n    IAxelarGasService public gasService;\r\n    ISwapRouter public router;\r\n\r\n    address public USDC;\r\n    address public USDT;\r\n    address public axlUSDC;\r\n    address public axlUSDT;\r\n    string public sourceChain;\r\n    bytes32 public sourceChainHash;\r\n\r\n    using SafeERC20 for IERC20;\r\n    // swap path map: from token -> to token -> encoded UniswapV3 path\r\n    mapping(address => mapping(address => bytes)) public swapPaths;\r\n    // precomputed hash for the string \"Ethereum\" to avoid recomputing keccak256\r\n    bytes32 private constant ETHEREUM_HASH = keccak256(abi.encodePacked(\"Ethereum\"));\r\n\r\n\r\n    // Convert an address to its ASCII hex string representation (0x prefixed)\r\n    function addressToString(address _addr) internal pure returns (string memory) {\r\n        bytes20 value = bytes20(uint160(_addr));\r\n        bytes memory buffer = new bytes(42);\r\n        buffer[0] = '0';\r\n        buffer[1] = 'x';\r\n        for (uint i = 0; i < 20; i++) {\r\n            uint8 b = uint8(value[i]);\r\n            uint8 hi = b / 16;\r\n            uint8 lo = b - 16 * hi;\r\n            buffer[2 + i * 2] = char(hi);\r\n            buffer[3 + i * 2] = char(lo);\r\n        }\r\n        return string(buffer);\r\n    }\r\n\r\n    function char(uint8 b) internal pure returns (bytes1) {\r\n        if (b < 10) return bytes1(b + 48);\r\n        else return bytes1(b + 87);\r\n    }\r\n\r\n    constructor(\r\n        address gateway_,\r\n        address gasService_,\r\n        address router_,\r\n        address usdc_,\r\n        address usdt_,\r\n        address axlUSDC_,\r\n        address axlUSDT_,\r\n        address[] memory pathFromTokens,\r\n        address[] memory pathToTokens,\r\n        bytes[] memory pathBytes,\r\n        uint256 slippageBps_,\r\n        string memory sourceChain_\r\n    ) AxelarExecutableWithToken(gateway_) {\r\n        require(gateway_ != address(0), \"gateway_ zero\");\r\n        require(gasService_ != address(0), \"gasService_ zero\");\r\n        require(router_ != address(0), \"router_ zero\");\r\n        require(usdc_ != address(0), \"usdc_ zero\");\r\n        require(usdt_ != address(0), \"usdt_ zero\");\r\n        require(axlUSDC_ != address(0), \"axlUSDC_ zero\");\r\n        require(axlUSDT_ != address(0), \"axlUSDT_ zero\");\r\n\r\n        gasService = IAxelarGasService(gasService_);\r\n        router = ISwapRouter(router_);\r\n        USDC = usdc_;\r\n        USDT = usdt_;\r\n        axlUSDC = axlUSDC_;\r\n        axlUSDT = axlUSDT_;\r\n        // Initialize swap paths if provided\r\n        if (pathFromTokens.length > 0) {\r\n            require(pathFromTokens.length == pathToTokens.length && pathFromTokens.length == pathBytes.length, \"paths length mismatch\");\r\n            for (uint256 i = 0; i < pathFromTokens.length; i++) {\r\n                swapPaths[pathFromTokens[i]][pathToTokens[i]] = pathBytes[i];\r\n            }\r\n        }\r\n\r\n        sourceChain = sourceChain_;\r\n        sourceChainHash = keccak256(bytes(sourceChain_));\r\n\r\n        require(slippageBps_ <= 10000, \"bps>10000\");\r\n        slippageBps = slippageBps_;\r\n    }\r\n\r\n    // Slippage in basis points (100 = 1%). Immutable after construction.\r\n    uint256 public immutable slippageBps;\r\n\r\n    event SentGMP(string dstChain, string dstContract, string dstWallet, string tokenSymbol, uint256 amount, address sender);\r\n    event ReceivedGMP(bytes32 commandId, string sourceChain, string sourceAddress, address targetRecipient, string tokenSymbol, uint256 amount, bool swapped, address finalAsset, uint256 finalAmount);\r\n    event UnsupportedExecute(bytes32 commandId, string srcChain, string srcAddress);\r\n\r\n\r\n    // One-shot: gas+GMP (gasNativeValue). msg.value must equal sum.\r\n    function sendTokenViaGMPLayerZero(\r\n        address tokenIn,\r\n        uint256 amountIn,\r\n        uint256 minAxlUSDC,\r\n        string calldata dstChain,\r\n        string calldata dstContract,\r\n        string calldata dstWallet,\r\n        string calldata srcAddress,\r\n        string calldata jsonPayload,\r\n        uint256 gasNativeValue\r\n    ) external payable {\r\n        require(msg.value == gasNativeValue, \"Value mismatch\");\r\n\r\n        require(amountIn > 0, \"amountIn must be > 0\");\r\n        require(bytes(dstChain).length > 0, \"dstChain empty\");\r\n        require(bytes(dstContract).length > 0, \"dstContract empty\");\r\n        require(bytes(dstWallet).length > 0, \"dstWallet empty\");\r\n        require(tokenIn != address(0), \"tokenIn zero\");\r\n        // delegate to internal nonReentrant implementation\r\n        bytes memory executeMsgPayload = abi.encode(srcAddress, jsonPayload);\r\n\r\n        _sendTokenViaGMP_impl(tokenIn, amountIn, minAxlUSDC, dstChain, dstContract, dstWallet, executeMsgPayload, bytes(\"\"), block.timestamp + 1 hours, gasNativeValue);\r\n    }\r\n\r\n    // One-shot: gas+GMP (gasNativeValue). msg.value must equal sum.\r\n    function sendTokenViaGMP(\r\n        address tokenIn,\r\n        uint256 amountIn,\r\n        uint256 minAxlUSDC,\r\n        string calldata dstChain,\r\n        string calldata dstContract,\r\n        string calldata dstWallet,\r\n        bytes calldata executeMsgPayload,\r\n        bytes calldata path,\r\n        uint256 deadline,\r\n        uint256 gasNativeValue\r\n    ) external payable {\r\n        require(msg.value == gasNativeValue, \"Value mismatch\");\r\n\r\n        require(amountIn > 0, \"amountIn must be > 0\");\r\n        require(deadline >= block.timestamp, \"deadline passed\");\r\n        require(bytes(dstChain).length > 0, \"dstChain empty\");\r\n        require(bytes(dstContract).length > 0, \"dstContract empty\");\r\n        require(bytes(dstWallet).length > 0, \"dstWallet empty\");\r\n        require(tokenIn != address(0), \"tokenIn zero\");\r\n        // delegate to internal nonReentrant implementation\r\n        _sendTokenViaGMP_impl(tokenIn, amountIn, minAxlUSDC, dstChain, dstContract, dstWallet, executeMsgPayload, path, deadline, gasNativeValue);\r\n    }\r\n\r\n    function _ensureApproval(IERC20 token, address spender, uint256 amount) internal {\r\n        // Standard approach for tokens like USDT that don't follow ERC20 return strictly\r\n        // and to handle the safeApprove(0) requirement.\r\n        token.safeApprove(spender, 0);\r\n        token.safeApprove(spender, amount);\r\n    }\r\n\r\n    // internal implementation guarded by nonReentrant\r\n    function _sendTokenViaGMP_impl(\r\n        address tokenIn,\r\n        uint256 amountIn,\r\n        uint256 minAxlUSDC,\r\n        string calldata dstChain,\r\n        string calldata dstContract,\r\n        string calldata dstWallet,\r\n        bytes memory executeMsgPayload,\r\n        bytes memory path,\r\n        uint256 deadline,\r\n        uint256 gasNativeValue\r\n    ) internal nonReentrant {\r\n        // 1. Pull tokens from user\r\n        IERC20(tokenIn).safeTransferFrom(msg.sender, address(this), amountIn);\r\n\r\n        uint256 amountToSend;\r\n        address tokenAddressVal;\r\n        string memory tokenSymbolStr;\r\n\r\n        // 2. Handle Swap / Normalization Logic\r\n        if (sourceChainHash == ETHEREUM_HASH) {\r\n            if (tokenIn == USDC || tokenIn == USDT) {\r\n                // Critical Fix: Ensure direct transfers also respect slippage requirements\r\n                require(amountIn >= minAxlUSDC, \"Slippage too high\");\r\n                amountToSend = amountIn;\r\n                tokenAddressVal = tokenIn;\r\n                tokenSymbolStr = (tokenIn == USDC) ? \"USDC\" : \"USDT\";\r\n            } else {\r\n                require(path.length > 0, \"empty swap path\");\r\n                _ensureApproval(IERC20(tokenIn), address(router), amountIn);\r\n                \r\n                uint256 balanceBefore = IERC20(USDC).balanceOf(address(this));\r\n                router.exactInput(ISwapRouter.ExactInputParams({\r\n                    path: path,\r\n                    recipient: address(this),\r\n                    deadline: deadline,\r\n                    amountIn: amountIn,\r\n                    amountOutMinimum: minAxlUSDC\r\n                }));\r\n\r\n                amountToSend = IERC20(USDC).balanceOf(address(this)) - balanceBefore;\r\n                require(amountToSend >= minAxlUSDC, \"Slippage too high\");\r\n                \r\n                tokenAddressVal = USDC;\r\n                tokenSymbolStr = \"USDC\";\r\n            }\r\n        } else {\r\n            if (tokenIn == axlUSDC || tokenIn == axlUSDT) {\r\n                amountToSend = amountIn;\r\n                tokenAddressVal = tokenIn;\r\n                tokenSymbolStr = tokenIn==axlUSDC?\"axlUSDC\":\"axlUSDT\";\r\n            } else {\r\n                require(path.length > 0, \"empty swap path\");\r\n                _ensureApproval(IERC20(tokenIn), address(router), amountIn);\r\n                \r\n                uint256 balanceBefore = IERC20(axlUSDC).balanceOf(address(this));\r\n                router.exactInput(ISwapRouter.ExactInputParams({\r\n                    path: path,\r\n                    recipient: address(this),\r\n                    deadline: deadline,\r\n                    amountIn: amountIn,\r\n                    amountOutMinimum: minAxlUSDC\r\n                }));\r\n\r\n                amountToSend = IERC20(axlUSDC).balanceOf(address(this)) - balanceBefore;\r\n                require(amountToSend >= minAxlUSDC, \"Slippage too high\");\r\n                tokenAddressVal = axlUSDC;\r\n                tokenSymbolStr = \"axlUSDC\";\r\n            }\r\n            \r\n        }\r\n\r\n        require(tokenAddressVal != address(0), \"tokenAddressVal zero\");\r\n\r\n        // 3. Prepare GMP Payload\r\n        // Use the provided `executeMsgPayload` parameter as the 'payload'\r\n\r\n        string[] memory argumentNames = new string[](3);\r\n        argumentNames[0] = \"gonka_address\";\r\n        argumentNames[1] = \"source_chain\";\r\n        argumentNames[2] = \"payload\";\r\n\r\n        string[] memory abiTypes = new string[](3);\r\n        abiTypes[0] = \"string\";\r\n        abiTypes[1] = \"string\";\r\n        abiTypes[2] = \"bytes\";\r\n\r\n        bytes memory argValues = abi.encode(dstWallet, sourceChain, executeMsgPayload);\r\n\r\n        bytes memory gmpPayload = abi.encode(\r\n            \"receive_gmp\",\r\n            argumentNames,\r\n            abiTypes,\r\n            argValues\r\n        );\r\n\r\n        // Axelar version prefix 0x00000001\r\n        bytes memory finalPayload = abi.encodePacked(bytes4(0x00000001), gmpPayload);\r\n\r\n        // 4. Single Approval for Gateway and Execute Cross-Chain Call\r\n        _ensureApproval(IERC20(tokenAddressVal), address(gateway()), amountToSend);\r\n\r\n        gasService.payNativeGasForContractCallWithToken{value: gasNativeValue}(\r\n            address(this),\r\n            dstChain,\r\n            dstContract,\r\n            finalPayload,\r\n            tokenSymbolStr,\r\n            amountToSend,\r\n            msg.sender\r\n        );\r\n\r\n        IAxelarGatewayWithToken(address(gateway())).callContractWithToken(dstChain, dstContract, finalPayload, tokenSymbolStr, amountToSend);\r\n    }\r\n    \r\n \r\n    // --- swap path management (owner only) ---\r\n    function setSwapPath(address from, address to, bytes calldata path) external onlyOwner {\r\n        swapPaths[from][to] = path;\r\n    }\r\n\r\n    function batchSetSwapPaths(address[] calldata froms, address[] calldata tos, bytes[] calldata paths) external onlyOwner {\r\n        require(froms.length == tos.length && froms.length == paths.length, \"length mismatch\");\r\n        for (uint256 i = 0; i < froms.length; i++) {\r\n            swapPaths[froms[i]][tos[i]] = paths[i];\r\n        }\r\n    }\r\n\r\n    function getSwapPath(address from, address to) external view returns (bytes memory) {\r\n        return swapPaths[from][to];\r\n    }\r\n\r\n    // convert 20-byte slice to address\r\n    function _toAddress(bytes memory _bs, uint256 _start) internal pure returns (address addr) {\r\n        require(_bs.length >= _start + 20, \"slice out of range\");\r\n        assembly {\r\n            addr := shr(96, mload(add(add(_bs, 0x20), _start)))\r\n        }\r\n    }\r\n\r\n    // parse UniswapV3-style path into tokens array\r\n    function parseV3Path(bytes memory path) public pure returns (address[] memory tokens) {\r\n        require(path.length >= 20, \"path too short\");\r\n        require((path.length - 20) % 23 == 0, \"invalid path length\");\r\n        uint256 tokenCount = 1 + (path.length - 20) / 23;\r\n        tokens = new address[](tokenCount);\r\n        uint256 offset = 0;\r\n        for (uint256 i = 0; i < tokenCount; i++) {\r\n            tokens[i] = _toAddress(path, offset);\r\n            offset += 20;\r\n            if (i < tokenCount - 1) offset += 3; // skip fee\r\n        }\r\n    }\r\n\r\n    receive() external payable {}\r\n\r\n    // Update _execute signature\r\n    function _execute(\r\n        bytes32 commandId,\r\n        string calldata srcChain,\r\n        string calldata srcAddress,\r\n        bytes calldata\r\n    ) internal override {\r\n        emit UnsupportedExecute(commandId, srcChain, srcAddress);\r\n        revert(\"_execute not supported\");\r\n    }\r\n    // Handle incoming GMP with token\r\n    function _executeWithToken(\r\n        bytes32 commandId,\r\n        string calldata srcChain,\r\n        string calldata srcAddress,\r\n        bytes calldata payload,\r\n        string calldata tokenSymbol,\r\n        uint256 amount\r\n    ) internal override  {\r\n        // Decode payload: (targetRecipient, finalAsset)\r\n        (address targetRecipient, address finalAsset) = abi.decode(payload, (address, address));\r\n\r\n        // lookup stored path for this token pair\r\n        address tokenAddress = IAxelarGatewayWithToken(address(gateway())).tokenAddresses(tokenSymbol);\r\n        bytes memory path = swapPaths[tokenAddress][finalAsset];\r\n\r\n        bool swapped = false;\r\n        uint256 finalAmount = 0;\r\n\r\n        // If no path provided or finalAsset equals incoming token -> direct transfer\r\n        if (path.length == 0 || tokenAddress == finalAsset) {\r\n            IERC20(tokenAddress).safeTransfer(targetRecipient, amount);\r\n            finalAmount = amount;\r\n            swapped = false;\r\n            emit ReceivedGMP(commandId, srcChain, srcAddress, targetRecipient, tokenSymbol, amount, swapped, finalAsset, finalAmount);\r\n            return;\r\n        }\r\n\r\n        // validate path start and end tokens\r\n        address pathStart = _toAddress(path, 0);\r\n        address pathEnd = _toAddress(path, path.length - 20);\r\n        if (pathStart != tokenAddress || pathEnd != finalAsset) {\r\n            // mismatch -> fallback\r\n            IERC20(tokenAddress).safeTransfer(targetRecipient, amount);\r\n            emit ReceivedGMP(commandId, srcChain, srcAddress, targetRecipient, tokenSymbol, amount, false, finalAsset, amount);\r\n            return;\r\n        }\r\n\r\n        // Attempt swap, but fallback to direct transfer on failure\r\n        _ensureApproval(IERC20(tokenAddress), address(router), amount);\r\n\r\n        uint256 amountOutMinimum;\r\n        // Calculate expected amount by adjusting decimals; if decimals() call fails, use amount as-is\r\n        try IERC20Decimals(finalAsset).decimals() returns (uint8 dstDec) {\r\n            uint8 srcDec = IERC20Decimals(tokenAddress).decimals();\r\n            uint256 scaled;\r\n            if (dstDec >= srcDec) {\r\n                scaled = amount * (10 ** (dstDec - srcDec));\r\n            } else {\r\n                scaled = amount / (10 ** (srcDec - dstDec));\r\n            }\r\n            amountOutMinimum = (scaled * (10000 - slippageBps)) / 10000;\r\n        } catch {\r\n            amountOutMinimum = (amount * (10000 - slippageBps)) / 10000;\r\n        }\r\n\r\n        uint256 balanceBefore = IERC20(finalAsset).balanceOf(address(this));\r\n        try router.exactInput(ISwapRouter.ExactInputParams({\r\n            path: path,\r\n            recipient: address(this),\r\n            deadline: block.timestamp + 300,\r\n            amountIn: amount,\r\n            amountOutMinimum: amountOutMinimum\r\n        })) returns (uint256) {\r\n            finalAmount = IERC20(finalAsset).balanceOf(address(this)) - balanceBefore;\r\n            // send swapped asset to recipient\r\n            IERC20(finalAsset).safeTransfer(targetRecipient, finalAmount);\r\n            swapped = true;\r\n        } catch {\r\n            // swap failed -> send original token to recipient\r\n            IERC20(tokenAddress).safeTransfer(targetRecipient, amount);\r\n            finalAmount = amount;\r\n            swapped = false;\r\n        }\r\n\r\n        emit ReceivedGMP(commandId, srcChain, srcAddress, targetRecipient, tokenSymbol, amount, swapped, finalAsset, finalAmount);\r\n    }\r\n\r\n\r\n}\r\n\n\n// File: project/contracts/StargateProxyV2.sol\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\r\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\n// IMPORT: Official LayerZero V2 Codec (local copy due to Hardhat import issues)\r\nimport { OFTComposeMsgCodec } from \"./libs/OFTComposeMsgCodec.sol\";\r\nimport \"./MultiChainBridgeV3.sol\";\r\n\r\n// Formal interface for Stargate V2\r\ninterface ILayerZeroComposer {\r\n    function lzCompose(address _from, bytes32 _guid, bytes calldata _message, address _executor, bytes calldata _extraData) external payable;\r\n}\r\n\r\n// Structs required by Stargate V2\r\nstruct SendParam {\r\n    uint32 dstEid;\r\n    bytes32 to;\r\n    uint256 amountLD;\r\n    uint256 minAmountLD;\r\n    bytes extraOptions;\r\n    bytes composeMsg;\r\n    bytes oftCmd;\r\n}\r\n\r\nstruct MessagingFee {\r\n    uint256 nativeFee;\r\n    uint256 lzTokenFee;\r\n}\r\n\r\nstruct MessagingReceipt {\r\n    bytes32 guid;\r\n    uint64 nonce;\r\n    MessagingFee fee;\r\n}\r\n\r\ninterface IStargate {\r\n    function sendToken(SendParam calldata _sendParam, MessagingFee calldata _fee, address _refundAddress) external payable returns (MessagingReceipt memory, bytes memory, bytes memory);\r\n    function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory);\r\n    function token() external view returns (address);\r\n}\r\n\r\ncontract StargateProxyV2 is ILayerZeroComposer, Ownable {\r\n    using SafeERC20 for IERC20;\r\n\r\n    UniversalSwapAndBridgeV3 public immutable multiChainBridge;\r\n    \r\n    // Mainnet USDT address\r\n    address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;\r\n\r\n    // Event for tracking successful bridge\r\n    event ProxyBridgeExecuted(string dstChain, uint256 amount);\r\n    event EmergencyWithdraw(address indexed token, address indexed to, uint256 amount);\r\n\r\n    constructor(address payable _multiChainBridgeAddress) Ownable() {\r\n        multiChainBridge = UniversalSwapAndBridgeV3(_multiChainBridgeAddress);\r\n    }\r\n\r\n/**\r\n     * @notice Handles incoming composed messages from Stargate V2\r\n     */\r\n    function lzCompose(\r\n        address _from, \r\n        bytes32 /*_guid*/,\r\n        bytes calldata _message, \r\n        address /*_executor*/,\r\n        bytes calldata /*_extraData*/\r\n    ) external payable override {\r\n        // 1. Extract payload (removes 76-byte LZ/Stargate header)\r\n        bytes memory actualPayload = OFTComposeMsgCodec.composeMsg(_message);\r\n\r\n        (\r\n            string memory dstChain, \r\n            string memory dstContract, \r\n            string memory dstWallet, \r\n            string memory srcAddress, \r\n            string memory jsonPayload\r\n        ) = abi.decode(actualPayload, (string, string, string, string,string));\r\n        // 3. IDENTIFY TOKEN AND BALANCE\r\n        address tokenReceived = IStargate(_from).token();\r\n        uint256 amountReceived = IERC20(tokenReceived).balanceOf(address(this));\r\n        \r\n        require(amountReceived > 0, \"No tokens received\");\r\n\r\n        // 4. EXECUTE GMP BRIDGE\r\n        IERC20(tokenReceived).forceApprove(address(multiChainBridge), amountReceived);\r\n        \r\n        // We pass '0x' for path directly here since it is constant\r\n        multiChainBridge.sendTokenViaGMPLayerZero{value: msg.value}(\r\n            tokenReceived,\r\n            amountReceived,\r\n            (amountReceived * 9900) / 10000, // 1% Slippage\r\n            dstChain,\r\n            dstContract,\r\n            dstWallet,\r\n            srcAddress,\r\n            jsonPayload,\r\n            msg.value \r\n        );\r\n\r\n        emit ProxyBridgeExecuted(dstChain, amountReceived);\r\n    }\r\n    // --- EMERGENCY FUNCTIONS ---\r\n\r\n    function emergencyWithdrawNative(address payable _to, uint256 _amount) external onlyOwner {\r\n        uint256 contractBalance = address(this).balance;\r\n        uint256 withdrawAmount = _amount == 0 ? contractBalance : _amount;\r\n        require(withdrawAmount <= contractBalance, \"Insufficient balance\");\r\n        \r\n        (bool success, ) = _to.call{value: withdrawAmount}(\"\");\r\n        require(success, \"Native transfer failed\");\r\n        emit EmergencyWithdraw(address(0), _to, withdrawAmount);\r\n    }\r\n\r\n    function emergencyWithdrawToken(address _token, address _to, uint256 _amount) external onlyOwner {\r\n        IERC20 token = IERC20(_token);\r\n        uint256 contractBalance = token.balanceOf(address(this));\r\n        uint256 withdrawAmount = _amount == 0 ? contractBalance : _amount;\r\n        token.safeTransfer(_to, withdrawAmount);\r\n        emit EmergencyWithdraw(_token, _to, withdrawAmount);\r\n    }\r\n\r\n    function emergencyWithdrawUSDT(address _to, uint256 _amount) external onlyOwner {\r\n        IERC20 token = IERC20(USDT);\r\n        uint256 contractBalance = token.balanceOf(address(this));\r\n        uint256 withdrawAmount = _amount == 0 ? contractBalance : _amount;\r\n        token.safeTransfer(_to, withdrawAmount);\r\n        emit EmergencyWithdraw(USDT, _to, withdrawAmount);\r\n    }\r\n\r\n    receive() external payable {}\r\n}","source_code_hash":null,"compiler_version":"v0.8.32+commit.ebbd65e5","optimization_used":"1","runs":200,"abi":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"gateway_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"gasService_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"router_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"usdc_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"usdt_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"axlUSDC_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"axlUSDT_\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"pathFromTokens\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"pathToTokens\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"pathBytes\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"slippageBps_\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"sourceChain_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotApprovedByGateway\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"commandId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"sourceChain\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"sourceAddress\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"targetRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"swapped\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"finalAsset\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"finalAmount\",\"type\":\"uint256\"}],\"name\":\"ReceivedGMP\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"dstChain\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"dstContract\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"dstWallet\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SentGMP\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"commandId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"srcChain\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"srcAddress\",\"type\":\"string\"}],\"name\":\"UnsupportedExecute\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"USDC\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"USDT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"axlUSDC\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"axlUSDT\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"froms\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tos\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"paths\",\"type\":\"bytes[]\"}],\"name\":\"batchSetSwapPaths\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commandId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"sourceChain\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"sourceAddress\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commandId\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"sourceChain\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"sourceAddress\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"executeWithToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasService\",\"outputs\":[{\"internalType\":\"contract IAxelarGasService\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gateway\",\"outputs\":[{\"internalType\":\"contract IAxelarGateway\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"getSwapPath\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"path\",\"type\":\"bytes\"}],\"name\":\"parseV3Path\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"router\",\"outputs\":[{\"internalType\":\"contract ISwapRouter\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minAxlUSDC\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"dstChain\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"dstContract\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"dstWallet\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"executeMsgPayload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"path\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gasNativeValue\",\"type\":\"uint256\"}],\"name\":\"sendTokenViaGMP\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenIn\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountIn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minAxlUSDC\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"dstChain\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"dstContract\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"dstWallet\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"srcAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"jsonPayload\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"gasNativeValue\",\"type\":\"uint256\"}],\"name\":\"sendTokenViaGMPLayerZero\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"path\",\"type\":\"bytes\"}],\"name\":\"setSwapPath\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"slippageBps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceChain\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceChainHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"swapPaths\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]","contract_file_name":"project/contracts/MultiChainBridgeV3.sol","compiler_type":"solc-j","evm_version":"Default","constructor_arguments":"0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a50000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000001b81d678ffb9c0263b24a97847620c99d213eb14000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000","library":null,"license_type":null,"critical_count":0,"high_count":1,"medium_count":0,"low_count":0,"informational_count":0,"audit_status":"completed","audit_completed_at":"1779825111163","erc20_balances":[]}}