GLMR Price: $0.020632 (-2.37%)

Contract

0xCDc4Ff6D20A4a3FB86383026Fd7245332B4019da

Overview

GLMR Balance

Moonbeam Chain LogoMoonbeam Chain LogoMoonbeam Chain Logo0 GLMR

GLMR Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

> 10 Internal Transactions found.

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
44239052023-09-13 5:49:30866 days ago1694584170
0xCDc4Ff6D...32B4019da
1.89655166 GLMR
44232022023-09-13 3:25:24866 days ago1694575524
0xCDc4Ff6D...32B4019da
1.46236565 GLMR
44230552023-09-13 2:55:36866 days ago1694573736
0xCDc4Ff6D...32B4019da
31.25804875 GLMR
44229882023-09-13 2:41:48866 days ago1694572908
0xCDc4Ff6D...32B4019da
1.17643127 GLMR
44224092023-09-13 0:44:48866 days ago1694565888
0xCDc4Ff6D...32B4019da
30.64151329 GLMR
44224092023-09-13 0:44:48866 days ago1694565888
0xCDc4Ff6D...32B4019da
15,350 GLMR
44221082023-09-12 23:43:54866 days ago1694562234
0xCDc4Ff6D...32B4019da
6.12286677 GLMR
44216842023-09-12 22:18:36866 days ago1694557116
0xCDc4Ff6D...32B4019da
1.42414109 GLMR
44214752023-09-12 21:36:36866 days ago1694554596
0xCDc4Ff6D...32B4019da
7.98023579 GLMR
44214752023-09-12 21:36:36866 days ago1694554596
0xCDc4Ff6D...32B4019da
6,100 GLMR
44213322023-09-12 21:07:36866 days ago1694552856
0xCDc4Ff6D...32B4019da
42.65596619 GLMR
44212372023-09-12 20:48:12866 days ago1694551692
0xCDc4Ff6D...32B4019da
18.58707868 GLMR
44212052023-09-12 20:41:48866 days ago1694551308
0xCDc4Ff6D...32B4019da
3.84208019 GLMR
44212052023-09-12 20:41:48866 days ago1694551308
0xCDc4Ff6D...32B4019da
425.12450523 GLMR
44209662023-09-12 19:53:42866 days ago1694548422
0xCDc4Ff6D...32B4019da
1.25090879 GLMR
44209662023-09-12 19:53:42866 days ago1694548422
0xCDc4Ff6D...32B4019da
950 GLMR
44209572023-09-12 19:51:54866 days ago1694548314
0xCDc4Ff6D...32B4019da
0.93980565 GLMR
44209572023-09-12 19:51:54866 days ago1694548314
0xCDc4Ff6D...32B4019da
5,300 GLMR
44206772023-09-12 18:55:18866 days ago1694544918
0xCDc4Ff6D...32B4019da
13.04417871 GLMR
44205892023-09-12 18:37:42866 days ago1694543862
0xCDc4Ff6D...32B4019da
0.9807921 GLMR
44205352023-09-12 18:26:36866 days ago1694543196
0xCDc4Ff6D...32B4019da
15.37344938 GLMR
44198962023-09-12 16:16:42866 days ago1694535402
0xCDc4Ff6D...32B4019da
2.71513059 GLMR
44198962023-09-12 16:16:42866 days ago1694535402
0xCDc4Ff6D...32B4019da
1.05 GLMR
44198772023-09-12 16:12:54866 days ago1694535174
0xCDc4Ff6D...32B4019da
2.45608211 GLMR
44198772023-09-12 16:12:54866 days ago1694535174
0xCDc4Ff6D...32B4019da
1.05 GLMR
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SquidRouter

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 99999 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {ISquidRouter} from "../interfaces/ISquidRouter.sol";
import {ISquidMulticall} from "../interfaces/ISquidMulticall.sol";
import {AxelarForecallable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executables/AxelarForecallable.sol";
import {IAxelarGasService} from "@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarGasService.sol";
import {IAxelarGateway} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol";
import {Upgradable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/upgradables/Upgradable.sol";
import {RoledPausable} from "../libraries/RoledPausable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract SquidRouter is ISquidRouter, AxelarForecallable, Upgradable, RoledPausable {
    IAxelarGasService private immutable gasService;
    IAxelarGasService private immutable forecallGasService;
    ISquidMulticall private immutable squidMulticall;

    constructor(
        address _gateway,
        address _gasService,
        address _forecallGasService,
        address _multicall
    ) AxelarForecallable(_gateway) {
        if (
            _gateway == address(0) ||
            _gasService == address(0) ||
            _forecallGasService == address(0) ||
            _multicall == address(0)
        ) revert ZeroAddressProvided();

        gasService = IAxelarGasService(_gasService);
        forecallGasService = IAxelarGasService(_forecallGasService);
        squidMulticall = ISquidMulticall(_multicall);
    }

    function bridgeCall(
        string calldata bridgedTokenSymbol,
        uint256 amount,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasRefundRecipient,
        bool enableExpress
    ) external payable whenNotPaused {
        address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);

        _safeTransferFrom(bridgedTokenAddress, msg.sender, amount);
        _bridgeCall(
            bridgedTokenSymbol,
            bridgedTokenAddress,
            destinationChain,
            destinationAddress,
            payload,
            gasRefundRecipient,
            enableExpress
        );
    }

    function callBridge(
        address token,
        uint256 amount,
        ISquidMulticall.Call[] calldata calls,
        string calldata bridgedTokenSymbol,
        string calldata destinationChain,
        string calldata destinationAddress
    ) external payable whenNotPaused {
        fundAndRunMulticall(token, amount, calls);

        address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
        uint256 bridgedTokenAmount = IERC20(bridgedTokenAddress).balanceOf(address(this));

        _approve(bridgedTokenAddress, address(gateway), bridgedTokenAmount);
        gateway.sendToken(destinationChain, destinationAddress, bridgedTokenSymbol, bridgedTokenAmount);
    }

    function callBridgeCall(
        address token,
        uint256 amount,
        ISquidMulticall.Call[] calldata calls,
        string calldata bridgedTokenSymbol,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasRefundRecipient,
        bool enableExpress
    ) external payable whenNotPaused {
        fundAndRunMulticall(token, amount, calls);

        address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);

        _bridgeCall(
            bridgedTokenSymbol,
            bridgedTokenAddress,
            destinationChain,
            destinationAddress,
            payload,
            gasRefundRecipient,
            enableExpress
        );
    }

    function contractId() external pure override returns (bytes32 id) {
        id = keccak256("squid-router");
    }

    function fundAndRunMulticall(
        address token,
        uint256 amount,
        ISquidMulticall.Call[] memory calls
    ) public payable whenNotPaused {
        uint256 valueToSend;

        if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
            valueToSend = amount;
        } else {
            _transferTokenToMulticall(token, amount);
        }

        squidMulticall.run{value: valueToSend}(calls);
    }

    function _executeWithToken(
        string calldata,
        string calldata,
        bytes calldata payload,
        string calldata bridgedTokenSymbol,
        uint256
    ) internal override {
        (ISquidMulticall.Call[] memory calls, address refundRecipient) = abi.decode(
            payload,
            (ISquidMulticall.Call[], address)
        );

        address bridgedTokenAddress = gateway.tokenAddresses(bridgedTokenSymbol);
        uint256 contractBalance = IERC20(bridgedTokenAddress).balanceOf(address(this));

        _approve(bridgedTokenAddress, address(squidMulticall), contractBalance);

        try squidMulticall.run(calls) {
            emit CrossMulticallExecuted(keccak256(payload));
        } catch (bytes memory reason) {
            // Refund tokens to refund recipient if swap fails
            _safeTransfer(bridgedTokenAddress, refundRecipient, contractBalance);
            emit CrossMulticallFailed(keccak256(payload), reason, refundRecipient);
        }
    }

    function _bridgeCall(
        string calldata bridgedTokenSymbol,
        address bridgedTokenAddress,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasRefundRecipient,
        bool enableExpress
    ) private {
        uint256 bridgedTokenBalance = IERC20(bridgedTokenAddress).balanceOf(address(this));

        if (address(this).balance > 0) {
            IAxelarGasService executionService = enableExpress ? forecallGasService : gasService;
            executionService.payNativeGasForContractCallWithToken{value: address(this).balance}(
                address(this),
                destinationChain,
                destinationAddress,
                payload,
                bridgedTokenSymbol,
                bridgedTokenBalance,
                gasRefundRecipient
            );
        }

        _approve(bridgedTokenAddress, address(gateway), bridgedTokenBalance);
        gateway.callContractWithToken(
            destinationChain,
            destinationAddress,
            payload,
            bridgedTokenSymbol,
            bridgedTokenBalance
        );
    }

    function _approve(address token, address spender, uint256 amount) private {
        uint256 allowance = IERC20(token).allowance(address(this), spender);
        if (allowance < amount) {
            if (allowance > 0) {
                _approveCall(token, spender, 0);
            }
            _approveCall(token, spender, type(uint256).max);
        }
    }

    function _approveCall(address token, address spender, uint256 amount) private {
        // Unlimited approval is not security issue since the contract doesn't store tokens
        (bool success, ) = token.call(abi.encodeWithSelector(IERC20.approve.selector, spender, amount));
        if (!success) revert ApprovalFailed();
    }

    function _transferTokenToMulticall(address token, uint256 amount) private {
        (bool success, bytes memory returnData) = token.call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, msg.sender, address(squidMulticall), amount)
        );
        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));
        if (!transferred || token.code.length == 0) revert TransferFailed();
    }

    function _setup(bytes calldata data) internal override {
        address _pauser = abi.decode(data, (address));
        if (_pauser == address(0)) revert ZeroAddressProvided();
        _setPauser(_pauser);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

import './IUpgradable.sol';

// This should be owned by the microservice that is paying for gas.
interface IAxelarGasService is IUpgradable {
    error NothingReceived();
    error TransferFailed();
    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 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);

    // This is called on the source chain before calling the gateway to execute a remote contract.
    function payGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    // This is called on the source chain before calling the gateway to execute a remote contract.
    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;

    // This is called on the source chain before calling the gateway to execute a remote contract.
    function payNativeGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;

    // This is called on the source chain before calling the gateway to execute a remote contract.
    function payNativeGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable;

    function addGas(
        bytes32 txHash,
        uint256 txIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    function addNativeGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable;

    function collectFees(
        address payable receiver,
        address[] calldata tokens,
        uint256[] calldata amounts
    ) external;

    function refund(
        address payable receiver,
        address token,
        uint256 amount
    ) external;

    function gasCollector() external returns (address);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;

// General interface for upgradable contracts
interface IUpgradable {
    error NotOwner();
    error InvalidOwner();
    error InvalidCodeHash();
    error InvalidImplementation();
    error SetupFailed();
    error NotProxy();

    event Upgraded(address indexed newImplementation);
    event OwnershipTransferred(address indexed newOwner);

    // Get current owner
    function owner() external view returns (address);

    function contractId() external pure returns (bytes32);

    function implementation() external view returns (address);

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

    function setup(bytes calldata data) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

contract AxelarForecallable is IAxelarForecallable {
    IAxelarGateway public immutable gateway;

    //keccak256('forecallers');
    uint256 public constant FORECALLERS_SALT = 0xdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f;

    constructor(address gateway_) {
        if (gateway_ == address(0)) revert InvalidAddress();

        gateway = IAxelarGateway(gateway_);
    }

    function getForecaller(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) public view override returns (address forecaller) {
        bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT));
        // solhint-disable-next-line no-inline-assembly
        assembly {
            forecaller := sload(pos)
        }
    }

    function _setForecaller(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        address forecaller
    ) internal {
        bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, FORECALLERS_SALT));
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(pos, forecaller)
        }
    }

    function forecall(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external {
        _checkForecall(sourceChain, sourceAddress, payload, msg.sender);
        if (getForecaller(sourceChain, sourceAddress, payload) != address(0)) revert AlreadyForecalled();
        _setForecaller(sourceChain, sourceAddress, payload, msg.sender);
        _execute(sourceChain, sourceAddress, payload);
    }

    function execute(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external override {
        bytes32 payloadHash = keccak256(payload);
        if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
            revert NotApprovedByGateway();
        address forecaller = getForecaller(sourceChain, sourceAddress, payload);
        if (forecaller != address(0)) {
            _setForecaller(sourceChain, sourceAddress, payload, address(0));
        } else {
            _execute(sourceChain, sourceAddress, payload);
        }
    }

    function getForecallerWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount
    ) public view override returns (address forecaller) {
        bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT));
        // solhint-disable-next-line no-inline-assembly
        assembly {
            forecaller := sload(pos)
        }
    }

    function _setForecallerWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address forecaller
    ) internal {
        bytes32 pos = keccak256(abi.encode(sourceChain, sourceAddress, payload, symbol, amount, FORECALLERS_SALT));
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(pos, forecaller)
        }
    }

    function forecallWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external override {
        address token = gateway.tokenAddresses(tokenSymbol);
        uint256 amountPost = amountPostFee(amount, payload);
        _safeTransferFrom(token, msg.sender, amountPost);
        _checkForecallWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender);
        if (getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount) != address(0))
            revert AlreadyForecalled();
        _setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, msg.sender);
        _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amountPost);
    }

    function executeWithToken(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external override {
        bytes32 payloadHash = keccak256(payload);
        if (
            !gateway.validateContractCallAndMint(
                commandId,
                sourceChain,
                sourceAddress,
                payloadHash,
                tokenSymbol,
                amount
            )
        ) revert NotApprovedByGateway();
        address forecaller = getForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
        if (forecaller != address(0)) {
            _setForecallerWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount, address(0));
            address token = gateway.tokenAddresses(tokenSymbol);
            _safeTransfer(token, forecaller, amount);
        } else {
            _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
        }
    }

    function _execute(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) internal virtual {}

    function _executeWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) internal virtual {}

    // Override this to keep a fee.
    function amountPostFee(
        uint256 amount,
        bytes calldata /*payload*/
    ) public virtual override returns (uint256) {
        return amount;
    }

    // Override this and revert if you want to only allow certain people/calls to be able to forecall.
    function _checkForecall(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        address forecaller
    ) internal virtual {}

    // Override this and revert if you want to only allow certain people/calls to be able to forecall.
    function _checkForecallWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount,
        address forecaller
    ) internal virtual {}

    function _safeTransfer(
        address tokenAddress,
        address receiver,
        uint256 amount
    ) internal {
        (bool success, bytes memory returnData) = tokenAddress.call(
            abi.encodeWithSelector(IERC20.transfer.selector, receiver, amount)
        );
        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));

        if (!transferred || tokenAddress.code.length == 0) revert TransferFailed();
    }

    function _safeTransferFrom(
        address tokenAddress,
        address from,
        uint256 amount
    ) internal {
        (bool success, bytes memory returnData) = tokenAddress.call(
            abi.encodeWithSelector(IERC20.transferFrom.selector, from, address(this), amount)
        );
        bool transferred = success && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));

        if (!transferred || tokenAddress.code.length == 0) revert TransferFailed();
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

interface IAxelarExecutable {
    error InvalidAddress();
    error NotApprovedByGateway();

    function gateway() external view returns (IAxelarGateway);

    function execute(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external;

    function executeWithToken(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

interface IAxelarForecallable is IAxelarExecutable {
    error AlreadyForecalled();
    error TransferFailed();

    function forecall(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external;

    function forecallWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external;

    function getForecaller(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external returns (address forecaller);

    function getForecallerWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount
    ) external returns (address forecaller);

    function amountPostFee(uint256 amount, bytes calldata payload) external returns (uint256);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IAxelarGateway {
    /**********\
    |* Errors *|
    \**********/

    error NotSelf();
    error NotProxy();
    error InvalidCodeHash();
    error SetupFailed();
    error InvalidAuthModule();
    error InvalidTokenDeployer();
    error InvalidAmount();
    error InvalidChainId();
    error InvalidCommands();
    error TokenDoesNotExist(string symbol);
    error TokenAlreadyExists(string symbol);
    error TokenDeployFailed(string symbol);
    error TokenContractDoesNotExist(address token);
    error BurnFailed(string symbol);
    error MintFailed(string symbol);
    error InvalidSetMintLimitsParams();
    error ExceedMintLimit(string symbol);

    /**********\
    |* Events *|
    \**********/

    event TokenSent(
        address indexed sender,
        string destinationChain,
        string destinationAddress,
        string symbol,
        uint256 amount
    );

    event ContractCall(
        address indexed sender,
        string destinationChain,
        string destinationContractAddress,
        bytes32 indexed payloadHash,
        bytes payload
    );

    event ContractCallWithToken(
        address indexed sender,
        string destinationChain,
        string destinationContractAddress,
        bytes32 indexed payloadHash,
        bytes payload,
        string symbol,
        uint256 amount
    );

    event Executed(bytes32 indexed commandId);

    event TokenDeployed(string symbol, address tokenAddresses);

    event ContractCallApproved(
        bytes32 indexed commandId,
        string sourceChain,
        string sourceAddress,
        address indexed contractAddress,
        bytes32 indexed payloadHash,
        bytes32 sourceTxHash,
        uint256 sourceEventIndex
    );

    event ContractCallApprovedWithMint(
        bytes32 indexed commandId,
        string sourceChain,
        string sourceAddress,
        address indexed contractAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        bytes32 sourceTxHash,
        uint256 sourceEventIndex
    );

    event TokenMintLimitUpdated(string symbol, uint256 limit);

    event OperatorshipTransferred(bytes newOperatorsData);

    event Upgraded(address indexed implementation);

    /********************\
    |* Public Functions *|
    \********************/

    function sendToken(
        string calldata destinationChain,
        string calldata destinationAddress,
        string calldata symbol,
        uint256 amount
    ) external;

    function callContract(
        string calldata destinationChain,
        string calldata contractAddress,
        bytes calldata payload
    ) external;

    function callContractWithToken(
        string calldata destinationChain,
        string calldata contractAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount
    ) external;

    function isContractCallApproved(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        address contractAddress,
        bytes32 payloadHash
    ) external view returns (bool);

    function isContractCallAndMintApproved(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        address contractAddress,
        bytes32 payloadHash,
        string calldata symbol,
        uint256 amount
    ) external view returns (bool);

    function validateContractCall(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes32 payloadHash
    ) external returns (bool);

    function validateContractCallAndMint(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes32 payloadHash,
        string calldata symbol,
        uint256 amount
    ) external returns (bool);

    /***********\
    |* Getters *|
    \***********/

    function authModule() external view returns (address);

    function tokenDeployer() external view returns (address);

    function tokenMintLimit(string memory symbol) external view returns (uint256);

    function tokenMintAmount(string memory symbol) external view returns (uint256);

    function allTokensFrozen() external view returns (bool);

    function implementation() external view returns (address);

    function tokenAddresses(string memory symbol) external view returns (address);

    function tokenFrozen(string memory symbol) external view returns (bool);

    function isCommandExecuted(bytes32 commandId) external view returns (bool);

    function adminEpoch() external view returns (uint256);

    function adminThreshold(uint256 epoch) external view returns (uint256);

    function admins(uint256 epoch) external view returns (address[] memory);

    /*******************\
    |* Admin Functions *|
    \*******************/

    function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;

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

    /**********************\
    |* External Functions *|
    \**********************/

    function setup(bytes calldata params) external;

    function execute(bytes calldata input) external;
}

// 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);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// General interface for upgradable contracts
interface IUpgradable {
    error NotOwner();
    error InvalidOwner();
    error InvalidCodeHash();
    error InvalidImplementation();
    error SetupFailed();
    error NotProxy();

    event Upgraded(address indexed newImplementation);
    event OwnershipTransferred(address indexed newOwner);

    // Get current owner
    function owner() external view returns (address);

    function contractId() external pure returns (bytes32);

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

    function setup(bytes calldata data) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import '../interfaces/IUpgradable.sol';

abstract contract Upgradable is IUpgradable {
    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    // keccak256('owner')
    bytes32 internal constant _OWNER_SLOT = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;

    modifier onlyOwner() {
        if (owner() != msg.sender) revert NotOwner();
        _;
    }

    function owner() public view returns (address owner_) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            owner_ := sload(_OWNER_SLOT)
        }
    }

    function transferOwnership(address newOwner) external virtual onlyOwner {
        if (newOwner == address(0)) revert InvalidOwner();

        emit OwnershipTransferred(newOwner);
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_OWNER_SLOT, newOwner)
        }
    }

    function implementation() public view returns (address implementation_) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            implementation_ := sload(_IMPLEMENTATION_SLOT)
        }
    }

    function upgrade(
        address newImplementation,
        bytes32 newImplementationCodeHash,
        bytes calldata params
    ) external override onlyOwner {
        if (IUpgradable(newImplementation).contractId() != IUpgradable(this).contractId())
            revert InvalidImplementation();
        if (newImplementationCodeHash != newImplementation.codehash) revert InvalidCodeHash();

        if (params.length > 0) {
            // solhint-disable-next-line avoid-low-level-calls
            (bool success, ) = newImplementation.delegatecall(abi.encodeWithSelector(this.setup.selector, params));

            if (!success) revert SetupFailed();
        }

        emit Upgraded(newImplementation);
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_IMPLEMENTATION_SLOT, newImplementation)
        }
    }

    function setup(bytes calldata data) external override {
        // Prevent setup from being called on the implementation
        if (implementation() == address(0)) revert NotProxy();

        _setup(data);
    }

    // solhint-disable-next-line no-empty-blocks
    function _setup(bytes calldata data) internal virtual {}
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

interface IRoledPausable {
    event PauserProposed(address indexed currentPauser, address indexed pendingPauser);
    event PauserUpdated(address indexed pendingPauser);
    event Paused();
    event Unpaused();

    error ContractIsPaused();
    error NotPauser();
    error NotPendingPauser();

    function updatePauser(address _newPauser) external;

    function acceptPauser() external;

    function pause() external;

    function unpause() external;

    function paused() external view returns (bool value);

    function pauser() external view returns (address value);

    function pendingPauser() external view returns (address value);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

interface ISquidMulticall {
    enum CallType {
        Default,
        FullTokenBalance,
        FullNativeBalance,
        CollectTokenBalance
    }

    struct Call {
        CallType callType;
        address target;
        uint256 value;
        bytes callData;
        bytes payload;
    }

    error AlreadyRunning();
    error CallFailed(uint256 callPosition, bytes reason);

    function run(Call[] calldata calls) external payable;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {ISquidMulticall} from "./ISquidMulticall.sol";

interface ISquidRouter {
    event CrossMulticallExecuted(bytes32 indexed payloadHash);
    event CrossMulticallFailed(bytes32 indexed payloadHash, bytes reason, address indexed refundRecipient);

    error ZeroAddressProvided();
    error ApprovalFailed();

    function bridgeCall(
        string calldata bridgedTokenSymbol,
        uint256 amount,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasRefundRecipient,
        bool enableExpress
    ) external payable;

    function callBridge(
        address token,
        uint256 amount,
        ISquidMulticall.Call[] calldata calls,
        string calldata bridgedTokenSymbol,
        string calldata destinationChain,
        string calldata destinationAddress
    ) external payable;

    function callBridgeCall(
        address token,
        uint256 amount,
        ISquidMulticall.Call[] calldata calls,
        string calldata bridgedTokenSymbol,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasRefundRecipient,
        bool enableExpress
    ) external payable;

    function fundAndRunMulticall(address token, uint256 amount, ISquidMulticall.Call[] memory calls) external payable;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {IRoledPausable} from "../interfaces/IRoledPausable.sol";
import {StorageSlot} from "./StorageSlot.sol";

abstract contract RoledPausable is IRoledPausable {
    using StorageSlot for bytes32;

    bytes32 internal constant PAUSED_SLOT = keccak256("RoledPausable.paused");
    bytes32 internal constant PAUSER_SLOT = keccak256("RoledPausable.pauser");
    bytes32 internal constant PENDING_PAUSER_SLOT = keccak256("RoledPausable.pendingPauser");

    modifier whenNotPaused() {
        if (paused()) revert ContractIsPaused();
        _;
    }

    modifier onlyPauser() {
        if (msg.sender != pauser()) revert NotPauser();
        _;
    }

    constructor() {
        _setPauser(msg.sender);
    }

    function updatePauser(address newPauser) external onlyPauser {
        PENDING_PAUSER_SLOT.setAddress(newPauser);
        emit PauserProposed(msg.sender, newPauser);
    }

    function acceptPauser() external {
        if (msg.sender != pendingPauser()) revert NotPendingPauser();
        _setPauser(msg.sender);
        PENDING_PAUSER_SLOT.setAddress(address(0));
    }

    function pause() external virtual onlyPauser {
        PAUSED_SLOT.setBool(true);
        emit Paused();
    }

    function unpause() external virtual onlyPauser {
        PAUSED_SLOT.setBool(false);
        emit Unpaused();
    }

    function pauser() public view returns (address value) {
        value = PAUSER_SLOT.getAddress();
    }

    function paused() public view returns (bool value) {
        value = PAUSED_SLOT.getBool();
    }

    function pendingPauser() public view returns (address value) {
        value = PENDING_PAUSER_SLOT.getAddress();
    }

    function _setPauser(address _pauser) internal {
        PAUSER_SLOT.setAddress(_pauser);
        emit PauserUpdated(_pauser);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

library StorageSlot {
    function setUint256(bytes32 slot, uint256 value) internal {
        assembly {
            sstore(slot, value)
        }
    }

    function getUint256(bytes32 slot) internal view returns (uint256 value) {
        assembly {
            value := sload(slot)
        }
    }

    function setAddress(bytes32 slot, address value) internal {
        assembly {
            sstore(slot, value)
        }
    }

    function getAddress(bytes32 slot) internal view returns (address value) {
        assembly {
            value := sload(slot)
        }
    }

    function setBool(bytes32 slot, bool value) internal {
        assembly {
            sstore(slot, value)
        }
    }

    function getBool(bytes32 slot) internal view returns (bool value) {
        assembly {
            value := sload(slot)
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 99999
  },
  "viaIR": true,
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_gateway","type":"address"},{"internalType":"address","name":"_gasService","type":"address"},{"internalType":"address","name":"_forecallGasService","type":"address"},{"internalType":"address","name":"_multicall","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyForecalled","type":"error"},{"inputs":[],"name":"ApprovalFailed","type":"error"},{"inputs":[],"name":"ContractIsPaused","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidCodeHash","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"NotApprovedByGateway","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotPauser","type":"error"},{"inputs":[],"name":"NotPendingPauser","type":"error"},{"inputs":[],"name":"NotProxy","type":"error"},{"inputs":[],"name":"SetupFailed","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"ZeroAddressProvided","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"name":"CrossMulticallExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"payloadHash","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"},{"indexed":true,"internalType":"address","name":"refundRecipient","type":"address"}],"name":"CrossMulticallFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"currentPauser","type":"address"},{"indexed":true,"internalType":"address","name":"pendingPauser","type":"address"}],"name":"PauserProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingPauser","type":"address"}],"name":"PauserUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"FORECALLERS_SALT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptPauser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"amountPostFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasRefundRecipient","type":"address"},{"internalType":"bool","name":"enableExpress","type":"bool"}],"name":"bridgeCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"},{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"}],"name":"callBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"},{"internalType":"string","name":"bridgedTokenSymbol","type":"string"},{"internalType":"string","name":"destinationChain","type":"string"},{"internalType":"string","name":"destinationAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"address","name":"gasRefundRecipient","type":"address"},{"internalType":"bool","name":"enableExpress","type":"bool"}],"name":"callBridgeCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractId","outputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"executeWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"forecall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"forecallWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"enum ISquidMulticall.CallType","name":"callType","type":"uint8"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct ISquidMulticall.Call[]","name":"calls","type":"tuple[]"}],"name":"fundAndRunMulticall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"getForecaller","outputs":[{"internalType":"address","name":"forecaller","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getForecallerWithToken","outputs":[{"internalType":"address","name":"forecaller","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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"value","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauser","outputs":[{"internalType":"address","name":"value","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingPauser","outputs":[{"internalType":"address","name":"value","type":"address"}],"stateMutability":"view","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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPauser","type":"address"}],"name":"updatePauser","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"}]

61010034620001e857601f620035b938819003918201601f19168301916001600160401b03831184841017620001ed57808492608094604052833981010312620001e8576200004e8162000203565b906200005d6020820162000203565b906200007a6060620000726040840162000203565b920162000203565b6001600160a01b039390929084168015620001d657608052337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379558360405191337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a2169081158015620001cb575b8015620001c0575b620001b1575060a052821660c0521660e0526040516133a090816200021982396080518181816102ec01528181610ef40152818161175f01528181611b3801528181611e5e015281816120310152818161211a01528181612234015281816125440152612edc015260a0518161311e015260c05181612ff8015260e05181818161049b01528181610df301528181610e6c01528181610fad0152818161138c0152818161145d015281816116e50152818161197401526122d80152f35b638474420160e01b8152600490fd5b5084841615620000f4565b5084831615620000ec565b60405163e6c4247b60e01b8152600490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001e85756fe60c0604052600436101561001257600080fd5b6000803560e01c806309cc027b146125c15780630d38218a14612568578063116191b6146124f9578063167a6f90146124135780631a98b2e014611ec95780632147796014611d265780633ca2fd8e14611cc85780633f4ba83a14611c115780634916065814611a1b57806352c41eb6146115c8578063554bab3c1461150457806358181a80146112d05780635c60da1b1461125f5780635c975abb146112025780638291286c146111a95780638456cb59146110c7578063846a1bc614610c7c5780638da5cb5b14610c0b5780639a7165e414610b9a5780639ded06df14610a4b5780639fd0506d146109da578063a3499c731461070b578063d0224434146106ad578063e888e86c14610279578063f2fde38b1461017b5763facd28a91461013b57600080fd5b3461017857602061015a61014e36612989565b94939093929192612aaf565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b80fd5b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576101b36126b5565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0805473ffffffffffffffffffffffffffffffffffffffff90813391160361024f5782168015610225577f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc6861638480a25580f35b60046040517f49e27cff000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b50346101785761028836612612565b6040989194969293959851977f935b13f600000000000000000000000000000000000000000000000000000000998a8a52602060048b01528b8a602081806102d4602482018d8d612a0d565b0373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169e8f5afa80156106155789898c8e6103488a80966103519873ffffffffffffffffffffffffffffffffffffffff9a9161068e575b503390612c84565b878c8a8d612b4a565b166106645761039f9287878a8c610373956040519a8b9860208a019b8c612aea565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612789565b339151902055828401906040858303126106605784359567ffffffffffffffff871161065c576103d660209361041598880161296e565b9373ffffffffffffffffffffffffffffffffffffffff6103f78589016126d8565b16986040519889948593849384528760048501526024840191612a0d565b03915afa938415610651578694610620575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa9283156106155782936105d9575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166104c6848289613183565b803b156105d55761050a83929183926040519586809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af191826105bd575b5050610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b98612bc7565b3691612804565b6020815191012092604051918291602083526020830190612ced565b0390a380f35b5061058f935036925090612804565b602081519101207f7c3aa10c5d96985be6de7d2e6fa79bdef95a95a9cb272f4113b3fe1ca89fedae8280a280f35b6105c69061272a565b6105d1578638610515565b8680fd5b8280fd5b915091506020813d60201161060d575b816105f660209383612789565b81010312610608578690519138610483565b600080fd5b3d91506105e9565b6040513d84823e3d90fd5b61064391945060203d60201161064a575b61063b8183612789565b810190612b6b565b9238610427565b503d610631565b6040513d88823e3d90fd5b8880fd5b8780fd5b60046040517f35b7d550000000000000000000000000000000000000000000000000000000008152fd5b6106a7915060203d60201161064a5761063b8183612789565b38610340565b5034610178576106bc36612989565b73ffffffffffffffffffffffffffffffffffffffff6106e4828486888a8c9b99989a9c612aaf565b16610664576107029361037392604051978895602087019889612a4c565b33915190205580f35b50346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107436126b5565b60443567ffffffffffffffff81116105d5576107639036906004016125e4565b907f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff90813391160361024f578316916040517f8291286c000000000000000000000000000000000000000000000000000000008082526020918281600481895afa9081156109a25788916109ad575b506040519182528282600481305afa9182156109a2578892610973575b500361094957843f6024350361091f57859282610869575b505050807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b91a27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580f35b6108d984936108ad604051938492868401967f9ded06df00000000000000000000000000000000000000000000000000000000885260248501526044840191612a0d565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612789565b5190855af46108e6612b97565b50156108f5578238808061081d565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f84fb24000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b9091508281813d831161099b575b61098b8183612789565b8101031261060857519038610805565b503d610981565b6040513d8a823e3d90fd5b90508281813d83116109d3575b6109c48183612789565b810103126106085751386107e8565b503d6109ba565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610b9657610a9b9036906004016125e4565b9073ffffffffffffffffffffffffffffffffffffffff91827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541615610b6c5781602091810103126105d557610af0906126d8565b168015610b4257807f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379557fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a280f35b60046040517f84744201000000000000000000000000000000000000000000000000000000008152fd5b60046040517fbf10dd3a000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b506101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610cb06126b5565b67ffffffffffffffff906044358281116110c357610cd29036906004016126f9565b916064358481116110bf57610ceb9036906004016125e4565b93909260843586811161066057610d069036906004016125e4565b60a4979197358281116110bb57610d219036906004016125e4565b93909260c4359081116110b757610d3c9036906004016125e4565b96909573ffffffffffffffffffffffffffffffffffffffff60e4351660e43503610608576101043515156101043503610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b92610da2913691612859565b90829073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee03610f765750506024355b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b156105d557610e5391839160405180809581947ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b039173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af1801561061557610f62575b5050604051977f935b13f6000000000000000000000000000000000000000000000000000000008952602060048a015260208980610edb602482018c8c612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa8015610f5757610f36998b91610f39575b50610104359860e43598612e5d565b80f35b610f51915060203d811161064a5761063b8183612789565b38610f27565b6040513d8c823e3d90fd5b610f6b9061272a565b61065c578838610e99565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000060208201908152336024808401919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16604484015235606483015292949192829161100081608481016108ad565b519082855af161100e612b97565b8161105e575b5015908115611054575b5061102a578a91610ddc565b60046040517f90b8ec18000000000000000000000000000000000000000000000000000000008152fd5b90503b153861101e565b8051801592508215611073575b505038611014565b6110869250602080918301019101612ad2565b388061106b565b60046040517f6d39fcd0000000000000000000000000000000000000000000000000000000008152fd5b8a80fd5b8980fd5b8580fd5b8380fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f5760017fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e7528180a180f35b60046040517f492f6781000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae848152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c546040519015158152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576113036126b5565b6024359060443567ffffffffffffffff81116110c35761132790369060040161296e565b7fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d5783928373ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85821614600014611415575050915b7f00000000000000000000000000000000000000000000000000000000000000001690813b156114105783916113ef916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af18015610615576114005750f35b6114099061272a565b6101785780f35b505050fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008816166044830152606482019490945294959194909282916114a181608481016108ad565b519082855af16114af612b97565b816114d5575b50159081156114cb575b5061102a57839261138a565b90503b15386114bf565b80518015925082156114ea575b5050386114b5565b6114fd9250602080918301019101612ad2565b38806114e2565b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761153c6126b5565b73ffffffffffffffffffffffffffffffffffffffff90817f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025516337f3210edd3f0fc490ffc59a4adae6f48dbda2d8e89afe5b37a0145a54762f3ecf98380a380f35b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b96576115fc6126b5565b67ffffffffffffffff91602435916044358481116110bf576116229036906004016126f9565b90946064358181116106605761163c9036906004016125e4565b936084358381116110bb576116559036906004016125e4565b91909360a4359081116110b7576116709036906004016125e4565b9890957fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b9a6116a6913691612859565b908a73ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8582161460001461192c575050905b827f00000000000000000000000000000000000000000000000000000000000000001690813b15611928578b91611748916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908115610f57578a91611914575b5050807f00000000000000000000000000000000000000000000000000000000000000001694604051917f935b13f60000000000000000000000000000000000000000000000000000000083526020928360048201528381806117c1602482018d8b612a0d565b03818b5afa9081156118e95784908d926118f4575b5060249192604051928380927f70a0823100000000000000000000000000000000000000000000000000000000825230600483015286165afa9384156118e9578c946118b4575b5050828761182a92613183565b853b156110bb57899761187e97899561188e61189d946040519d8e9c8d9b8c9a7f26ef699d000000000000000000000000000000000000000000000000000000008c52608060048d015260848c0191612a0d565b91868a84030160248b0152612a0d565b92868403016044870152612a0d565b90606483015203925af18015610615576114005750f35b819c50809294503d83116118e2575b6118cd8183612789565b810103126106085798518a999091808761181d565b503d6118c3565b6040513d8e823e3d90fd5b6024925061190e90823d841161064a5761063b8183612789565b916117d6565b61191d9061272a565b61065c57883861175a565b8b80fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000088161660448301526064820194909452939c9193909282916119b881608481016108ad565b519082855af16119c6612b97565b816119ec575b50159081156119e2575b5061102a578a996116e2565b90503b15386119d6565b8051801592508215611a01575b5050386119cc565b611a149250602080918301019101612ad2565b38806119f9565b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608081360112610b965767ffffffffffffffff906024358281116110c357611a6e9036906004016125e4565b9290916044358281116110bf57611a899036906004016125e4565b9490926064359081116105d157611aa49036906004016125e4565b959092611ab2368886612804565b6020815191012090611b12604051917f5f6970c3000000000000000000000000000000000000000000000000000000008352600435600484015260806024840152611b0160848401878b612a0d565b908382030160448401528488612a0d565b9160648201526020818073ffffffffffffffffffffffffffffffffffffffff9403818c867f0000000000000000000000000000000000000000000000000000000000000000165af1908115611c06578991611bd8575b5015611bae57611b7c87858488878b612aaf565b1615611ba557600095611b9e936108ad9260405196879560208701998a612a4c565b5190205580f35b50505050505080f35b60046040517f500c44b4000000000000000000000000000000000000000000000000000000008152fd5b611bf9915060203d8111611bff575b611bf18183612789565b810190612ad2565b38611b68565b503d611be7565b6040513d8b823e3d90fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d169338180a180f35b50346101785760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760243567ffffffffffffffff8111610b9657611d189036906004016125e4565b505060206040516004358152f35b5060e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785767ffffffffffffffff6004358181116105d557611d729036906004016125e4565b9091604435818111611ec557611d8c9036906004016125e4565b6064929192358281116105d157611da79036906004016125e4565b909260843590811161066057611dc19036906004016125e4565b93909260a4359573ffffffffffffffffffffffffffffffffffffffff9889881688036106085760c435988915158a03610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d576020604051809c7f935b13f60000000000000000000000000000000000000000000000000000000082528260048301528180611e5a602482018789612a0d565b03917f0000000000000000000000000000000000000000000000000000000000000000165afa9182156118e957610f369b8d93611ea5575b50611ea06024353385612c84565b612e5d565b611ebe91935060203d811161064a5761063b8183612789565b9138611e92565b8480fd5b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b965760243567ffffffffffffffff81116105d557611f1a9036906004016125e4565b9160443567ffffffffffffffff8111611ec557611f3b9036906004016125e4565b60649491943567ffffffffffffffff81116105d157611f5e9036906004016125e4565b9590946084359667ffffffffffffffff881161065c5761200f611f8760209936906004016125e4565b999097611f9536858c612804565b8281519101209060405193849283927f1876eed9000000000000000000000000000000000000000000000000000000008452600435600485015260c06024850152611ff9611fe88d60c48701908c612a0d565b828682030160448701528c8c612a0d565b9160648501528382030160848401528d8c612a0d565b60a43560a483015203818d73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af1908115610f57578a916123f4575b5015611bae5761207a60a4358988848b89898c8a612b4a565b9673ffffffffffffffffffffffffffffffffffffffff881615612184576000936108ad8897948b60209a6121019d99966120c2966040519889978f89019b60a435978d612aea565b5190205560405194859283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561217957610f36928492612158575b5060a43591612bc7565b61217291925060203d60201161064a5761063b8183612789565b903861214e565b6040513d85823e3d90fd5b9596509350505050808201926040838503126110bf5782359367ffffffffffffffff85116105d1576121bd60209161221b96860161296e565b9173ffffffffffffffffffffffffffffffffffffffff6121de8387016126d8565b169660405196879283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9384156106515786946123d3575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa92831561061557829361239f575b5073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690612304848389613183565b813b156105d5578291612346916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908161238c575b50610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b6123989097919761272a565b9538612351565b9092506020813d6020116123cb575b816123bb60209383612789565b81010312610b96575191386122c0565b3d91506123ae565b6123ed91945060203d60201161064a5761063b8183612789565b9238612264565b61240d915060203d602011611bff57611bf18183612789565b38612061565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178577fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb93970273ffffffffffffffffffffffffffffffffffffffff81541633036124cf578190337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c37955337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab8380a25580f35b60046040517fb3a270d8000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f8152f35b503461017857602061015a6125d536612612565b97969096959195949294612b4a565b9181601f840112156106085782359167ffffffffffffffff8311610608576020838186019501011161060857565b60a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126106085767ffffffffffffffff90600435828111610608578161265d916004016125e4565b939093926024358181116106085783612678916004016125e4565b939093926044358381116106085782612693916004016125e4565b93909392606435918211610608576126ad916004016125e4565b909160843590565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b9181601f840112156106085782359167ffffffffffffffff8311610608576020808501948460051b01011161060857565b67ffffffffffffffff811161273e57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761273e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761273e57604052565b67ffffffffffffffff811161273e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192612810826127ca565b9161281e6040519384612789565b829481845281830111610608578281602093846000960137010152565b9080601f830112156106085781602061285693359101612804565b90565b9291909267ffffffffffffffff80851161273e578460051b60408051946020809661288682860182612789565b8099815201928501948186116106085780935b8685106128aa575050505050505050565b843586811161060857820160a091828286031261060857855192830183811089821117612940578652813560048110156106085783526128eb8a83016126d8565b8a8401528582013586840152606080830135898111610608578661291091850161283b565b90840152608092838301359389851161060857612931878d9687960161283b565b90820152815201940193612899565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9080601f830112156106085781602061285693359101612859565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126106085767ffffffffffffffff60043581811161060857836129d4916004016125e4565b9390939260243583811161060857826129ef916004016125e4565b9390939260443591821161060857612a09916004016125e4565b9091565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b969590612aaa93606095612a8e612a9c937fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999660808d5260808d0191612a0d565b918a830360208c0152612a0d565b918783036040890152612a0d565b930152565b946108ad919294612acb9460405196879560208701998a612a4c565b5190205490565b90816020910312610608575180151581036106085790565b95612a9c7fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999460a09996612a8e612b4099959d9e9d612b329760c08d5260c08d0191612a0d565b918483036060860152612a0d565b9460808201520152565b9792946108ad94612acb979296989398604051998a9860208a019c8d612aea565b90816020910312610608575173ffffffffffffffffffffffffffffffffffffffff811681036106085790565b3d15612bc2573d90612ba8826127ca565b91612bb66040519384612789565b82523d6000602084013e565b606090565b9160009182916040519073ffffffffffffffffffffffffffffffffffffffff60208301937fa9059cbb000000000000000000000000000000000000000000000000000000008552166024830152604482015260448152612c268161276d565b519082855af1612c34612b97565b81612c55575b5015908115612c4b575b5061102a57565b90503b1538612c44565b8051801592508215612c6a575b505038612c3a565b612c7d9250602080918301019101612ad2565b3880612c62565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff90931660248201523060448201526064810193909352916000918291612c2681608481016108ad565b919082519283825260005b848110612d375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612cf8565b602080820181835283518091526040918284019381848460051b83010196019460009485925b858410612d8357505050505050505090565b90919293949596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082820301845288518051600480821015612e315750612e1f83899384936001965273ffffffffffffffffffffffffffffffffffffffff8482015116848301528781015188830152612e0c6060808301519060a08091860152840190612ced565b9160808092015191818403910152612ced565b9a019401940192969594939190612d71565b8a60216024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b919992949698999790959760805260a0526040968751927f70a0823100000000000000000000000000000000000000000000000000000000845260009a30600486015273ffffffffffffffffffffffffffffffffffffffff9160208660248186608051165afa958615613179578d96613142575b5047612ff0575b50507f00000000000000000000000000000000000000000000000000000000000000001695612f0a8488608051613183565b863b156110b757918a9796959492918894928a519b8c998a9889977fb54170840000000000000000000000000000000000000000000000000000000089526004890160a0905260a4890190612f5e92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858983030160248a0152612f9392612a0d565b8387820301604488015260a051612fa992612a0d565b91858303016064860152612fbc92612a0d565b90608483015203925af1908115612fe75750612fd6575050565b612fe0829161272a565b6101785750565b513d84823e3d90fd5b1561311b57817f00000000000000000000000000000000000000000000000000000000000000005b16904790823b15613117578c92898f938a8f948f958f8b8d918c93519b8c9a8b998a987fc62c2002000000000000000000000000000000000000000000000000000000008a523060048b015260248a0160e0905260e48a019061307a92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858a83030160448b01526130af92612a0d565b8388820301606489015260a0516130c592612a0d565b918683030160848701526130d892612a0d565b918d60a48501521660c483015203925af1801561310d576130fa575b80612ed8565b613106909b919b61272a565b99386130f4565b8a513d8e823e3d90fd5b8d80fd5b817f0000000000000000000000000000000000000000000000000000000000000000613018565b9095506020813d8211613171575b8161315d60209383612789565b8101031261316d57519438612ed1565b8c80fd5b3d9150613150565b8b513d8f823e3d90fd5b90604092835180917fdd62ed3e00000000000000000000000000000000000000000000000000000000825230600483015273ffffffffffffffffffffffffffffffffffffffff80941693846024840152826044602095869389165afa91821561335f57600092613330575b5081106131fd575b5050505050565b6132af575b91600092918380938651908101927f095ea7b300000000000000000000000000000000000000000000000000000000845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60448201526044815261326b8161276d565b51925af1613277612b97565b501561328657808080806131f6565b600490517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b6000808551838101907f095ea7b3000000000000000000000000000000000000000000000000000000008252856024820152826044820152604481526132f48161276d565b519082875af1613302612b97565b5061320257600484517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b90918382813d8311613358575b6133478183612789565b8101031261017857505190386131ee565b503d61333d565b86513d6000823e3d90fdfea264697066735822122092b491d862f5d7f0f51a05f1561f5c4485044ab0040ff8acdc07f03b840cac9b64736f6c634300081400330000000000000000000000004f4495243837681061c4743b74b3eedf548d56a50000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3

Deployed Bytecode

0x60c0604052600436101561001257600080fd5b6000803560e01c806309cc027b146125c15780630d38218a14612568578063116191b6146124f9578063167a6f90146124135780631a98b2e014611ec95780632147796014611d265780633ca2fd8e14611cc85780633f4ba83a14611c115780634916065814611a1b57806352c41eb6146115c8578063554bab3c1461150457806358181a80146112d05780635c60da1b1461125f5780635c975abb146112025780638291286c146111a95780638456cb59146110c7578063846a1bc614610c7c5780638da5cb5b14610c0b5780639a7165e414610b9a5780639ded06df14610a4b5780639fd0506d146109da578063a3499c731461070b578063d0224434146106ad578063e888e86c14610279578063f2fde38b1461017b5763facd28a91461013b57600080fd5b3461017857602061015a61014e36612989565b94939093929192612aaf565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b80fd5b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576101b36126b5565b7f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0805473ffffffffffffffffffffffffffffffffffffffff90813391160361024f5782168015610225577f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc6861638480a25580f35b60046040517f49e27cff000000000000000000000000000000000000000000000000000000008152fd5b60046040517f30cd7471000000000000000000000000000000000000000000000000000000008152fd5b50346101785761028836612612565b6040989194969293959851977f935b13f600000000000000000000000000000000000000000000000000000000998a8a52602060048b01528b8a602081806102d4602482018d8d612a0d565b0373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5169e8f5afa80156106155789898c8e6103488a80966103519873ffffffffffffffffffffffffffffffffffffffff9a9161068e575b503390612c84565b878c8a8d612b4a565b166106645761039f9287878a8c610373956040519a8b9860208a019b8c612aea565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612789565b339151902055828401906040858303126106605784359567ffffffffffffffff871161065c576103d660209361041598880161296e565b9373ffffffffffffffffffffffffffffffffffffffff6103f78589016126d8565b16986040519889948593849384528760048501526024840191612a0d565b03915afa938415610651578694610620575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa9283156106155782936105d9575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3166104c6848289613183565b803b156105d55761050a83929183926040519586809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af191826105bd575b5050610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b98612bc7565b3691612804565b6020815191012092604051918291602083526020830190612ced565b0390a380f35b5061058f935036925090612804565b602081519101207f7c3aa10c5d96985be6de7d2e6fa79bdef95a95a9cb272f4113b3fe1ca89fedae8280a280f35b6105c69061272a565b6105d1578638610515565b8680fd5b8280fd5b915091506020813d60201161060d575b816105f660209383612789565b81010312610608578690519138610483565b600080fd5b3d91506105e9565b6040513d84823e3d90fd5b61064391945060203d60201161064a575b61063b8183612789565b810190612b6b565b9238610427565b503d610631565b6040513d88823e3d90fd5b8880fd5b8780fd5b60046040517f35b7d550000000000000000000000000000000000000000000000000000000008152fd5b6106a7915060203d60201161064a5761063b8183612789565b38610340565b5034610178576106bc36612989565b73ffffffffffffffffffffffffffffffffffffffff6106e4828486888a8c9b99989a9c612aaf565b16610664576107029361037392604051978895602087019889612a4c565b33915190205580f35b50346101785760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576107436126b5565b60443567ffffffffffffffff81116105d5576107639036906004016125e4565b907f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff90813391160361024f578316916040517f8291286c000000000000000000000000000000000000000000000000000000008082526020918281600481895afa9081156109a25788916109ad575b506040519182528282600481305afa9182156109a2578892610973575b500361094957843f6024350361091f57859282610869575b505050807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b91a27f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5580f35b6108d984936108ad604051938492868401967f9ded06df00000000000000000000000000000000000000000000000000000000885260248501526044840191612a0d565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612789565b5190855af46108e6612b97565b50156108f5578238808061081d565b60046040517f97905dfb000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f84fb24000000000000000000000000000000000000000000000000000000008152fd5b60046040517f68155f9a000000000000000000000000000000000000000000000000000000008152fd5b9091508281813d831161099b575b61098b8183612789565b8101031261060857519038610805565b503d610981565b6040513d8a823e3d90fd5b90508281813d83116109d3575b6109c48183612789565b810103126106085751386107e8565b503d6109ba565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760043567ffffffffffffffff8111610b9657610a9b9036906004016125e4565b9073ffffffffffffffffffffffffffffffffffffffff91827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc541615610b6c5781602091810103126105d557610af0906126d8565b168015610b4257807f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c379557fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab600080a280f35b60046040517f84744201000000000000000000000000000000000000000000000000000000008152fd5b60046040517fbf10dd3a000000000000000000000000000000000000000000000000000000008152fd5b5080fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c05473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b506101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857610cb06126b5565b67ffffffffffffffff906044358281116110c357610cd29036906004016126f9565b916064358481116110bf57610ceb9036906004016125e4565b93909260843586811161066057610d069036906004016125e4565b60a4979197358281116110bb57610d219036906004016125e4565b93909260c4359081116110b757610d3c9036906004016125e4565b96909573ffffffffffffffffffffffffffffffffffffffff60e4351660e43503610608576101043515156101043503610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b92610da2913691612859565b90829073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee03610f765750506024355b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3163b156105d557610e5391839160405180809581947ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b039173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3165af1801561061557610f62575b5050604051977f935b13f6000000000000000000000000000000000000000000000000000000008952602060048a015260208980610edb602482018c8c612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa8015610f5757610f36998b91610f39575b50610104359860e43598612e5d565b80f35b610f51915060203d811161064a5761063b8183612789565b38610f27565b6040513d8c823e3d90fd5b610f6b9061272a565b61065c578838610e99565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000060208201908152336024808401919091527f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd373ffffffffffffffffffffffffffffffffffffffff16604484015235606483015292949192829161100081608481016108ad565b519082855af161100e612b97565b8161105e575b5015908115611054575b5061102a578a91610ddc565b60046040517f90b8ec18000000000000000000000000000000000000000000000000000000008152fd5b90503b153861101e565b8051801592508215611073575b505038611014565b6110869250602080918301019101612ad2565b388061106b565b60046040517f6d39fcd0000000000000000000000000000000000000000000000000000000008152fd5b8a80fd5b8980fd5b8580fd5b8380fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f5760017fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e7528180a180f35b60046040517f492f6781000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fc097d45e5a99ca772ab5ec2e5457c2e249760944b95b0b97cbb6b03ec55bae848152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c546040519015158152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760207f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178576113036126b5565b6024359060443567ffffffffffffffff81116110c35761132790369060040161296e565b7fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d5783928373ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee85821614600014611415575050915b7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690813b156114105783916113ef916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af18015610615576114005750f35b6114099061272a565b6101785780f35b505050fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd38816166044830152606482019490945294959194909282916114a181608481016108ad565b519082855af16114af612b97565b816114d5575b50159081156114cb575b5061102a57839261138a565b90503b15386114bf565b80518015925082156114ea575b5050386114b5565b6114fd9250602080918301019101612ad2565b38806114e2565b50346101785760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785761153c6126b5565b73ffffffffffffffffffffffffffffffffffffffff90817f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb9397025516337f3210edd3f0fc490ffc59a4adae6f48dbda2d8e89afe5b37a0145a54762f3ecf98380a380f35b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b96576115fc6126b5565b67ffffffffffffffff91602435916044358481116110bf576116229036906004016126f9565b90946064358181116106605761163c9036906004016125e4565b936084358381116110bb576116559036906004016125e4565b91909360a4359081116110b7576116709036906004016125e4565b9890957fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d578b9a6116a6913691612859565b908a73ffffffffffffffffffffffffffffffffffffffff9373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8582161460001461192c575050905b827f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690813b15611928578b91611748916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908115610f57578a91611914575b5050807f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a51694604051917f935b13f60000000000000000000000000000000000000000000000000000000083526020928360048201528381806117c1602482018d8b612a0d565b03818b5afa9081156118e95784908d926118f4575b5060249192604051928380927f70a0823100000000000000000000000000000000000000000000000000000000825230600483015286165afa9384156118e9578c946118b4575b5050828761182a92613183565b853b156110bb57899761187e97899561188e61189d946040519d8e9c8d9b8c9a7f26ef699d000000000000000000000000000000000000000000000000000000008c52608060048d015260848c0191612a0d565b91868a84030160248b0152612a0d565b92868403016044870152612a0d565b90606483015203925af18015610615576114005750f35b819c50809294503d83116118e2575b6118cd8183612789565b810103126106085798518a999091808761181d565b503d6118c3565b6040513d8e823e3d90fd5b6024925061190e90823d841161064a5761063b8183612789565b916117d6565b61191d9061272a565b61065c57883861175a565b8b80fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815233602483015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd388161660448301526064820194909452939c9193909282916119b881608481016108ad565b519082855af16119c6612b97565b816119ec575b50159081156119e2575b5061102a578a996116e2565b90503b15386119d6565b8051801592508215611a01575b5050386119cc565b611a149250602080918301019101612ad2565b38806119f9565b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc608081360112610b965767ffffffffffffffff906024358281116110c357611a6e9036906004016125e4565b9290916044358281116110bf57611a899036906004016125e4565b9490926064359081116105d157611aa49036906004016125e4565b959092611ab2368886612804565b6020815191012090611b12604051917f5f6970c3000000000000000000000000000000000000000000000000000000008352600435600484015260806024840152611b0160848401878b612a0d565b908382030160448401528488612a0d565b9160648201526020818073ffffffffffffffffffffffffffffffffffffffff9403818c867f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165af1908115611c06578991611bd8575b5015611bae57611b7c87858488878b612aaf565b1615611ba557600095611b9e936108ad9260405196879560208701998a612a4c565b5190205580f35b50505050505080f35b60046040517f500c44b4000000000000000000000000000000000000000000000000000000008152fd5b611bf9915060203d8111611bff575b611bf18183612789565b810190612ad2565b38611b68565b503d611be7565b6040513d8b823e3d90fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785773ffffffffffffffffffffffffffffffffffffffff7f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c3795416330361117f57807fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c557fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d169338180a180f35b50346101785760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760243567ffffffffffffffff8111610b9657611d189036906004016125e4565b505060206040516004358152f35b5060e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785767ffffffffffffffff6004358181116105d557611d729036906004016125e4565b9091604435818111611ec557611d8c9036906004016125e4565b6064929192358281116105d157611da79036906004016125e4565b909260843590811161066057611dc19036906004016125e4565b93909260a4359573ffffffffffffffffffffffffffffffffffffffff9889881688036106085760c435988915158a03610608577fa42f2cf999e26109eb49cb7eef3654cc55b677b2db805f3eab8722cc5dd1af0c5461108d576020604051809c7f935b13f60000000000000000000000000000000000000000000000000000000082528260048301528180611e5a602482018789612a0d565b03917f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa9182156118e957610f369b8d93611ea5575b50611ea06024353385612c84565b612e5d565b611ebe91935060203d811161064a5761063b8183612789565b9138611e92565b8480fd5b5034610178577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c081360112610b965760243567ffffffffffffffff81116105d557611f1a9036906004016125e4565b9160443567ffffffffffffffff8111611ec557611f3b9036906004016125e4565b60649491943567ffffffffffffffff81116105d157611f5e9036906004016125e4565b9590946084359667ffffffffffffffff881161065c5761200f611f8760209936906004016125e4565b999097611f9536858c612804565b8281519101209060405193849283927f1876eed9000000000000000000000000000000000000000000000000000000008452600435600485015260c06024850152611ff9611fe88d60c48701908c612a0d565b828682030160448701528c8c612a0d565b9160648501528382030160848401528d8c612a0d565b60a43560a483015203818d73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165af1908115610f57578a916123f4575b5015611bae5761207a60a4358988848b89898c8a612b4a565b9673ffffffffffffffffffffffffffffffffffffffff881615612184576000936108ad8897948b60209a6121019d99966120c2966040519889978f89019b60a435978d612aea565b5190205560405194859283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa90811561217957610f36928492612158575b5060a43591612bc7565b61217291925060203d60201161064a5761063b8183612789565b903861214e565b6040513d85823e3d90fd5b9596509350505050808201926040838503126110bf5782359367ffffffffffffffff85116105d1576121bd60209161221b96860161296e565b9173ffffffffffffffffffffffffffffffffffffffff6121de8387016126d8565b169660405196879283927f935b13f60000000000000000000000000000000000000000000000000000000084528560048501526024840191612a0d565b038173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5165afa9384156106515786946123d3575b5085604051917f70a0823100000000000000000000000000000000000000000000000000000000835230600484015260208360248173ffffffffffffffffffffffffffffffffffffffff8a165afa92831561061557829361239f575b5073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd31690612304848389613183565b813b156105d5578291612346916040519485809481937ff87ef80000000000000000000000000000000000000000000000000000000000835260048301612d4b565b03925af1908161238c575b50610580577fdd7b1484db8d21f4fbda2407f2920037dc379dd66e18b0851aa9d6c14ef493b99261057a9261055761055e9388610551612b97565b6123989097919761272a565b9538612351565b9092506020813d6020116123cb575b816123bb60209383612789565b81010312610b96575191386122c0565b3d91506123ae565b6123ed91945060203d60201161064a5761063b8183612789565b9238612264565b61240d915060203d602011611bff57611bf18183612789565b38612061565b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610178577fe330cfee289e568e8774e923acd6e2a00f84be86aa1d02356835d33dbb93970273ffffffffffffffffffffffffffffffffffffffff81541633036124cf578190337f23e06a2ed150be3aaebbce1156aecc5187e5e955ea717a17e165cca37ef8c37955337fa4336c0cb1e245b95ad204faed7e940d6dc999684fd8b5e1ff597a0c4efca8ab8380a25580f35b60046040517fb3a270d8000000000000000000000000000000000000000000000000000000008152fd5b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261017857602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5168152f35b503461017857807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101785760206040517fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f8152f35b503461017857602061015a6125d536612612565b97969096959195949294612b4a565b9181601f840112156106085782359167ffffffffffffffff8311610608576020838186019501011161060857565b60a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126106085767ffffffffffffffff90600435828111610608578161265d916004016125e4565b939093926024358181116106085783612678916004016125e4565b939093926044358381116106085782612693916004016125e4565b93909392606435918211610608576126ad916004016125e4565b909160843590565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b359073ffffffffffffffffffffffffffffffffffffffff8216820361060857565b9181601f840112156106085782359167ffffffffffffffff8311610608576020808501948460051b01011161060857565b67ffffffffffffffff811161273e57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761273e57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761273e57604052565b67ffffffffffffffff811161273e57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192612810826127ca565b9161281e6040519384612789565b829481845281830111610608578281602093846000960137010152565b9080601f830112156106085781602061285693359101612804565b90565b9291909267ffffffffffffffff80851161273e578460051b60408051946020809661288682860182612789565b8099815201928501948186116106085780935b8685106128aa575050505050505050565b843586811161060857820160a091828286031261060857855192830183811089821117612940578652813560048110156106085783526128eb8a83016126d8565b8a8401528582013586840152606080830135898111610608578661291091850161283b565b90840152608092838301359389851161060857612931878d9687960161283b565b90820152815201940193612899565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9080601f830112156106085781602061285693359101612859565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126106085767ffffffffffffffff60043581811161060857836129d4916004016125e4565b9390939260243583811161060857826129ef916004016125e4565b9390939260443591821161060857612a09916004016125e4565b9091565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b969590612aaa93606095612a8e612a9c937fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999660808d5260808d0191612a0d565b918a830360208c0152612a0d565b918783036040890152612a0d565b930152565b946108ad919294612acb9460405196879560208701998a612a4c565b5190205490565b90816020910312610608575180151581036106085790565b95612a9c7fdb79ee324babd8834c3c1a1a2739c004fce73b812ac9f637241ff47b19e4b71f999460a09996612a8e612b4099959d9e9d612b329760c08d5260c08d0191612a0d565b918483036060860152612a0d565b9460808201520152565b9792946108ad94612acb979296989398604051998a9860208a019c8d612aea565b90816020910312610608575173ffffffffffffffffffffffffffffffffffffffff811681036106085790565b3d15612bc2573d90612ba8826127ca565b91612bb66040519384612789565b82523d6000602084013e565b606090565b9160009182916040519073ffffffffffffffffffffffffffffffffffffffff60208301937fa9059cbb000000000000000000000000000000000000000000000000000000008552166024830152604482015260448152612c268161276d565b519082855af1612c34612b97565b81612c55575b5015908115612c4b575b5061102a57565b90503b1538612c44565b8051801592508215612c6a575b505038612c3a565b612c7d9250602080918301019101612ad2565b3880612c62565b6040517f23b872dd000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff90931660248201523060448201526064810193909352916000918291612c2681608481016108ad565b919082519283825260005b848110612d375750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8460006020809697860101520116010190565b602081830181015184830182015201612cf8565b602080820181835283518091526040918284019381848460051b83010196019460009485925b858410612d8357505050505050505090565b90919293949596977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082820301845288518051600480821015612e315750612e1f83899384936001965273ffffffffffffffffffffffffffffffffffffffff8482015116848301528781015188830152612e0c6060808301519060a08091860152840190612ced565b9160808092015191818403910152612ced565b9a019401940192969594939190612d71565b8a60216024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b919992949698999790959760805260a0526040968751927f70a0823100000000000000000000000000000000000000000000000000000000845260009a30600486015273ffffffffffffffffffffffffffffffffffffffff9160208660248186608051165afa958615613179578d96613142575b5047612ff0575b50507f0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a51695612f0a8488608051613183565b863b156110b757918a9796959492918894928a519b8c998a9889977fb54170840000000000000000000000000000000000000000000000000000000089526004890160a0905260a4890190612f5e92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858983030160248a0152612f9392612a0d565b8387820301604488015260a051612fa992612a0d565b91858303016064860152612fbc92612a0d565b90608483015203925af1908115612fe75750612fd6575050565b612fe0829161272a565b6101785750565b513d84823e3d90fd5b1561311b57817f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827125b16904790823b15613117578c92898f938a8f948f958f8b8d918c93519b8c9a8b998a987fc62c2002000000000000000000000000000000000000000000000000000000008a523060048b015260248a0160e0905260e48a019061307a92612a0d565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc94858a83030160448b01526130af92612a0d565b8388820301606489015260a0516130c592612a0d565b918683030160848701526130d892612a0d565b918d60a48501521660c483015203925af1801561310d576130fa575b80612ed8565b613106909b919b61272a565b99386130f4565b8a513d8e823e3d90fd5b8d80fd5b817f0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712613018565b9095506020813d8211613171575b8161315d60209383612789565b8101031261316d57519438612ed1565b8c80fd5b3d9150613150565b8b513d8f823e3d90fd5b90604092835180917fdd62ed3e00000000000000000000000000000000000000000000000000000000825230600483015273ffffffffffffffffffffffffffffffffffffffff80941693846024840152826044602095869389165afa91821561335f57600092613330575b5081106131fd575b5050505050565b6132af575b91600092918380938651908101927f095ea7b300000000000000000000000000000000000000000000000000000000845260248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60448201526044815261326b8161276d565b51925af1613277612b97565b501561328657808080806131f6565b600490517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b6000808551838101907f095ea7b3000000000000000000000000000000000000000000000000000000008252856024820152826044820152604481526132f48161276d565b519082875af1613302612b97565b5061320257600484517f8164f842000000000000000000000000000000000000000000000000000000008152fd5b90918382813d8311613358575b6133478183612789565b8101031261017857505190386131ee565b503d61333d565b86513d6000823e3d90fdfea264697066735822122092b491d862f5d7f0f51a05f1561f5c4485044ab0040ff8acdc07f03b840cac9b64736f6c63430008140033

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

0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a50000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000002d5d7d31f671f86c782533cc367f14109a0827120000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3

-----Decoded View---------------
Arg [0] : _gateway (address): 0x4F4495243837681061C4743b74B3eEdf548D56A5
Arg [1] : _gasService (address): 0x2d5d7d31F671F86C782533cc367F14109a082712
Arg [2] : _forecallGasService (address): 0x2d5d7d31F671F86C782533cc367F14109a082712
Arg [3] : _multicall (address): 0x4fd39C9E151e50580779bd04B1f7eCc310079fd3

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000004f4495243837681061c4743b74b3eedf548d56a5
Arg [1] : 0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712
Arg [2] : 0000000000000000000000002d5d7d31f671f86c782533cc367f14109a082712
Arg [3] : 0000000000000000000000004fd39c9e151e50580779bd04b1f7ecc310079fd3


Block Transaction Gas Used Reward
view all blocks collator

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

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.