ETH Price: $1,793.14 (+10.15%)

Contract

0xE622B1D44F5061DB10ABa2594F1A8eb2DC1fC1d4
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AxelarGasService

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 1000 runs

Other Settings:
london EvmVersion
File 1 of 12 : AxelarGasService.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IERC20.sol';
import { SafeTokenTransfer, SafeTokenTransferFrom } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeTransfer.sol';
import { SafeNativeTransfer } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/SafeNativeTransfer.sol';
import { IAxelarGasService } from '../interfaces/IAxelarGasService.sol';
import { Upgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradable/Upgradable.sol';

/**
 * @title AxelarGasService
 * @notice This contract manages gas payments and refunds for cross-chain communication on the Axelar network.
 * @dev The owner address of this contract should be the microservice that pays for gas.
 * @dev Users pay gas for cross-chain calls, and the gasCollector can collect accumulated fees and/or refund users if needed.
 */
contract AxelarGasService is Upgradable, IAxelarGasService {
    using SafeTokenTransfer for IERC20;
    using SafeTokenTransferFrom for IERC20;
    using SafeNativeTransfer for address payable;

    address public immutable gasCollector;

    /**
     * @notice Constructs the AxelarGasService contract.
     * @param gasCollector_ The address of the gas collector
     */
    constructor(address gasCollector_) {
        gasCollector = gasCollector_;
    }

    /**
     * @notice Modifier that ensures the caller is the designated gas collector.
     */
    modifier onlyCollector() {
        if (msg.sender != gasCollector) revert NotCollector();

        _;
    }

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit GasPaidForContractCall(
            sender,
            destinationChain,
            destinationAddress,
            keccak256(payload),
            gasToken,
            gasFeeAmount,
            refundAddress
        );

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string memory symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit GasPaidForContractCallWithToken(
            sender,
            destinationChain,
            destinationAddress,
            keccak256(payload),
            symbol,
            amount,
            gasToken,
            gasFeeAmount,
            refundAddress
        );

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Pay for gas using native currency for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable override {
        emit NativeGasPaidForContractCall(sender, destinationChain, destinationAddress, keccak256(payload), msg.value, refundAddress);
    }

    /**
     * @notice Pay for gas using native currency for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable override {
        emit NativeGasPaidForContractCallWithToken(
            sender,
            destinationChain,
            destinationAddress,
            keccak256(payload),
            symbol,
            amount,
            msg.value,
            refundAddress
        );
    }

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit GasPaidForExpressCall(sender, destinationChain, destinationAddress, keccak256(payload), gasToken, gasFeeAmount, refundAddress);

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string memory symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit GasPaidForExpressCallWithToken(
            sender,
            destinationChain,
            destinationAddress,
            keccak256(payload),
            symbol,
            amount,
            gasToken,
            gasFeeAmount,
            refundAddress
        );

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Pay for gas using native currency for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable override {
        emit NativeGasPaidForExpressCall(sender, destinationChain, destinationAddress, keccak256(payload), msg.value, refundAddress);
    }

    /**
     * @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable override {
        emit NativeGasPaidForExpressCallWithToken(
            sender,
            destinationChain,
            destinationAddress,
            keccak256(payload),
            symbol,
            amount,
            msg.value,
            refundAddress
        );
    }

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit GasAdded(txHash, logIndex, gasToken, gasFeeAmount, refundAddress);

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Add additional gas payment using native currency after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable override {
        emit NativeGasAdded(txHash, logIndex, msg.value, refundAddress);
    }

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external override {
        emit ExpressGasAdded(txHash, logIndex, gasToken, gasFeeAmount, refundAddress);

        IERC20(gasToken).safeTransferFrom(msg.sender, address(this), gasFeeAmount);
    }

    /**
     * @notice Add additional gas payment using native currency after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable override {
        emit NativeExpressGasAdded(txHash, logIndex, msg.value, refundAddress);
    }

    /**
     * @notice Allows the gasCollector to collect accumulated fees from the contract.
     * @dev Use address(0) as the token address for native currency.
     * @param receiver The address to receive the collected fees
     * @param tokens Array of token addresses to be collected
     * @param amounts Array of amounts to be collected for each respective token address
     */
    function collectFees(
        address payable receiver,
        address[] calldata tokens,
        uint256[] calldata amounts
    ) external onlyCollector {
        if (receiver == address(0)) revert InvalidAddress();

        uint256 tokensLength = tokens.length;
        if (tokensLength != amounts.length) revert InvalidAmounts();

        for (uint256 i; i < tokensLength; i++) {
            address token = tokens[i];
            uint256 amount = amounts[i];
            if (amount == 0) revert InvalidAmounts();

            if (token == address(0)) {
                if (amount <= address(this).balance) receiver.safeNativeTransfer(amount);
            } else {
                // slither-disable-next-line calls-loop
                if (amount <= IERC20(token).balanceOf(address(this))) IERC20(token).safeTransfer(receiver, amount);
            }
        }
    }

    /**
     * @dev Deprecated refund function, kept for backward compatibility.
     */
    function refund(
        address payable receiver,
        address token,
        uint256 amount
    ) external onlyCollector {
        _refund(bytes32(0), 0, receiver, token, amount);
    }

    /**
     * @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.
     * @dev Only callable by the gasCollector.
     * @dev Use address(0) as the token address to refund native currency.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param receiver The address to receive the refund
     * @param token The token address to be refunded
     * @param amount The amount to refund
     */
    function refund(
        bytes32 txHash,
        uint256 logIndex,
        address payable receiver,
        address token,
        uint256 amount
    ) external onlyCollector {
        _refund(txHash, logIndex, receiver, token, amount);
    }

    /**
     * @dev Internal function to implement gas refund logic.
     */
    function _refund(
        bytes32 txHash,
        uint256 logIndex,
        address payable receiver,
        address token,
        uint256 amount
    ) private {
        if (receiver == address(0)) revert InvalidAddress();

        emit Refunded(txHash, logIndex, receiver, token, amount);

        if (token == address(0)) {
            receiver.safeNativeTransfer(amount);
        } else {
            IERC20(token).safeTransfer(receiver, amount);
        }
    }

    /**
     * @notice Returns a unique identifier for the contract.
     * @return bytes32 Hash of the contract identifier
     */
    function contractId() external pure returns (bytes32) {
        return keccak256('axelar-gas-service');
    }
}

File 2 of 12 : IContractIdentifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// General interface for upgradable contracts
interface IContractIdentifier {
    /**
     * @notice Returns the contract ID. It can be used as a check during upgrades.
     * @dev Meant to be overridden in derived contracts.
     * @return bytes32 The contract ID
     */
    function contractId() external pure returns (bytes32);
}

File 3 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    error InvalidAccount();

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 4 of 12 : IImplementation.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IContractIdentifier } from './IContractIdentifier.sol';

interface IImplementation is IContractIdentifier {
    error NotProxy();

    function setup(bytes calldata data) external;
}

File 5 of 12 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IOwnable Interface
 * @notice IOwnable is an interface that abstracts the implementation of a
 * contract with ownership control features. It's commonly used in upgradable
 * contracts and includes the functionality to get current owner, transfer
 * ownership, and propose and accept ownership.
 */
interface IOwnable {
    error NotOwner();
    error InvalidOwner();
    error InvalidOwnerAddress();

    event OwnershipTransferStarted(address indexed newOwner);
    event OwnershipTransferred(address indexed newOwner);

    /**
     * @notice Returns the current owner of the contract.
     * @return address The address of the current owner
     */
    function owner() external view returns (address);

    /**
     * @notice Returns the address of the pending owner of the contract.
     * @return address The address of the pending owner
     */
    function pendingOwner() external view returns (address);

    /**
     * @notice Transfers ownership of the contract to a new address
     * @param newOwner The address to transfer ownership to
     */
    function transferOwnership(address newOwner) external;

    /**
     * @notice Proposes to transfer the contract's ownership to a new address.
     * The new owner needs to accept the ownership explicitly.
     * @param newOwner The address to transfer ownership to
     */
    function proposeOwnership(address newOwner) external;

    /**
     * @notice Transfers ownership to the pending owner.
     * @dev Can only be called by the pending owner
     */
    function acceptOwnership() external;
}

File 6 of 12 : IUpgradable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IOwnable } from './IOwnable.sol';
import { IImplementation } from './IImplementation.sol';

// General interface for upgradable contracts
interface IUpgradable is IOwnable, IImplementation {
    error InvalidCodeHash();
    error InvalidImplementation();
    error SetupFailed();

    event Upgraded(address indexed newImplementation);

    function implementation() external view returns (address);

    function upgrade(
        address newImplementation,
        bytes32 newImplementationCodeHash,
        bytes calldata params
    ) external;
}

File 7 of 12 : SafeNativeTransfer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

error NativeTransferFailed();

/*
 * @title SafeNativeTransfer
 * @dev This library is used for performing safe native value transfers in Solidity by utilizing inline assembly.
 */
library SafeNativeTransfer {
    /*
     * @notice Perform a native transfer to a given address.
     * @param receiver The recipient address to which the amount will be sent.
     * @param amount The amount of native value to send.
     * @throws NativeTransferFailed error if transfer is not successful.
     */
    function safeNativeTransfer(address receiver, uint256 amount) internal {
        bool success;

        assembly {
            success := call(gas(), receiver, amount, 0, 0, 0, 0)
        }

        if (!success) revert NativeTransferFailed();
    }
}

File 8 of 12 : SafeTransfer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC20 } from '../interfaces/IERC20.sol';

error TokenTransferFailed();

/*
 * @title SafeTokenCall
 * @dev This library is used for performing safe token transfers.
 */
library SafeTokenCall {
    /*
     * @notice Make a safe call to a token contract.
     * @param token The token contract to interact with.
     * @param callData The function call data.
     * @throws TokenTransferFailed error if transfer of token is not successful.
     */
    function safeCall(IERC20 token, bytes memory callData) internal {
        (bool success, bytes memory returnData) = address(token).call(callData);
        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));

        if (!transferred || address(token).code.length == 0) revert TokenTransferFailed();
    }
}

/*
 * @title SafeTokenTransfer
 * @dev This library safely transfers tokens from the contract to a recipient.
 */
library SafeTokenTransfer {
    /*
     * @notice Transfer tokens to a recipient.
     * @param token The token contract.
     * @param receiver The recipient of the tokens.
     * @param amount The amount of tokens to transfer.
     */
    function safeTransfer(
        IERC20 token,
        address receiver,
        uint256 amount
    ) internal {
        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount));
    }
}

/*
 * @title SafeTokenTransferFrom
 * @dev This library helps to safely transfer tokens on behalf of a token holder.
 */
library SafeTokenTransferFrom {
    /*
     * @notice Transfer tokens on behalf of a token holder.
     * @param token The token contract.
     * @param from The address of the token holder.
     * @param to The address the tokens are to be sent to.
     * @param amount The amount of tokens to be transferred.
     */
    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        SafeTokenCall.safeCall(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount));
    }
}

File 9 of 12 : Implementation.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IImplementation } from '../interfaces/IImplementation.sol';

/**
 * @title Implementation
 * @notice This contract serves as a base for other contracts and enforces a proxy-first access restriction.
 * @dev Derived contracts must implement the setup function.
 */
abstract contract Implementation is IImplementation {
    address private immutable implementationAddress;

    /**
     * @dev Contract constructor that sets the implementation address to the address of this contract.
     */
    constructor() {
        implementationAddress = address(this);
    }

    /**
     * @dev Modifier to require the caller to be the proxy contract.
     * Reverts if the caller is the current contract (i.e., the implementation contract itself).
     */
    modifier onlyProxy() {
        if (implementationAddress == address(this)) revert NotProxy();
        _;
    }

    /**
     * @notice Initializes contract parameters.
     * This function is intended to be overridden by derived contracts.
     * The overriding function must have the onlyProxy modifier.
     * @param params The parameters to be used for initialization
     */
    function setup(bytes calldata params) external virtual;
}

File 10 of 12 : Upgradable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IImplementation } from '../interfaces/IImplementation.sol';
import { IUpgradable } from '../interfaces/IUpgradable.sol';
import { Ownable } from '../utils/Ownable.sol';
import { Implementation } from './Implementation.sol';

/**
 * @title Upgradable Contract
 * @notice This contract provides an interface for upgradable smart contracts and includes the functionality to perform upgrades.
 */
abstract contract Upgradable is Ownable, Implementation, IUpgradable {
    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /**
     * @notice Constructor sets the implementation address to the address of the contract itself
     * @dev This is used in the onlyProxy modifier to prevent certain functions from being called directly
     * on the implementation contract itself.
     * @dev The owner is initially set as address(1) because the actual owner is set within the proxy. It is not
     * set as the zero address because Ownable is designed to throw an error for ownership transfers to the zero address.
     */
    constructor() Ownable(address(1)) {}

    /**
     * @notice Returns the address of the current implementation
     * @return implementation_ Address of the current implementation
     */
    function implementation() public view returns (address implementation_) {
        assembly {
            implementation_ := sload(_IMPLEMENTATION_SLOT)
        }
    }

    /**
     * @notice Upgrades the contract to a new implementation
     * @param newImplementation The address of the new implementation contract
     * @param newImplementationCodeHash The codehash of the new implementation contract
     * @param params Optional setup parameters for the new implementation contract
     * @dev This function is only callable by the owner.
     */
    function upgrade(
        address newImplementation,
        bytes32 newImplementationCodeHash,
        bytes calldata params
    ) external override onlyOwner {
        if (IUpgradable(newImplementation).contractId() != IUpgradable(implementation()).contractId())
            revert InvalidImplementation();

        if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash();

        emit Upgraded(newImplementation);

        if (params.length > 0) {
            // slither-disable-next-line controlled-delegatecall
            (bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params));

            if (!success) revert SetupFailed();
        }

        assembly {
            sstore(_IMPLEMENTATION_SLOT, newImplementation)
        }
    }

    /**
     * @notice Sets up the contract with initial data
     * @param data Initialization data for the contract
     * @dev This function is only callable by the proxy contract.
     */
    function setup(bytes calldata data) external override(IImplementation, Implementation) onlyProxy {
        _setup(data);
    }

    /**
     * @notice Internal function to set up the contract with initial data
     * @param data Initialization data for the contract
     * @dev This function should be implemented in derived contracts.
     */
    function _setup(bytes calldata data) internal virtual {}
}

File 11 of 12 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IOwnable } from '../interfaces/IOwnable.sol';

/**
 * @title Ownable
 * @notice A contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The owner account is set through ownership transfer. This module makes
 * it possible to transfer the ownership of the contract to a new account in one
 * step, as well as to an interim pending owner. In the second flow the ownership does not
 * change until the pending owner accepts the ownership transfer.
 */
abstract contract Ownable is IOwnable {
    // keccak256('owner')
    bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;
    // keccak256('ownership-transfer')
    bytes32 internal constant _OWNERSHIP_TRANSFER_SLOT =
        0x9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d1;

    /**
     * @notice Initializes the contract by transferring ownership to the owner parameter.
     * @param _owner Address to set as the initial owner of the contract
     */
    constructor(address _owner) {
        _transferOwnership(_owner);
    }

    /**
     * @notice Modifier that throws an error if called by any account other than the owner.
     */
    modifier onlyOwner() {
        if (owner() != msg.sender) revert NotOwner();

        _;
    }

    /**
     * @notice Returns the current owner of the contract.
     * @return owner_ The current owner of the contract
     */
    function owner() public view returns (address owner_) {
        assembly {
            owner_ := sload(_OWNER_SLOT)
        }
    }

    /**
     * @notice Returns the pending owner of the contract.
     * @return owner_ The pending owner of the contract
     */
    function pendingOwner() public view returns (address owner_) {
        assembly {
            owner_ := sload(_OWNERSHIP_TRANSFER_SLOT)
        }
    }

    /**
     * @notice Transfers ownership of the contract to a new account `newOwner`.
     * @dev Can only be called by the current owner.
     * @param newOwner The address to transfer ownership to
     */
    function transferOwnership(address newOwner) external virtual onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @notice Propose to transfer ownership of the contract to a new account `newOwner`.
     * @dev Can only be called by the current owner. The ownership does not change
     * until the new owner accepts the ownership transfer.
     * @param newOwner The address to transfer ownership to
     */
    function proposeOwnership(address newOwner) external virtual onlyOwner {
        if (newOwner == address(0)) revert InvalidOwnerAddress();

        emit OwnershipTransferStarted(newOwner);

        assembly {
            sstore(_OWNERSHIP_TRANSFER_SLOT, newOwner)
        }
    }

    /**
     * @notice Accepts ownership of the contract.
     * @dev Can only be called by the pending owner
     */
    function acceptOwnership() external virtual {
        address newOwner = pendingOwner();
        if (newOwner != msg.sender) revert InvalidOwner();

        _transferOwnership(newOwner);
    }

    /**
     * @notice Internal function to transfer ownership of the contract to a new account `newOwner`.
     * @dev Called in the constructor to set the initial owner.
     * @param newOwner The address to transfer ownership to
     */
    function _transferOwnership(address newOwner) internal virtual {
        if (newOwner == address(0)) revert InvalidOwnerAddress();

        emit OwnershipTransferred(newOwner);

        assembly {
            sstore(_OWNER_SLOT, newOwner)
            sstore(_OWNERSHIP_TRANSFER_SLOT, 0)
        }
    }
}

File 12 of 12 : IAxelarGasService.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IUpgradable } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IUpgradable.sol';

/**
 * @title IAxelarGasService Interface
 * @notice This is an interface for the AxelarGasService contract which manages gas payments
 * and refunds for cross-chain communication on the Axelar network.
 * @dev This interface inherits IUpgradable
 */
interface IAxelarGasService is IUpgradable {
    error InvalidAddress();
    error NotCollector();
    error InvalidAmounts();

    event GasPaidForContractCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForContractCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForContractCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForContractCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForExpressCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForExpressCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForExpressCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForExpressCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasAdded(bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress);

    event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);

    event ExpressGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, address gasToken, uint256 gasFeeAmount, address refundAddress);

    event NativeExpressGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);

    event Refunded(bytes32 indexed txHash, uint256 indexed logIndex, address payable receiver, address token, uint256 amount);

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using native currency for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using native currency for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using native currency for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable;

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Add additional gas payment using native currency after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable;

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Add additional gas payment using native currency after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable;

    /**
     * @notice Allows the gasCollector to collect accumulated fees from the contract.
     * @dev Use address(0) as the token address for native currency.
     * @param receiver The address to receive the collected fees
     * @param tokens Array of token addresses to be collected
     * @param amounts Array of amounts to be collected for each respective token address
     */
    function collectFees(
        address payable receiver,
        address[] calldata tokens,
        uint256[] calldata amounts
    ) external;

    /**
     * @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.
     * @dev Only callable by the gasCollector.
     * @dev Use address(0) as the token address to refund native currency.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param receiver The address to receive the refund
     * @param token The token address to be refunded
     * @param amount The amount to refund
     */
    function refund(
        bytes32 txHash,
        uint256 logIndex,
        address payable receiver,
        address token,
        uint256 amount
    ) external;

    /**
     * @notice Returns the address of the designated gas collector.
     * @return address of the gas collector
     */
    function gasCollector() external returns (address);
}

Settings
{
  "evmVersion": "london",
  "optimizer": {
    "enabled": true,
    "runs": 1000,
    "details": {
      "peephole": true,
      "inliner": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "deduplicate": true,
      "cse": true,
      "constantOptimizer": true,
      "yul": true,
      "yulDetails": {
        "stackAllocation": true
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"gasCollector_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmounts","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidOwnerAddress","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"NotCollector","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[],"name":"TokenTransferFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"ExpressGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForContractCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForContractCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForExpressCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"gasToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"GasPaidForExpressCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeExpressGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForContractCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForContractCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForExpressCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"string","name":"destinationChain","type":"string"},{"indexed":false,"internalType":"string","name":"destinationAddress","type":"string"},{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"refundAddress","type":"address"}],"name":"NativeGasPaidForExpressCallWithToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"logIndex","type":"uint256"},{"indexed":false,"internalType":"address payable","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Refunded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addExpressGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addNativeExpressGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"addNativeGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"gasCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForContractCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForContractCallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForExpressCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"gasToken","type":"address"},{"internalType":"uint256","name":"gasFeeAmount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payGasForExpressCallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForContractCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForContractCallWithToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForExpressCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"payNativeGasForExpressCallWithToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"txHash","type":"bytes32"},{"internalType":"uint256","name":"logIndex","type":"uint256"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes32","name":"newImplementationCodeHash","type":"bytes32"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b50604051620020a2380380620020a28339810160408190526200003491620000fc565b6001620000418162000058565b50306080526001600160a01b031660a0526200012e565b6001600160a01b0381166200008057604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000602082840312156200010f57600080fd5b81516001600160a01b03811681146200012757600080fd5b9392505050565b60805160a051611f39620001696000396000818161034501528181610560015281816108cb0152610ab401526000610b060152611f396000f3fe6080604052600436106101965760003560e01c8063892b5007116100e1578063c62c20021161008a578063edb6b3a511610064578063edb6b3a514610475578063f2fde38b14610495578063f61ed218146104b5578063fd09e3bd146104c857600080fd5b8063c62c20021461041b578063cd433ada1461042e578063e30c39781461044157600080fd5b8063a3499c73116100bb578063a3499c73146103bb578063ab1999ba146103db578063ba9ddc8d146103fb57600080fd5b8063892b5007146103335780638da5cb5b146103675780639ded06df1461039b57600080fd5b80634d2384891161014357806379ba50971161011d57806379ba5097146102c35780638291286c146102d857806382ad6f351461031357600080fd5b80634d238489146102435780635c60da1b14610256578063710bf322146102a357600080fd5b80632e9b7470116101745780632e9b7470146101f05780632edd2aa814610203578063365047211461022357600080fd5b80630c93e3bb1461019b5780631055eaaf146101b057806317a49f7c146101d0575b600080fd5b6101ae6101a9366004611566565b6104e8565b005b3480156101bc57600080fd5b506101ae6101cb36600461166b565b610555565b3480156101dc57600080fd5b506101ae6101eb366004611791565b61074f565b6101ae6101fe3660046118af565b6107db565b34801561020f57600080fd5b506101ae61021e3660046119a2565b610851565b34801561022f57600080fd5b506101ae61023e3660046119f8565b6108c0565b6101ae610251366004611a4a565b610915565b34801561026257600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102af57600080fd5b506101ae6102be366004611a83565b610960565b3480156102cf57600080fd5b506101ae610a2f565b3480156102e457600080fd5b506040517ffaa2f015f2ce5aee225904728de2def86eb8837491efd21f1a04fc20d8e923f6815260200161029a565b34801561031f57600080fd5b506101ae61032e366004611aa7565b610aa9565b34801561033f57600080fd5b506102867f000000000000000000000000000000000000000000000000000000000000000081565b34801561037357600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c054610286565b3480156103a757600080fd5b506101ae6103b6366004611ae8565b610b04565b3480156103c757600080fd5b506101ae6103d6366004611b2a565b610b6b565b3480156103e757600080fd5b506101ae6103f63660046119a2565b610ea8565b34801561040757600080fd5b506101ae610416366004611b86565b610ef7565b6101ae6104293660046118af565b610f7d565b6101ae61043c366004611a4a565b610fde565b34801561044d57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d154610286565b34801561048157600080fd5b506101ae610490366004611791565b611020565b3480156104a157600080fd5b506101ae6104b0366004611a83565b611081565b6101ae6104c3366004611566565b6110d1565b3480156104d457600080fd5b506101ae6104e3366004611b86565b61112c565b82826040516104f8929190611c5e565b6040518091039020886001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a89898989348860405161054396959493929190611c97565b60405180910390a35050505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461059d57604051623bb10360e91b815260040160405180910390fd5b6001600160a01b0385166105c45760405163e6c4247b60e01b815260040160405180910390fd5b828181146105e557604051636c2b7e2d60e11b815260040160405180910390fd5b60005b8181101561074657600086868381811061060457610604611ce1565b90506020020160208101906106199190611a83565b9050600085858481811061062f5761062f611ce1565b905060200201359050806000141561065a57604051636c2b7e2d60e11b815260040160405180910390fd5b6001600160a01b03821661068757478111610682576106826001600160a01b038a1682611189565b610731565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a082319060240160206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107179190611cf7565b8111610731576107316001600160a01b0383168a836111ce565b5050808061073e90611d10565b9150506105e8565b50505050505050565b868660405161075f929190611c5e565b60405180910390208c6001600160a01b03167fda4ed638a7ffe9e814722efdb9ad6058c152c19c8564ceffe52e11dda1ca32238d8d8d8d8b8b8b8b8b6040516107b099989796959493929190611d65565b60405180910390a36107cd6001600160a01b038416333085611277565b505050505050505050505050565b85856040516107eb929190611c5e565b60405180910390208b6001600160a01b03167f8c092067e86e85e8cfbaf187202ef580cdfd7ec37fbec89191607de73ca800058c8c8c8c8a8a8a348b60405161083c99989796959493929190611dee565b60405180910390a35050505050505050505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907ff0b09bf969e7958967e0968e22596f647dd6efa09f4778e0393967b881f4b09f906060015b60405180910390a36108b96001600160a01b038416333085611277565b5050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461090857604051623bb10360e91b815260040160405180910390fd5b6108b985858585856112ce565b604080513481526001600160a01b0383166020820152839185917fb26db521e067acd5c6e345ad92fa1ed06bc7fb2aedd68f35dc7a2e10d636fc9891015b60405180910390a3505050565b336109897f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146109b0576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b0381166109d757604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000610a597f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314610a9d576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aa68161137e565b50565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610af157604051623bb10360e91b815260040160405180910390fd5b610aff6000808585856112ce565b505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316301415610b67576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b33610b947f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610bbb576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1557600080fd5b505afa158015610c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4d9190611cf7565b846001600160a01b0316638291286c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbe9190611cf7565b14610cf5576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f8314610d38576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015610e81576000846001600160a01b0316639ded06df60e01b8484604051602401610d99929190611e55565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051610e049190611e71565b600060405180830381855af49150503d8060008114610e3f576040519150601f19603f3d011682016040523d82523d6000602084013e610e44565b606091505b5050905080610e7f576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080516001600160a01b03808616825260208201859052831691810191909152849086907f2275e75614080f9782f72563c2c1688c901c5339c7f9f436d323f9386fed700a9060600161089c565b8484604051610f07929190611c5e565b60405180910390208a6001600160a01b03167fd171a7eb157e548ca493dd0a16016d125963a369ac5ae3c275ec12c96d5277028b8b8b8b898989604051610f549796959493929190611e8d565b60405180910390a3610f716001600160a01b038416333085611277565b50505050505050505050565b8585604051610f8d929190611c5e565b60405180910390208b6001600160a01b03167f999d431b58761213cf53af96262b67a069cbd963499fd8effd1e21556217b8418c8c8c8c8a8a8a348b60405161083c99989796959493929190611dee565b604080513481526001600160a01b0383166020820152839185917ffeb6b00343feee0f29a1a4345f8bf93ca1c73ee922248a4237a4e50d6447604e9101610953565b8686604051611030929190611c5e565b60405180910390208c6001600160a01b03167f8875f9764f28fa82d3e7ff1b80bd5c8f665e1f42fcd8c2faebc7c400a4ba1bbd8d8d8d8d8b8b8b8b8b6040516107b099989796959493929190611d65565b336110aa7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610a9d576040516330cd747160e01b815260040160405180910390fd5b82826040516110e1929190611c5e565b6040518091039020886001600160a01b03167f5cf48f121a0fecaa2c4a64b3eaf482c8c308d5387e161535970f3e9e4363eff689898989348860405161054396959493929190611c97565b848460405161113c929190611c5e565b60405180910390208a6001600160a01b03167f99206760f0be19dd093729bd35e5924daff5e217bcedc5223ed067b60008cf8a8b8b8b8b898989604051610f549796959493929190611e8d565b600080600080600085875af1905080610aff576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038316602482015260448101829052610aff9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611421565b6040516001600160a01b03808516602483015283166044820152606481018290526112c89085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611213565b50505050565b6001600160a01b0383166112f55760405163e6c4247b60e01b815260040160405180910390fd5b604080516001600160a01b03808616825284166020820152908101829052849086907fd5df103822011013c8c940930e5180419111c65abadd6525ca7e740d56b4703f9060600160405180910390a36001600160a01b03821661136a576113656001600160a01b03841682611189565b6108b9565b6108b96001600160a01b03831684836111ce565b6001600160a01b0381166113a557604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b600080836001600160a01b03168360405161143c9190611e71565b6000604051808303816000865af19150503d8060008114611479576040519150601f19603f3d011682016040523d82523d6000602084013e61147e565b606091505b509150915060008280156114aa5750815115806114aa5750818060200190518101906114aa9190611ee1565b90508015806114c157506001600160a01b0385163b155b156108b9576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381168114610aa657600080fd5b8035611518816114f8565b919050565b60008083601f84011261152f57600080fd5b50813567ffffffffffffffff81111561154757600080fd5b60208301915083602082850101111561155f57600080fd5b9250929050565b60008060008060008060008060a0898b03121561158257600080fd5b883561158d816114f8565b9750602089013567ffffffffffffffff808211156115aa57600080fd5b6115b68c838d0161151d565b909950975060408b01359150808211156115cf57600080fd5b6115db8c838d0161151d565b909750955060608b01359150808211156115f457600080fd5b506116018b828c0161151d565b9094509250506080890135611615816114f8565b809150509295985092959890939650565b60008083601f84011261163857600080fd5b50813567ffffffffffffffff81111561165057600080fd5b6020830191508360208260051b850101111561155f57600080fd5b60008060008060006060868803121561168357600080fd5b853561168e816114f8565b9450602086013567ffffffffffffffff808211156116ab57600080fd5b6116b789838a01611626565b909650945060408801359150808211156116d057600080fd5b506116dd88828901611626565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261171557600080fd5b813567ffffffffffffffff80821115611730576117306116ee565b604051601f8301601f19908116603f01168101908282118183101715611758576117586116ee565b8160405283815286602085880101111561177157600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806000806000806000806000806101208d8f0312156117b457600080fd5b6117bd8d61150d565b9b5067ffffffffffffffff60208e013511156117d857600080fd5b6117e88e60208f01358f0161151d565b909b50995067ffffffffffffffff60408e0135111561180657600080fd5b6118168e60408f01358f0161151d565b909950975067ffffffffffffffff60608e0135111561183457600080fd5b6118448e60608f01358f0161151d565b909750955067ffffffffffffffff60808e0135111561186257600080fd5b6118728e60808f01358f01611704565b945060a08d0135935061188760c08e0161150d565b925060e08d0135915061189d6101008e0161150d565b90509295989b509295989b509295989b565b600080600080600080600080600080600060e08c8e0312156118d057600080fd5b6118d98c61150d565b9a5067ffffffffffffffff8060208e013511156118f557600080fd5b6119058e60208f01358f0161151d565b909b50995060408d013581101561191b57600080fd5b61192b8e60408f01358f0161151d565b909950975060608d013581101561194157600080fd5b6119518e60608f01358f0161151d565b909750955060808d013581101561196757600080fd5b506119788d60808e01358e0161151d565b909450925060a08c0135915061199060c08d0161150d565b90509295989b509295989b9093969950565b600080600080600060a086880312156119ba57600080fd5b853594506020860135935060408601356119d3816114f8565b92506060860135915060808601356119ea816114f8565b809150509295509295909350565b600080600080600060a08688031215611a1057600080fd5b85359450602086013593506040860135611a29816114f8565b92506060860135611a39816114f8565b949793965091946080013592915050565b600080600060608486031215611a5f57600080fd5b83359250602084013591506040840135611a78816114f8565b809150509250925092565b600060208284031215611a9557600080fd5b8135611aa0816114f8565b9392505050565b600080600060608486031215611abc57600080fd5b8335611ac7816114f8565b92506020840135611ad7816114f8565b929592945050506040919091013590565b60008060208385031215611afb57600080fd5b823567ffffffffffffffff811115611b1257600080fd5b611b1e8582860161151d565b90969095509350505050565b60008060008060608587031215611b4057600080fd5b8435611b4b816114f8565b935060208501359250604085013567ffffffffffffffff811115611b6e57600080fd5b611b7a8782880161151d565b95989497509550505050565b60008060008060008060008060008060e08b8d031215611ba557600080fd5b8a35611bb0816114f8565b995060208b013567ffffffffffffffff80821115611bcd57600080fd5b611bd98e838f0161151d565b909b50995060408d0135915080821115611bf257600080fd5b611bfe8e838f0161151d565b909950975060608d0135915080821115611c1757600080fd5b50611c248d828e0161151d565b90965094505060808b0135611c38816114f8565b925060a08b01359150611c4d60c08c0161150d565b90509295989b9194979a5092959850565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b608081526000611cab60808301888a611c6e565b8281036020840152611cbe818789611c6e565b9150508360408301526001600160a01b0383166060830152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611d0957600080fd5b5051919050565b6000600019821415611d3257634e487b7160e01b600052601160045260246000fd5b5060010190565b60005b83811015611d54578181015183820152602001611d3c565b838111156112c85750506000910152565b60e081526000611d7960e083018b8d611c6e565b8281036020840152611d8c818a8c611c6e565b905082810360408401528751808252611dac816020840160208c01611d39565b60608401979097526001600160a01b03958616608084015260a083019490945250921660c0909201919091526020601f909201601f1916010195945050505050565b60c081526000611e0260c083018b8d611c6e565b8281036020840152611e15818a8c611c6e565b90508281036040840152611e2a81888a611c6e565b6060840196909652505060808101929092526001600160a01b031660a0909101529695505050505050565b602081526000611e69602083018486611c6e565b949350505050565b60008251611e83818460208701611d39565b9190910192915050565b60a081526000611ea160a08301898b611c6e565b8281036020840152611eb481888a611c6e565b6001600160a01b039687166040850152606084019590955250509216608090920191909152949350505050565b600060208284031215611ef357600080fd5b81518015158114611aa057600080fdfea26469706673582212205bea4548792d5e969db468efab61606ac6679ee26b5a75ed3cbb7288303b0b4f64736f6c634300080900330000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc

Deployed Bytecode

0x6080604052600436106101965760003560e01c8063892b5007116100e1578063c62c20021161008a578063edb6b3a511610064578063edb6b3a514610475578063f2fde38b14610495578063f61ed218146104b5578063fd09e3bd146104c857600080fd5b8063c62c20021461041b578063cd433ada1461042e578063e30c39781461044157600080fd5b8063a3499c73116100bb578063a3499c73146103bb578063ab1999ba146103db578063ba9ddc8d146103fb57600080fd5b8063892b5007146103335780638da5cb5b146103675780639ded06df1461039b57600080fd5b80634d2384891161014357806379ba50971161011d57806379ba5097146102c35780638291286c146102d857806382ad6f351461031357600080fd5b80634d238489146102435780635c60da1b14610256578063710bf322146102a357600080fd5b80632e9b7470116101745780632e9b7470146101f05780632edd2aa814610203578063365047211461022357600080fd5b80630c93e3bb1461019b5780631055eaaf146101b057806317a49f7c146101d0575b600080fd5b6101ae6101a9366004611566565b6104e8565b005b3480156101bc57600080fd5b506101ae6101cb36600461166b565b610555565b3480156101dc57600080fd5b506101ae6101eb366004611791565b61074f565b6101ae6101fe3660046118af565b6107db565b34801561020f57600080fd5b506101ae61021e3660046119a2565b610851565b34801561022f57600080fd5b506101ae61023e3660046119f8565b6108c0565b6101ae610251366004611a4a565b610915565b34801561026257600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102af57600080fd5b506101ae6102be366004611a83565b610960565b3480156102cf57600080fd5b506101ae610a2f565b3480156102e457600080fd5b506040517ffaa2f015f2ce5aee225904728de2def86eb8837491efd21f1a04fc20d8e923f6815260200161029a565b34801561031f57600080fd5b506101ae61032e366004611aa7565b610aa9565b34801561033f57600080fd5b506102867f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc81565b34801561037357600080fd5b507f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c054610286565b3480156103a757600080fd5b506101ae6103b6366004611ae8565b610b04565b3480156103c757600080fd5b506101ae6103d6366004611b2a565b610b6b565b3480156103e757600080fd5b506101ae6103f63660046119a2565b610ea8565b34801561040757600080fd5b506101ae610416366004611b86565b610ef7565b6101ae6104293660046118af565b610f7d565b6101ae61043c366004611a4a565b610fde565b34801561044d57600080fd5b507f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d154610286565b34801561048157600080fd5b506101ae610490366004611791565b611020565b3480156104a157600080fd5b506101ae6104b0366004611a83565b611081565b6101ae6104c3366004611566565b6110d1565b3480156104d457600080fd5b506101ae6104e3366004611b86565b61112c565b82826040516104f8929190611c5e565b6040518091039020886001600160a01b03167f617332c1832058df6ee45fcbdf471251474c9945a8e5d229287a21a5f67ccf0a89898989348860405161054396959493929190611c97565b60405180910390a35050505050505050565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc161461059d57604051623bb10360e91b815260040160405180910390fd5b6001600160a01b0385166105c45760405163e6c4247b60e01b815260040160405180910390fd5b828181146105e557604051636c2b7e2d60e11b815260040160405180910390fd5b60005b8181101561074657600086868381811061060457610604611ce1565b90506020020160208101906106199190611a83565b9050600085858481811061062f5761062f611ce1565b905060200201359050806000141561065a57604051636c2b7e2d60e11b815260040160405180910390fd5b6001600160a01b03821661068757478111610682576106826001600160a01b038a1682611189565b610731565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038316906370a082319060240160206040518083038186803b1580156106df57600080fd5b505afa1580156106f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107179190611cf7565b8111610731576107316001600160a01b0383168a836111ce565b5050808061073e90611d10565b9150506105e8565b50505050505050565b868660405161075f929190611c5e565b60405180910390208c6001600160a01b03167fda4ed638a7ffe9e814722efdb9ad6058c152c19c8564ceffe52e11dda1ca32238d8d8d8d8b8b8b8b8b6040516107b099989796959493929190611d65565b60405180910390a36107cd6001600160a01b038416333085611277565b505050505050505050505050565b85856040516107eb929190611c5e565b60405180910390208b6001600160a01b03167f8c092067e86e85e8cfbaf187202ef580cdfd7ec37fbec89191607de73ca800058c8c8c8c8a8a8a348b60405161083c99989796959493929190611dee565b60405180910390a35050505050505050505050565b604080516001600160a01b03808616825260208201859052831691810191909152849086907ff0b09bf969e7958967e0968e22596f647dd6efa09f4778e0393967b881f4b09f906060015b60405180910390a36108b96001600160a01b038416333085611277565b5050505050565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc161461090857604051623bb10360e91b815260040160405180910390fd5b6108b985858585856112ce565b604080513481526001600160a01b0383166020820152839185917fb26db521e067acd5c6e345ad92fa1ed06bc7fb2aedd68f35dc7a2e10d636fc9891015b60405180910390a3505050565b336109897f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b0316146109b0576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b0381166109d757604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907fd9be0e8e07417e00f2521db636cb53e316fd288f5051f16d2aa2bf0c3938a87690600090a27f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b6000610a597f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d15490565b90506001600160a01b0381163314610a9d576040517f49e27cff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610aa68161137e565b50565b336001600160a01b037f0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc1614610af157604051623bb10360e91b815260040160405180910390fd5b610aff6000808585856112ce565b505050565b7f000000000000000000000000e622b1d44f5061db10aba2594f1a8eb2dc1fc1d46001600160a01b0316301415610b67576040517fbf10dd3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b33610b947f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610bbb576040516330cd747160e01b815260040160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b0316638291286c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c1557600080fd5b505afa158015610c29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4d9190611cf7565b846001600160a01b0316638291286c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c8657600080fd5b505afa158015610c9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cbe9190611cf7565b14610cf5576040517f68155f9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836001600160a01b03163f8314610d38576040517f8f84fb2400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038516907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a28015610e81576000846001600160a01b0316639ded06df60e01b8484604051602401610d99929190611e55565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051610e049190611e71565b600060405180830381855af49150503d8060008114610e3f576040519150601f19603f3d011682016040523d82523d6000602084013e610e44565b606091505b5050905080610e7f576040517f97905dfb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b5050507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b604080516001600160a01b03808616825260208201859052831691810191909152849086907f2275e75614080f9782f72563c2c1688c901c5339c7f9f436d323f9386fed700a9060600161089c565b8484604051610f07929190611c5e565b60405180910390208a6001600160a01b03167fd171a7eb157e548ca493dd0a16016d125963a369ac5ae3c275ec12c96d5277028b8b8b8b898989604051610f549796959493929190611e8d565b60405180910390a3610f716001600160a01b038416333085611277565b50505050505050505050565b8585604051610f8d929190611c5e565b60405180910390208b6001600160a01b03167f999d431b58761213cf53af96262b67a069cbd963499fd8effd1e21556217b8418c8c8c8c8a8a8a348b60405161083c99989796959493929190611dee565b604080513481526001600160a01b0383166020820152839185917ffeb6b00343feee0f29a1a4345f8bf93ca1c73ee922248a4237a4e50d6447604e9101610953565b8686604051611030929190611c5e565b60405180910390208c6001600160a01b03167f8875f9764f28fa82d3e7ff1b80bd5c8f665e1f42fcd8c2faebc7c400a4ba1bbd8d8d8d8d8b8b8b8b8b6040516107b099989796959493929190611d65565b336110aa7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05490565b6001600160a01b031614610a9d576040516330cd747160e01b815260040160405180910390fd5b82826040516110e1929190611c5e565b6040518091039020886001600160a01b03167f5cf48f121a0fecaa2c4a64b3eaf482c8c308d5387e161535970f3e9e4363eff689898989348860405161054396959493929190611c97565b848460405161113c929190611c5e565b60405180910390208a6001600160a01b03167f99206760f0be19dd093729bd35e5924daff5e217bcedc5223ed067b60008cf8a8b8b8b8b898989604051610f549796959493929190611e8d565b600080600080600085875af1905080610aff576040517ff4b3b1bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516001600160a01b038316602482015260448101829052610aff9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611421565b6040516001600160a01b03808516602483015283166044820152606481018290526112c89085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611213565b50505050565b6001600160a01b0383166112f55760405163e6c4247b60e01b815260040160405180910390fd5b604080516001600160a01b03808616825284166020820152908101829052849086907fd5df103822011013c8c940930e5180419111c65abadd6525ca7e740d56b4703f9060600160405180910390a36001600160a01b03821661136a576113656001600160a01b03841682611189565b6108b9565b6108b96001600160a01b03831684836111ce565b6001600160a01b0381166113a557604051633649397d60e21b815260040160405180910390fd5b6040516001600160a01b038216907f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616390600090a27f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05560007f9855384122b55936fbfb8ca5120e63c6537a1ac40caf6ae33502b3c5da8c87d155565b600080836001600160a01b03168360405161143c9190611e71565b6000604051808303816000865af19150503d8060008114611479576040519150601f19603f3d011682016040523d82523d6000602084013e61147e565b606091505b509150915060008280156114aa5750815115806114aa5750818060200190518101906114aa9190611ee1565b90508015806114c157506001600160a01b0385163b155b156108b9576040517f045c4b0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0381168114610aa657600080fd5b8035611518816114f8565b919050565b60008083601f84011261152f57600080fd5b50813567ffffffffffffffff81111561154757600080fd5b60208301915083602082850101111561155f57600080fd5b9250929050565b60008060008060008060008060a0898b03121561158257600080fd5b883561158d816114f8565b9750602089013567ffffffffffffffff808211156115aa57600080fd5b6115b68c838d0161151d565b909950975060408b01359150808211156115cf57600080fd5b6115db8c838d0161151d565b909750955060608b01359150808211156115f457600080fd5b506116018b828c0161151d565b9094509250506080890135611615816114f8565b809150509295985092959890939650565b60008083601f84011261163857600080fd5b50813567ffffffffffffffff81111561165057600080fd5b6020830191508360208260051b850101111561155f57600080fd5b60008060008060006060868803121561168357600080fd5b853561168e816114f8565b9450602086013567ffffffffffffffff808211156116ab57600080fd5b6116b789838a01611626565b909650945060408801359150808211156116d057600080fd5b506116dd88828901611626565b969995985093965092949392505050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261171557600080fd5b813567ffffffffffffffff80821115611730576117306116ee565b604051601f8301601f19908116603f01168101908282118183101715611758576117586116ee565b8160405283815286602085880101111561177157600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806000806000806000806000806101208d8f0312156117b457600080fd5b6117bd8d61150d565b9b5067ffffffffffffffff60208e013511156117d857600080fd5b6117e88e60208f01358f0161151d565b909b50995067ffffffffffffffff60408e0135111561180657600080fd5b6118168e60408f01358f0161151d565b909950975067ffffffffffffffff60608e0135111561183457600080fd5b6118448e60608f01358f0161151d565b909750955067ffffffffffffffff60808e0135111561186257600080fd5b6118728e60808f01358f01611704565b945060a08d0135935061188760c08e0161150d565b925060e08d0135915061189d6101008e0161150d565b90509295989b509295989b509295989b565b600080600080600080600080600080600060e08c8e0312156118d057600080fd5b6118d98c61150d565b9a5067ffffffffffffffff8060208e013511156118f557600080fd5b6119058e60208f01358f0161151d565b909b50995060408d013581101561191b57600080fd5b61192b8e60408f01358f0161151d565b909950975060608d013581101561194157600080fd5b6119518e60608f01358f0161151d565b909750955060808d013581101561196757600080fd5b506119788d60808e01358e0161151d565b909450925060a08c0135915061199060c08d0161150d565b90509295989b509295989b9093969950565b600080600080600060a086880312156119ba57600080fd5b853594506020860135935060408601356119d3816114f8565b92506060860135915060808601356119ea816114f8565b809150509295509295909350565b600080600080600060a08688031215611a1057600080fd5b85359450602086013593506040860135611a29816114f8565b92506060860135611a39816114f8565b949793965091946080013592915050565b600080600060608486031215611a5f57600080fd5b83359250602084013591506040840135611a78816114f8565b809150509250925092565b600060208284031215611a9557600080fd5b8135611aa0816114f8565b9392505050565b600080600060608486031215611abc57600080fd5b8335611ac7816114f8565b92506020840135611ad7816114f8565b929592945050506040919091013590565b60008060208385031215611afb57600080fd5b823567ffffffffffffffff811115611b1257600080fd5b611b1e8582860161151d565b90969095509350505050565b60008060008060608587031215611b4057600080fd5b8435611b4b816114f8565b935060208501359250604085013567ffffffffffffffff811115611b6e57600080fd5b611b7a8782880161151d565b95989497509550505050565b60008060008060008060008060008060e08b8d031215611ba557600080fd5b8a35611bb0816114f8565b995060208b013567ffffffffffffffff80821115611bcd57600080fd5b611bd98e838f0161151d565b909b50995060408d0135915080821115611bf257600080fd5b611bfe8e838f0161151d565b909950975060608d0135915080821115611c1757600080fd5b50611c248d828e0161151d565b90965094505060808b0135611c38816114f8565b925060a08b01359150611c4d60c08c0161150d565b90509295989b9194979a5092959850565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b608081526000611cab60808301888a611c6e565b8281036020840152611cbe818789611c6e565b9150508360408301526001600160a01b0383166060830152979650505050505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611d0957600080fd5b5051919050565b6000600019821415611d3257634e487b7160e01b600052601160045260246000fd5b5060010190565b60005b83811015611d54578181015183820152602001611d3c565b838111156112c85750506000910152565b60e081526000611d7960e083018b8d611c6e565b8281036020840152611d8c818a8c611c6e565b905082810360408401528751808252611dac816020840160208c01611d39565b60608401979097526001600160a01b03958616608084015260a083019490945250921660c0909201919091526020601f909201601f1916010195945050505050565b60c081526000611e0260c083018b8d611c6e565b8281036020840152611e15818a8c611c6e565b90508281036040840152611e2a81888a611c6e565b6060840196909652505060808101929092526001600160a01b031660a0909101529695505050505050565b602081526000611e69602083018486611c6e565b949350505050565b60008251611e83818460208701611d39565b9190910192915050565b60a081526000611ea160a08301898b611c6e565b8281036020840152611eb481888a611c6e565b6001600160a01b039687166040850152606084019590955250509216608090920191909152949350505050565b600060208284031215611ef357600080fd5b81518015158114611aa057600080fdfea26469706673582212205bea4548792d5e969db468efab61606ac6679ee26b5a75ed3cbb7288303b0b4f64736f6c63430008090033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc

-----Decoded View---------------
Arg [0] : gasCollector_ (address): 0x7DdB2d76b80B0AA19bDEa48EB1301182F4CeefbC

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007ddb2d76b80b0aa19bdea48eb1301182f4ceefbc


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.