Contract 0xC29D6110f18b1D03C75e8756617E7d0a5F5f9d70

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x3e89112a47a5f33db37cdb7ebe0e572fb5988da50ff0e7ab409b4be926da6391Set Token Peers111469352022-08-05 2:35:5455 days 11 hrs ago0xd71cb0c4a82c36312b5b83c43f351b882756957f IN  0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700 Ether0.00012164 2.5
0xc473a68d1e07b314a25a867a66ad70d20651dc19bbef0df2bb305e29a49222daSet Client Peers111469332022-08-05 2:35:2455 days 11 hrs ago0xd71cb0c4a82c36312b5b83c43f351b882756957f IN  0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700 Ether0.00011629 2.425
0xa5ed657598f80dd956be511425bd8f6b0f63179f1c2a00b0cd72cc2ca2d440970x60806040111468952022-08-05 2:25:5355 days 11 hrs ago0xd71cb0c4a82c36312b5b83c43f351b882756957f IN  Create: AnyswapTokenAnycallClient0 Ether0.0093117 2.5
[ Download CSV Export 
Latest 16 internal transactions
Parent Txn Hash Block From To Value
0x2368cf7fe5a9c3f0d4aec9bd129155c22565430d9dbb0d7757cfedec77cadf51111527852022-08-06 3:06:4254 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0x2368cf7fe5a9c3f0d4aec9bd129155c22565430d9dbb0d7757cfedec77cadf51111527852022-08-06 3:06:4254 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0x2368cf7fe5a9c3f0d4aec9bd129155c22565430d9dbb0d7757cfedec77cadf51111527852022-08-06 3:06:4254 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x332c97a68156351bd4e7bc4c96df79d199514f140 Ether
0x2368cf7fe5a9c3f0d4aec9bd129155c22565430d9dbb0d7757cfedec77cadf51111527852022-08-06 3:06:4254 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700x273a4ffceb31b8473d51051ad2a2edbb7ac8ce020 Ether
0x2368cf7fe5a9c3f0d4aec9bd129155c22565430d9dbb0d7757cfedec77cadf51111527852022-08-06 3:06:4254 days 11 hrs ago 0x332c97a68156351bd4e7bc4c96df79d199514f14 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700 Ether
0xb731f15a68ac7da8d54a4d88e8ad1316b83016308a071fbdba1944dd841bc269111473082022-08-05 4:09:3855 days 10 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0xb731f15a68ac7da8d54a4d88e8ad1316b83016308a071fbdba1944dd841bc269111473082022-08-05 4:09:3855 days 10 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0xb731f15a68ac7da8d54a4d88e8ad1316b83016308a071fbdba1944dd841bc269111473082022-08-05 4:09:3855 days 10 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x332c97a68156351bd4e7bc4c96df79d199514f140 Ether
0xb731f15a68ac7da8d54a4d88e8ad1316b83016308a071fbdba1944dd841bc269111473082022-08-05 4:09:3855 days 10 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700x273a4ffceb31b8473d51051ad2a2edbb7ac8ce020 Ether
0xb731f15a68ac7da8d54a4d88e8ad1316b83016308a071fbdba1944dd841bc269111473082022-08-05 4:09:3855 days 10 hrs ago 0x332c97a68156351bd4e7bc4c96df79d199514f14 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700 Ether
0xdf9337061e5650aaaf6f66e8daadedb5c3ea1381dd1578ee3a9d1f004c904824111469792022-08-05 2:46:5655 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0xdf9337061e5650aaaf6f66e8daadedb5c3ea1381dd1578ee3a9d1f004c904824111469792022-08-05 2:46:5655 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x8f9ad58819cb11036d5ff69d0e1a6392f9e9172a0 Ether
0xdf9337061e5650aaaf6f66e8daadedb5c3ea1381dd1578ee3a9d1f004c904824111469792022-08-05 2:46:5655 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d70 0x332c97a68156351bd4e7bc4c96df79d199514f140 Ether
0xdf9337061e5650aaaf6f66e8daadedb5c3ea1381dd1578ee3a9d1f004c904824111469792022-08-05 2:46:5655 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700x273a4ffceb31b8473d51051ad2a2edbb7ac8ce020 Ether
0xdf9337061e5650aaaf6f66e8daadedb5c3ea1381dd1578ee3a9d1f004c904824111469792022-08-05 2:46:5655 days 11 hrs ago 0x332c97a68156351bd4e7bc4c96df79d199514f14 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700 Ether
0xa5ed657598f80dd956be511425bd8f6b0f63179f1c2a00b0cd72cc2ca2d44097111468952022-08-05 2:25:5355 days 11 hrs ago 0xc29d6110f18b1d03c75e8756617e7d0a5f5f9d700x273a4ffceb31b8473d51051ad2a2edbb7ac8ce020 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AnyswapTokenAnycallClient

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 8 : bAnycallbridgetoken.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.6;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./access/PausableControlWithAdmin.sol";

/// three level architecture
/// top level is the `AnycallClient` which the users interact with (through UI or tools)
/// middle level is `AnyswapToken` which works as handlers and vaults for tokens
/// bottom level is the `AnycallProxy` which complete the cross-chain interaction

interface IApp {
    function anyExecute(bytes calldata _data) external returns (bool success, bytes memory result);
}

interface IAnyswapToken {
    function mint(address to, uint256 amount) external returns (bool);

    function burn(address from, uint256 amount) external returns (bool);
}

interface IAnycallExecutor {
    function context() external returns (address from, uint256 fromChainID, uint256 nonce);
}

interface IAnycallV6Proxy {
    function executor() external view returns (address);

    function anyCall(
        address _to,
        bytes calldata _data,
        address _fallback,
        uint256 _toChainID,
        uint256 _flags
    ) external payable;
}

abstract contract AnycallClientBase is IApp, PausableControlWithAdmin {
    address public callProxy;
    address public anycallExecutor;
    // associated client app on each chain
    mapping(uint256 => address) public clientPeers; // key is chainId

    modifier onlyExecutor() {
        require(msg.sender == anycallExecutor, "AnycallClient: not authorized");
        _;
    }



    constructor(address _admin, address _callProxy) PausableControlWithAdmin(_admin) {
        require(_callProxy != address(0));
        callProxy = _callProxy;
        anycallExecutor = IAnycallV6Proxy(callProxy).executor();
    }

    receive() external payable {
        require(msg.sender == callProxy, "AnycallClient: receive from forbidden sender");
    }

    function setCallProxy(address _callProxy) external onlyAdmin {
        require(_callProxy != address(0));
        callProxy = _callProxy;
        anycallExecutor = IAnycallV6Proxy(callProxy).executor();

    }

    function setClientPeers(
        uint256[] calldata _chainIds,
        address[] calldata _peers
    ) external onlyAdmin {
        require(_chainIds.length == _peers.length);
        for (uint256 i = 0; i < _chainIds.length; i++) {
            clientPeers[_chainIds[i]] = _peers[i];
        }
    }
}

contract AnyswapTokenAnycallClient is AnycallClientBase {
    using SafeERC20 for IERC20;

    // pausable control roles
    bytes32 public constant PAUSE_SWAPOUT_ROLE = keccak256("PAUSE_SWAPOUT_ROLE");
    bytes32 public constant PAUSE_SWAPIN_ROLE = keccak256("PAUSE_SWAPIN_ROLE");
    bytes32 public constant PAUSE_FALLBACK_ROLE = keccak256("PAUSE_FALLBACK_ROLE");

    // associated tokens on each chain
    mapping(address => mapping(uint256 => address)) public tokenPeers;

    event LogSwapout(
        address indexed token, address indexed sender, address indexed receiver,
        uint256 amount, uint256 toChainId
    );
    event LogSwapin(
        address indexed token, address indexed sender, address indexed receiver,
        uint256 amount, uint256 fromChainId
    );
    event LogSwapoutFail(
        address indexed token, address indexed sender, address indexed receiver,
        uint256 amount, uint256 toChainId
    );

    constructor(
        address _admin,
        address _callProxy
    ) AnycallClientBase(_admin, _callProxy) {
    }

    function setTokenPeers(
        address srcToken,
        uint256[] calldata chainIds,
        address[] calldata dstTokens
    ) external onlyAdmin {
        require(chainIds.length == dstTokens.length);
        for (uint256 i = 0; i < chainIds.length; i++) {
            tokenPeers[srcToken][chainIds[i]] = dstTokens[i];
        }
    }

    /// @dev Call by the user to submit a request for a cross chain interaction
    function swapout(
        address token,
        uint256 amount,
        address receiver,
        uint256 toChainId,
        uint256 flags
    ) external payable whenNotPaused(PAUSE_SWAPOUT_ROLE) {
        address clientPeer = clientPeers[toChainId];
        require(clientPeer != address(0), "AnycallClient: no dest client");

        address dstToken = tokenPeers[token][toChainId];
        require(dstToken != address(0), "AnycallClient: no dest token");

        uint256 oldCoinBalance;
        if (msg.value > 0) {
            oldCoinBalance = address(this).balance - msg.value;
        }

        address _underlying = _getUnderlying(token);

        if (_underlying != address(0)) {
            uint256 old_balance = IERC20(_underlying).balanceOf(token);

            IERC20(_underlying).safeTransferFrom(msg.sender, token, amount);

            uint256 new_balance = IERC20(_underlying).balanceOf(token);

            // update amount to real balance increasement (some token may deduct fees)
            amount = new_balance > old_balance ? new_balance - old_balance : 0;
        } else {
            assert(IAnyswapToken(token).burn(msg.sender, amount));
        }

        bytes memory data = abi.encodeWithSelector(
            this.anyExecute.selector,
            token,
            dstToken,
            amount,
            msg.sender,
            receiver,
            toChainId
        );
        IAnycallV6Proxy(callProxy).anyCall{value: msg.value}(
            clientPeer,
            data,
            address(this),
            toChainId,
            flags
        );

        if (msg.value > 0) {
            uint256 newCoinBalance = address(this).balance;
            if (newCoinBalance > oldCoinBalance) {
                // return remaining fees
                (bool success,) = msg.sender.call{value: newCoinBalance - oldCoinBalance}("");
                require(success);
            }
        }

        emit LogSwapout(token, msg.sender, receiver, amount, toChainId);
    }

    /// @notice Call by `AnycallProxy` to execute a cross chain interaction on the destination chain
    function anyExecute(bytes calldata data)
        external
        override
        onlyExecutor
        whenNotPaused(PAUSE_SWAPIN_ROLE)
        returns (bool success, bytes memory result)
    {
        bytes4 selector = bytes4(data[:4]);
        if (selector == this.anyExecute.selector) {
            (
                address srcToken,
                address dstToken,
                uint256 amount,
                address sender,
                address receiver,
                //uint256 toChainId
            ) = abi.decode(
                data[4:],
                (address, address, uint256, address, address, uint256)
            );

            address executor = IAnycallV6Proxy(callProxy).executor();
            (address from, uint256 fromChainId,) = IAnycallExecutor(executor).context();
            require(clientPeers[fromChainId] == from, "AnycallClient: wrong context");
            require(tokenPeers[dstToken][fromChainId] == srcToken, "AnycallClient: mismatch source token");

            address _underlying = _getUnderlying(dstToken);

            if (_underlying != address(0) && (IERC20(dstToken).balanceOf(address(this)) >= amount)) {
                IERC20(dstToken).safeTransferFrom(address(this), receiver, amount);
            } else {
                assert(IAnyswapToken(dstToken).mint(receiver, amount));
            }

            emit LogSwapin(dstToken, sender, receiver, amount, fromChainId);
        } else if (selector == 0xa35fe8bf) { // bytes4(keccak256('anyFallback(address,bytes)'))
            (address _to, bytes memory _data) = abi.decode(data[4:], (address, bytes));
            anyFallback(_to, _data);
        } else {
            return (false, "unknown selector");
        }
        return (true, "");
    }

    /// @dev Call back by `AnycallProxy` on the originating chain if the cross chain interaction fails
    function anyFallback(address to, bytes memory data)
        internal
        whenNotPaused(PAUSE_FALLBACK_ROLE)
    {
        address executor = IAnycallV6Proxy(callProxy).executor();
        (address _from,,) = IAnycallExecutor(executor).context();
        require(_from == address(this), "AnycallClient: wrong context");

        (
            bytes4 selector,
            address srcToken,
            address dstToken,
            uint256 amount,
            address from,
            address receiver,
            uint256 toChainId
        ) = abi.decode(
            data,
            (bytes4, address, address, uint256, address, address, uint256)
        );

        require(selector == this.anyExecute.selector, "AnycallClient: wrong fallback data");
        require(clientPeers[toChainId] == to, "AnycallClient: mismatch dest client");
        require(tokenPeers[srcToken][toChainId] == dstToken, "AnycallClient: mismatch dest token");

        address _underlying = _getUnderlying(srcToken);

        if (_underlying != address(0) && (IERC20(srcToken).balanceOf(address(this)) >= amount)) {
            IERC20(_underlying).safeTransferFrom(address(this), from, amount);
        } else {
            assert(IAnyswapToken(srcToken).mint(from, amount));
        }

        emit LogSwapoutFail(srcToken, from, receiver, amount, toChainId);
    }

    function _getUnderlying(address token) internal returns (address) {
        (bool success, bytes memory returndata) = token.call(abi.encodeWithSelector(0x6f307dc3));
        if (success && returndata.length > 0) {
            (address _underlying) = abi.decode(returndata, (address));
            return _underlying;
        }
        return address(0);
    }
}

File 2 of 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 3 of 8 : PausableControlWithAdmin.sol
// SPDX-License-Identifier: GPL-3.0-or-later

import "./PausableControl.sol";
import "./AdminControl.sol";

pragma solidity ^0.8.10;

abstract contract PausableControlWithAdmin is PausableControl, AdminControl {
    constructor(address _admin) AdminControl(_admin) {
    }

    function pause(bytes32 role) external onlyAdmin {
        _pause(role);
    }

    function unpause(bytes32 role) external onlyAdmin {
        _unpause(role);
    }
}

File 4 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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);
}

File 5 of 8 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 6 of 8 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 7 of 8 : PausableControl.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity ^0.8.10;

abstract contract PausableControl {
    mapping(bytes32 => bool) private _pausedRoles;

    bytes32 public constant PAUSE_ALL_ROLE = 0x00;

    event Paused(bytes32 role);
    event Unpaused(bytes32 role);

    modifier whenNotPaused(bytes32 role) {
        require(
            !paused(role) && !paused(PAUSE_ALL_ROLE),
            "PausableControl: paused"
        );
        _;
    }

    modifier whenPaused(bytes32 role) {
        require(
            paused(role) || paused(PAUSE_ALL_ROLE),
            "PausableControl: not paused"
        );
        _;
    }

    function paused(bytes32 role) public view virtual returns (bool) {
        return _pausedRoles[role];
    }

    function _pause(bytes32 role) internal virtual whenNotPaused(role) {
        _pausedRoles[role] = true;
        emit Paused(role);
    }

    function _unpause(bytes32 role) internal virtual whenPaused(role) {
        _pausedRoles[role] = false;
        emit Unpaused(role);
    }
}

File 8 of 8 : AdminControl.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity ^0.8.10;

abstract contract AdminControl {
    address public admin;
    address public pendingAdmin;

    event ChangeAdmin(address indexed _old, address indexed _new);
    event ApplyAdmin(address indexed _old, address indexed _new);

    constructor(address _admin) {
        require(_admin != address(0), "AdminControl: address(0)");
        admin = _admin;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "AdminControl: not admin");
        _;
    }

    function changeAdmin(address _admin) external onlyAdmin {
        require(_admin != address(0), "AdminControl: address(0)");
        pendingAdmin = _admin;
        emit ChangeAdmin(admin, _admin);
    }

    function applyAdmin() external {
        require(msg.sender == pendingAdmin, "AdminControl: Forbidden");
        emit ApplyAdmin(admin, pendingAdmin);
        admin = pendingAdmin;
        pendingAdmin = address(0);
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_callProxy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_old","type":"address"},{"indexed":true,"internalType":"address","name":"_new","type":"address"}],"name":"ApplyAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_old","type":"address"},{"indexed":true,"internalType":"address","name":"_new","type":"address"}],"name":"ChangeAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromChainId","type":"uint256"}],"name":"LogSwapin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"}],"name":"LogSwapout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainId","type":"uint256"}],"name":"LogSwapoutFail","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"PAUSE_ALL_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_FALLBACK_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_SWAPIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_SWAPOUT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"anyExecute","outputs":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"anycallExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"applyAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"callProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"clientPeers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_callProxy","type":"address"}],"name":"setCallProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_chainIds","type":"uint256[]"},{"internalType":"address[]","name":"_peers","type":"address[]"}],"name":"setClientPeers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"address[]","name":"dstTokens","type":"address[]"}],"name":"setTokenPeers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"uint256","name":"flags","type":"uint256"}],"name":"swapout","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenPeers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b50604051620044dc380380620044dc8339818101604052810190620000379190620002b5565b81818180600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415620000ae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a5906200035d565b60405180910390fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200012c57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020191906200037f565b600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050620003b1565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200027d8262000250565b9050919050565b6200028f8162000270565b81146200029b57600080fd5b50565b600081519050620002af8162000284565b92915050565b60008060408385031215620002cf57620002ce6200024b565b5b6000620002df858286016200029e565b9250506020620002f2858286016200029e565b9150509250929050565b600082825260208201905092915050565b7f41646d696e436f6e74726f6c3a20616464726573732830290000000000000000600082015250565b600062000345601883620002fc565b915062000352826200030d565b602082019050919050565b60006020820190508181036000830152620003788162000336565b9050919050565b6000602082840312156200039857620003976200024b565b5b6000620003a8848285016200029e565b91505092915050565b61411b80620003c16000396000f3fe6080604052600436106101235760003560e01c80638d190370116100a0578063b5fb43c811610064578063b5fb43c81461045d578063d2c7dfcc1461049a578063ed56531a146104c5578063f1352f4d146104ee578063f851a4401461050a576101ba565b80638d190370146103655780638f2839701461038e5780639abaf479146103b75780639ac25d08146103f55780639e9e466614610420576101ba565b80632f4dae9f116100e75780632f4dae9f146102945780634c1278b0146102bd5780634e67428d146102e657806351fe4c2b146102fd5780638b7719fd1461033a576101ba565b80630e42fa36146101bf57806315a9234e146101ea57806326782247146102155780632b0d0a8b146102405780632da688ac14610269576101ba565b366101ba57600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101af90612a6a565b60405180910390fd5b005b600080fd5b3480156101cb57600080fd5b506101d4610535565b6040516101e19190612aa3565b60405180910390f35b3480156101f657600080fd5b506101ff610559565b60405161020c9190612aa3565b60405180910390f35b34801561022157600080fd5b5061022a61057d565b6040516102379190612aff565b60405180910390f35b34801561024c57600080fd5b5061026760048036038101906102629190612b5a565b6105a3565b005b34801561027557600080fd5b5061027e610782565b60405161028b9190612aff565b60405180910390f35b3480156102a057600080fd5b506102bb60048036038101906102b69190612bb3565b6107a8565b005b3480156102c957600080fd5b506102e460048036038101906102df9190612c9b565b610844565b005b3480156102f257600080fd5b506102fb6109de565b005b34801561030957600080fd5b50610324600480360381019061031f9190612d66565b610bb3565b6040516103319190612aff565b60405180910390f35b34801561034657600080fd5b5061034f610be6565b60405161035c9190612aa3565b60405180910390f35b34801561037157600080fd5b5061038c60048036038101906103879190612d93565b610c0a565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612b5a565b610d66565b005b3480156103c357600080fd5b506103de60048036038101906103d99190612e6a565b610f26565b6040516103ec929190612f6b565b60405180910390f35b34801561040157600080fd5b5061040a611644565b6040516104179190612aa3565b60405180910390f35b34801561042c57600080fd5b5061044760048036038101906104429190612bb3565b61164b565b6040516104549190612f9b565b60405180910390f35b34801561046957600080fd5b50610484600480360381019061047f9190612fb6565b611674565b6040516104919190612aff565b60405180910390f35b3480156104a657600080fd5b506104af6116b6565b6040516104bc9190612aff565b60405180910390f35b3480156104d157600080fd5b506104ec60048036038101906104e79190612bb3565b6116dc565b005b61050860048036038101906105039190612ff6565b611778565b005b34801561051657600080fd5b5061051f611df7565b60405161052c9190612aff565b60405180910390f35b7fcc99d060aac886e0f57b189f805230aca6bd003684c54e24a7043ac5d5c3567681565b7fa29cfc2ce0a6eb3cf6a8893cfc761b7caf0d3e334ba02bae304e0da8db4006ae81565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610633576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062a906130bd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561066d57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f91906130f2565b600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610838576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082f906130bd565b60405180910390fd5b61084181611e1d565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108cb906130bd565b60405180910390fd5b8181905084849050146108e657600080fd5b60005b848490508110156109d6578282828181106109075761090661311f565b5b905060200201602081019061091c9190612b5a565b600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008787858181106109705761096f61311f565b5b90506020020135815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080806109ce9061317d565b9150506108e9565b505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a6e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6590613212565b60405180910390fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f6d7e0a4e01cdbbdb3b116a1157c3a2c5165678006563d891c1c700b1238027ca60405160405180910390a3600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f6b4dbfc84e4e79534c6e41e5a2fd5db184a99d798352dc0921c31a59bc413eb581565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c91906130bd565b60405180910390fd5b818190508484905014610cac57600080fd5b60005b84849050811015610d5f57828282818110610ccd57610ccc61311f565b5b9050602002016020810190610ce29190612b5a565b60056000878785818110610cf957610cf861311f565b5b90506020020135815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080610d579061317d565b915050610caf565b5050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610df6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ded906130bd565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610e66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5d9061327e565b60405180910390fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fcf9b665e0639e0b81a8db37b60ac7ddf45aeb1b484e11adeb7dff4bf4a3a625860405160405180910390a350565b60006060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb1906132ea565b60405180910390fd5b7f6b4dbfc84e4e79534c6e41e5a2fd5db184a99d798352dc0921c31a59bc413eb5610fe48161164b565b158015610ffa5750610ff86000801b61164b565b155b611039576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161103090613356565b60405180910390fd5b6000858560009060049261104f93929190613380565b9061105a91906133ff565b9050639abaf47960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561157b5760008060008060008a8a60049080926110c493929190613380565b8101906110d1919061349c565b50945094509450945094506000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561114b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116f91906130f2565b90506000808273ffffffffffffffffffffffffffffffffffffffff1663d0496d6a6040518163ffffffff1660e01b81526004016060604051808303816000875af11580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e5919061353e565b50915091508173ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461128b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611282906135dd565b60405180910390fd5b8773ffffffffffffffffffffffffffffffffffffffff16600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611369576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113609061366f565b60405180910390fd5b600061137488611edf565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561142c5750868873ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016113e89190612aff565b602060405180830381865afa158015611405573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611429919061368f565b10155b156114635761145e3086898b73ffffffffffffffffffffffffffffffffffffffff16611fdd909392919063ffffffff16565b6114ef565b8773ffffffffffffffffffffffffffffffffffffffff166340c10f1986896040518363ffffffff1660e01b815260040161149e9291906136cb565b6020604051808303816000875af11580156114bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e19190613720565b6114ee576114ed61374d565b5b5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fd93e4cd2268f799ea5b0b87cddf50adc982760eafe2def648a6a62296f2ea9928a8660405161156592919061377c565b60405180910390a4505050505050505050611624565b63a35fe8bf60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156115e157600080878760049080926115bf93929190613380565b8101906115cc91906138d5565b915091506115da8282612066565b5050611623565b60006040518060400160405280601081526020017f756e6b6e6f776e2073656c6563746f7200000000000000000000000000000000815250935093505061163c565b5b60016040518060200160405280600081525093509350505b509250929050565b6000801b81565b600080600083815260200190815260200160002060009054906101000a900460ff169050919050565b60066020528160005260406000206020528060005260406000206000915091509054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461176c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611763906130bd565b60405180910390fd5b611775816126a5565b50565b7fcc99d060aac886e0f57b189f805230aca6bd003684c54e24a7043ac5d5c356766117a28161164b565b1580156117b857506117b66000801b61164b565b155b6117f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ee90613356565b60405180910390fd5b60006005600085815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561189f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118969061397d565b60405180910390fd5b6000600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197b906139e9565b60405180910390fd5b60008034111561199d57344761199a9190613a09565b90505b60006119a88a611edf565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b2b5760008173ffffffffffffffffffffffffffffffffffffffff166370a082318c6040518263ffffffff1660e01b8152600401611a199190612aff565b602060405180830381865afa158015611a36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5a919061368f565b9050611a89338c8c8573ffffffffffffffffffffffffffffffffffffffff16611fdd909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a082318d6040518263ffffffff1660e01b8152600401611ac49190612aff565b602060405180830381865afa158015611ae1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b05919061368f565b9050818111611b15576000611b22565b8181611b219190613a09565b5b9a505050611bb7565b8973ffffffffffffffffffffffffffffffffffffffff16639dc29fac338b6040518363ffffffff1660e01b8152600401611b669291906136cb565b6020604051808303816000875af1158015611b85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ba99190613720565b611bb657611bb561374d565b5b5b6000639abaf47960e01b8b858c338d8d604051602401611bdc96959493929190613a3d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd45c4e7348784308d8d6040518763ffffffff1660e01b8152600401611c9f959493929190613a9e565b6000604051808303818588803b158015611cb857600080fd5b505af1158015611ccc573d6000803e3d6000fd5b50505050506000341115611d6c57600047905083811115611d6a5760003373ffffffffffffffffffffffffffffffffffffffff168583611d0c9190613a09565b604051611d1890613b29565b60006040518083038185875af1925050503d8060008114611d55576040519150601f19603f3d011682016040523d82523d6000602084013e611d5a565b606091505b5050905080611d6857600080fd5b505b505b8873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff167fb8b6a223e65ec5259b95a21624d01bae48fee26b3533e6e13f1c99b75a0c7af38d8c604051611de292919061377c565b60405180910390a45050505050505050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b80611e278161164b565b80611e3a5750611e396000801b61164b565b5b611e79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7090613b8a565b60405180910390fd5b600080600084815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd05bfc2250abb0f8fd265a54c53a24359c5484af63cad2e4ce87c78ab751395a82604051611ed39190612aa3565b60405180910390a15050565b60008060008373ffffffffffffffffffffffffffffffffffffffff16636f307dc36040516024016040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611f549190613bdb565b6000604051808303816000865af19150503d8060008114611f91576040519150601f19603f3d011682016040523d82523d6000602084013e611f96565b606091505b5091509150818015611fa9575060008151115b15611fd157600081806020019051810190611fc49190613c07565b9050809350505050611fd8565b6000925050505b919050565b612060846323b872dd60e01b858585604051602401611ffe93929190613c34565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061276a565b50505050565b7fa29cfc2ce0a6eb3cf6a8893cfc761b7caf0d3e334ba02bae304e0da8db4006ae6120908161164b565b1580156120a657506120a46000801b61164b565b155b6120e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120dc90613356565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612154573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217891906130f2565b905060008173ffffffffffffffffffffffffffffffffffffffff1663d0496d6a6040518163ffffffff1660e01b81526004016060604051808303816000875af11580156121c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ed919061353e565b505090503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461225f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612256906135dd565b60405180910390fd5b60008060008060008060008a80602001905181019061227e9190613c97565b9650965096509650965096509650639abaf47960e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916877bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612313576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161230a90613dab565b60405180910390fd5b8b73ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146123b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ab90613e3d565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612492576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248990613ecf565b60405180910390fd5b600061249d87611edf565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141580156125555750848773ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016125119190612aff565b602060405180830381865afa15801561252e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612552919061368f565b10155b1561258c576125873085878473ffffffffffffffffffffffffffffffffffffffff16611fdd909392919063ffffffff16565b612618565b8673ffffffffffffffffffffffffffffffffffffffff166340c10f1985876040518363ffffffff1660e01b81526004016125c79291906136cb565b6020604051808303816000875af11580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a9190613720565b6126175761261661374d565b5b5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f2592581e9728083f952ca32d7c95ca01d40128f428d5cd727dab5570660c04c5888660405161268e92919061377c565b60405180910390a450505050505050505050505050565b806126af8161164b565b1580156126c557506126c36000801b61164b565b155b612704576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126fb90613356565b60405180910390fd5b600160008084815260200190815260200160002060006101000a81548160ff0219169083151502179055507f0cb09dc71d57eeec2046f6854976717e4874a3cf2d6ddeddde337e5b6de6ba318260405161275e9190612aa3565b60405180910390a15050565b60006127cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166128319092919063ffffffff16565b905060008151111561282c57808060200190518101906127ec9190613720565b61282b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282290613f61565b60405180910390fd5b5b505050565b60606128408484600085612849565b90509392505050565b60608247101561288e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288590613ff3565b60405180910390fd5b6128978561295d565b6128d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128cd9061405f565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516128ff9190613bdb565b60006040518083038185875af1925050503d806000811461293c576040519150601f19603f3d011682016040523d82523d6000602084013e612941565b606091505b5091509150612951828286612980565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315612990578290506129e0565b6000835111156129a35782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d791906140c3565b60405180910390fd5b9392505050565b600082825260208201905092915050565b7f416e7963616c6c436c69656e743a20726563656976652066726f6d20666f726260008201527f696464656e2073656e6465720000000000000000000000000000000000000000602082015250565b6000612a54602c836129e7565b9150612a5f826129f8565b604082019050919050565b60006020820190508181036000830152612a8381612a47565b9050919050565b6000819050919050565b612a9d81612a8a565b82525050565b6000602082019050612ab86000830184612a94565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612ae982612abe565b9050919050565b612af981612ade565b82525050565b6000602082019050612b146000830184612af0565b92915050565b6000604051905090565b600080fd5b600080fd5b612b3781612ade565b8114612b4257600080fd5b50565b600081359050612b5481612b2e565b92915050565b600060208284031215612b7057612b6f612b24565b5b6000612b7e84828501612b45565b91505092915050565b612b9081612a8a565b8114612b9b57600080fd5b50565b600081359050612bad81612b87565b92915050565b600060208284031215612bc957612bc8612b24565b5b6000612bd784828501612b9e565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612c0557612c04612be0565b5b8235905067ffffffffffffffff811115612c2257612c21612be5565b5b602083019150836020820283011115612c3e57612c3d612bea565b5b9250929050565b60008083601f840112612c5b57612c5a612be0565b5b8235905067ffffffffffffffff811115612c7857612c77612be5565b5b602083019150836020820283011115612c9457612c93612bea565b5b9250929050565b600080600080600060608688031215612cb757612cb6612b24565b5b6000612cc588828901612b45565b955050602086013567ffffffffffffffff811115612ce657612ce5612b29565b5b612cf288828901612bef565b9450945050604086013567ffffffffffffffff811115612d1557612d14612b29565b5b612d2188828901612c45565b92509250509295509295909350565b6000819050919050565b612d4381612d30565b8114612d4e57600080fd5b50565b600081359050612d6081612d3a565b92915050565b600060208284031215612d7c57612d7b612b24565b5b6000612d8a84828501612d51565b91505092915050565b60008060008060408587031215612dad57612dac612b24565b5b600085013567ffffffffffffffff811115612dcb57612dca612b29565b5b612dd787828801612bef565b9450945050602085013567ffffffffffffffff811115612dfa57612df9612b29565b5b612e0687828801612c45565b925092505092959194509250565b60008083601f840112612e2a57612e29612be0565b5b8235905067ffffffffffffffff811115612e4757612e46612be5565b5b602083019150836001820283011115612e6357612e62612bea565b5b9250929050565b60008060208385031215612e8157612e80612b24565b5b600083013567ffffffffffffffff811115612e9f57612e9e612b29565b5b612eab85828601612e14565b92509250509250929050565b60008115159050919050565b612ecc81612eb7565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612f0c578082015181840152602081019050612ef1565b83811115612f1b576000848401525b50505050565b6000601f19601f8301169050919050565b6000612f3d82612ed2565b612f478185612edd565b9350612f57818560208601612eee565b612f6081612f21565b840191505092915050565b6000604082019050612f806000830185612ec3565b8181036020830152612f928184612f32565b90509392505050565b6000602082019050612fb06000830184612ec3565b92915050565b60008060408385031215612fcd57612fcc612b24565b5b6000612fdb85828601612b45565b9250506020612fec85828601612d51565b9150509250929050565b600080600080600060a0868803121561301257613011612b24565b5b600061302088828901612b45565b955050602061303188828901612d51565b945050604061304288828901612b45565b935050606061305388828901612d51565b925050608061306488828901612d51565b9150509295509295909350565b7f41646d696e436f6e74726f6c3a206e6f742061646d696e000000000000000000600082015250565b60006130a76017836129e7565b91506130b282613071565b602082019050919050565b600060208201905081810360008301526130d68161309a565b9050919050565b6000815190506130ec81612b2e565b92915050565b60006020828403121561310857613107612b24565b5b6000613116848285016130dd565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061318882612d30565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156131bb576131ba61314e565b5b600182019050919050565b7f41646d696e436f6e74726f6c3a20466f7262696464656e000000000000000000600082015250565b60006131fc6017836129e7565b9150613207826131c6565b602082019050919050565b6000602082019050818103600083015261322b816131ef565b9050919050565b7f41646d696e436f6e74726f6c3a20616464726573732830290000000000000000600082015250565b60006132686018836129e7565b915061327382613232565b602082019050919050565b600060208201905081810360008301526132978161325b565b9050919050565b7f416e7963616c6c436c69656e743a206e6f7420617574686f72697a6564000000600082015250565b60006132d4601d836129e7565b91506132df8261329e565b602082019050919050565b60006020820190508181036000830152613303816132c7565b9050919050565b7f5061757361626c65436f6e74726f6c3a20706175736564000000000000000000600082015250565b60006133406017836129e7565b915061334b8261330a565b602082019050919050565b6000602082019050818103600083015261336f81613333565b9050919050565b600080fd5b600080fd5b6000808585111561339457613393613376565b5b838611156133a5576133a461337b565b5b6001850283019150848603905094509492505050565b600082905092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600082821b905092915050565b600061340b83836133bb565b8261341681356133c6565b92506004821015613456576134517fffffffff00000000000000000000000000000000000000000000000000000000836004036008026133f2565b831692505b505092915050565b600061346982612abe565b9050919050565b6134798161345e565b811461348457600080fd5b50565b60008135905061349681613470565b92915050565b60008060008060008060c087890312156134b9576134b8612b24565b5b60006134c789828a01613487565b96505060206134d889828a01613487565b95505060406134e989828a01612d51565b94505060606134fa89828a01613487565b935050608061350b89828a01613487565b92505060a061351c89828a01612d51565b9150509295509295509295565b60008151905061353881612d3a565b92915050565b60008060006060848603121561355757613556612b24565b5b6000613565868287016130dd565b935050602061357686828701613529565b925050604061358786828701613529565b9150509250925092565b7f416e7963616c6c436c69656e743a2077726f6e6720636f6e7465787400000000600082015250565b60006135c7601c836129e7565b91506135d282613591565b602082019050919050565b600060208201905081810360008301526135f6816135ba565b9050919050565b7f416e7963616c6c436c69656e743a206d69736d6174636820736f75726365207460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b60006136596024836129e7565b9150613664826135fd565b604082019050919050565b600060208201905081810360008301526136888161364c565b9050919050565b6000602082840312156136a5576136a4612b24565b5b60006136b384828501613529565b91505092915050565b6136c581612d30565b82525050565b60006040820190506136e06000830185612af0565b6136ed60208301846136bc565b9392505050565b6136fd81612eb7565b811461370857600080fd5b50565b60008151905061371a816136f4565b92915050565b60006020828403121561373657613735612b24565b5b60006137448482850161370b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600060408201905061379160008301856136bc565b61379e60208301846136bc565b9392505050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6137e282612f21565b810181811067ffffffffffffffff82111715613801576138006137aa565b5b80604052505050565b6000613814612b1a565b905061382082826137d9565b919050565b600067ffffffffffffffff8211156138405761383f6137aa565b5b61384982612f21565b9050602081019050919050565b82818337600083830152505050565b600061387861387384613825565b61380a565b905082815260208101848484011115613894576138936137a5565b5b61389f848285613856565b509392505050565b600082601f8301126138bc576138bb612be0565b5b81356138cc848260208601613865565b91505092915050565b600080604083850312156138ec576138eb612b24565b5b60006138fa85828601613487565b925050602083013567ffffffffffffffff81111561391b5761391a612b29565b5b613927858286016138a7565b9150509250929050565b7f416e7963616c6c436c69656e743a206e6f206465737420636c69656e74000000600082015250565b6000613967601d836129e7565b915061397282613931565b602082019050919050565b600060208201905081810360008301526139968161395a565b9050919050565b7f416e7963616c6c436c69656e743a206e6f206465737420746f6b656e00000000600082015250565b60006139d3601c836129e7565b91506139de8261399d565b602082019050919050565b60006020820190508181036000830152613a02816139c6565b9050919050565b6000613a1482612d30565b9150613a1f83612d30565b925082821015613a3257613a3161314e565b5b828203905092915050565b600060c082019050613a526000830189612af0565b613a5f6020830188612af0565b613a6c60408301876136bc565b613a796060830186612af0565b613a866080830185612af0565b613a9360a08301846136bc565b979650505050505050565b600060a082019050613ab36000830188612af0565b8181036020830152613ac58187612f32565b9050613ad46040830186612af0565b613ae160608301856136bc565b613aee60808301846136bc565b9695505050505050565b600081905092915050565b50565b6000613b13600083613af8565b9150613b1e82613b03565b600082019050919050565b6000613b3482613b06565b9150819050919050565b7f5061757361626c65436f6e74726f6c3a206e6f74207061757365640000000000600082015250565b6000613b74601b836129e7565b9150613b7f82613b3e565b602082019050919050565b60006020820190508181036000830152613ba381613b67565b9050919050565b6000613bb582612ed2565b613bbf8185613af8565b9350613bcf818560208601612eee565b80840191505092915050565b6000613be78284613baa565b915081905092915050565b600081519050613c0181613470565b92915050565b600060208284031215613c1d57613c1c612b24565b5b6000613c2b84828501613bf2565b91505092915050565b6000606082019050613c496000830186612af0565b613c566020830185612af0565b613c6360408301846136bc565b949350505050565b613c74816133c6565b8114613c7f57600080fd5b50565b600081519050613c9181613c6b565b92915050565b600080600080600080600060e0888a031215613cb657613cb5612b24565b5b6000613cc48a828b01613c82565b9750506020613cd58a828b01613bf2565b9650506040613ce68a828b01613bf2565b9550506060613cf78a828b01613529565b9450506080613d088a828b01613bf2565b93505060a0613d198a828b01613bf2565b92505060c0613d2a8a828b01613529565b91505092959891949750929550565b7f416e7963616c6c436c69656e743a2077726f6e672066616c6c6261636b20646160008201527f7461000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d956022836129e7565b9150613da082613d39565b604082019050919050565b60006020820190508181036000830152613dc481613d88565b9050919050565b7f416e7963616c6c436c69656e743a206d69736d61746368206465737420636c6960008201527f656e740000000000000000000000000000000000000000000000000000000000602082015250565b6000613e276023836129e7565b9150613e3282613dcb565b604082019050919050565b60006020820190508181036000830152613e5681613e1a565b9050919050565b7f416e7963616c6c436c69656e743a206d69736d61746368206465737420746f6b60008201527f656e000000000000000000000000000000000000000000000000000000000000602082015250565b6000613eb96022836129e7565b9150613ec482613e5d565b604082019050919050565b60006020820190508181036000830152613ee881613eac565b9050919050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000613f4b602a836129e7565b9150613f5682613eef565b604082019050919050565b60006020820190508181036000830152613f7a81613f3e565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613fdd6026836129e7565b9150613fe882613f81565b604082019050919050565b6000602082019050818103600083015261400c81613fd0565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000614049601d836129e7565b915061405482614013565b602082019050919050565b600060208201905081810360008301526140788161403c565b9050919050565b600081519050919050565b60006140958261407f565b61409f81856129e7565b93506140af818560208601612eee565b6140b881612f21565b840191505092915050565b600060208201905081810360008301526140dd818461408a565b90509291505056fea2646970667358221220232a47e365b015bc0b7836c4f8944bd0d25ac50fc28f8275599ef3162807395d64736f6c634300080a0033000000000000000000000000d71cb0c4a82c36312b5b83c43f351b882756957f000000000000000000000000273a4ffceb31b8473d51051ad2a2edbb7ac8ce02

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

000000000000000000000000d71cb0c4a82c36312b5b83c43f351b882756957f000000000000000000000000273a4ffceb31b8473d51051ad2a2edbb7ac8ce02

-----Decoded View---------------
Arg [0] : _admin (address): 0xD71Cb0C4A82C36312B5b83c43F351B882756957F
Arg [1] : _callProxy (address): 0x273a4fFcEb31B8473D51051Ad2a2EdbB7Ac8Ce02

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000d71cb0c4a82c36312b5b83c43f351b882756957f
Arg [1] : 000000000000000000000000273a4ffceb31b8473d51051ad2a2edbb7ac8ce02


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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.