ETH Price: $2,974.75 (+3.96%)
Gas: 1 Gwei

Contract

0x8BE7dbC73a9e1bB40d1D7741783B0a8FA003ACF7
 

Overview

ETH Balance

0.6 ETH

Eth Value

$1,784.85 (@ $2,974.75/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Buy Wolves193766812024-03-06 14:18:59121 days ago1709734739IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.03575697.81185904
Buy Wolves192687982024-02-20 12:04:23136 days ago1708430663IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0115206231.50647509
Buy Wolves191220572024-01-30 21:38:47157 days ago1706650727IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0089836224.89221064
Claim Wolves174890872023-06-16 1:18:23386 days ago1686878303IN
0x8BE7dbC7...FA003ACF7
0 ETH0.016767714.84251494
Withdraw170566012023-04-16 2:46:23447 days ago1681613183IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0010707228.4781708
Claim Wolves167885062023-03-09 5:15:47485 days ago1678338947IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0140320426.90888392
Buy Wolves167135522023-02-26 16:20:11495 days ago1677428411IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0070048619.73451934
Buy Wolves167110732023-02-26 7:57:59495 days ago1677398279IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0068370218.999387
Buy Wolves166688262023-02-20 9:19:59501 days ago1676884799IN
0x8BE7dbC7...FA003ACF7
1 ETH0.0256221722.94306785
Buy Wolves166294002023-02-14 20:34:35507 days ago1676406875IN
0x8BE7dbC7...FA003ACF7
1 ETH0.13894819127.21712389
Buy Wolves166283732023-02-14 17:06:59507 days ago1676394419IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0124172834.41989618
Buy Wolves165909392023-02-09 11:36:47512 days ago1675942607IN
0x8BE7dbC7...FA003ACF7
0.4 ETH0.0115501819.93803119
Buy Wolves165839002023-02-08 11:55:23513 days ago1675857323IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0091036124.902241
Buy Wolves165574552023-02-04 19:18:23517 days ago1675538303IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0093365525.87120597
Withdraw165552212023-02-04 11:48:47517 days ago1675511327IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0007229420.56811446
Claim Wolves165173992023-01-30 4:57:59523 days ago1675054679IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0145442313.34905174
Buy Wolves160601792022-11-27 8:38:23586 days ago1669538303IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.003315579.06738746
Gift Wolves159545932022-11-12 14:41:11601 days ago1668264071IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0049853115.12231088
Buy Wolves158332522022-10-26 15:49:59618 days ago1666799399IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0110738832
Buy Wolves157909902022-10-20 18:05:47624 days ago1666289147IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0149715141
Claim Wolves157382312022-10-13 9:14:11631 days ago1665652451IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0044349313.17893261
Buy Wolves156661182022-10-03 7:25:11641 days ago1664781911IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.003262978.92045603
Withdraw156011772022-09-24 5:38:11651 days ago1663997891IN
0x8BE7dbC7...FA003ACF7
0 ETH0.000236346.271626
Buy Wolves155229572022-09-12 20:45:36662 days ago1663015536IN
0x8BE7dbC7...FA003ACF7
0.2 ETH0.0051152314.19877084
Claim Wolves152780882022-08-04 20:46:23701 days ago1659645983IN
0x8BE7dbC7...FA003ACF7
0 ETH0.0057365116.81321543
View all transactions

Latest 4 internal transactions

Advanced mode:
Parent Transaction Hash Block From To Value
170566012023-04-16 2:46:23447 days ago1681613183
0x8BE7dbC7...FA003ACF7
3.4 ETH
165552212023-02-04 11:48:47517 days ago1675511327
0x8BE7dbC7...FA003ACF7
0.8 ETH
156011772022-09-24 5:38:11651 days ago1663997891
0x8BE7dbC7...FA003ACF7
5.3 ETH
147995782022-05-18 15:20:55779 days ago1652887255
0x8BE7dbC7...FA003ACF7
13 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FearWolfDistributor

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 1 : FearWolfDistributor.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}




/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    function toString(bytes32 value) internal pure returns (string memory) {
        uint8 i = 0;
        while(i < 32 && value[i] != 0) {
            i++;
        }
        bytes memory bytesArray = new bytes(i);
        for (i = 0; i < 32 && value[i] != 0; i++) {
            bytesArray[i] = value[i];
        }
        return string(bytesArray);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}




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




/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}




/**
 * @dev Interface of a contract containing identifier for Root role.
 */
interface IRoleContainerRoot {
    /**
    * @dev Returns Root role identifier.
    */
    function ROOT_ROLE() external view returns (bytes32);
}




/**
 * @dev Interface of a contract containing identifier for Admin role.
 */
interface IRoleContainerAdmin {
    /**
    * @dev Returns Admin role identifier.
    */
    function ADMIN_ROLE() external view returns (bytes32);
}




/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via _msgSender() and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}




/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}



/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}



/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165Storage is ERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}



/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, _msgSender()));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 */
abstract contract AccessControl is Context, ERC165Storage, IAccessControl, IRoleContainerAdmin {
    /**
    * @dev Root Admin role identifier.
    */
    bytes32 public constant ROOT_ROLE = "Root";

    /**
    * @dev Admin role identifier.
    */
    bytes32 public constant ADMIN_ROLE = "Admin";

    /**
    * @dev Manager role identifier.
    */
    bytes32 public constant MANAGER_ROLE = "Manager";

    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    constructor() {
        _registerInterface(type(IAccessControl).interfaceId);

        _setupRole(ROOT_ROLE, _msgSender());
        _setupRole(ADMIN_ROLE, _msgSender());
        _setRoleAdmin(MANAGER_ROLE, ROOT_ROLE);
    }

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toString(role)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) private {
        _grantRole(role, account);
        _setRoleAdmin(role, ROOT_ROLE);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}




/**
 * @dev Interface for contract which allows to pause and unpause the contract.
 */
interface IPausable {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);
    
    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() external view returns (bool);

    /**
    * @dev Pauses the contract.
    */
    function pause() external;

    /**
    * @dev Unpauses the contract.
    */
    function unpause() external;
}




/**
 * @dev Interface of a contract containing identifier for Pauser role.
 */
interface IRoleContainerPauser {
    /**
    * @dev Returns Pauser role identifier.
    */
    function PAUSER_ROLE() external view returns (bytes32);
}



/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
contract Pausable is AccessControl, IPausable, IRoleContainerPauser {
    /**
    * @dev Pauser role identifier.
    */
    bytes32 public constant PAUSER_ROLE = "Pauser";

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor () {
        _registerInterface(type(IPausable).interfaceId);

        _setRoleAdmin(PAUSER_ROLE, ROOT_ROLE);

        _paused = true;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
   
    /**
    * @dev This function is called before pausing the contract.
    * Override to add custom pausing conditions or actions.
    */
    function _beforePause() internal virtual {
    }

    /**
    * @dev This function is called before unpausing the contract.
    * Override to add custom unpausing conditions or actions.
    */
    function _beforeUnpause() internal virtual {
    }

    /**
    * @dev Pauses the contract.
    * Requirements:
    * - Caller must have 'PAUSER_ROLE';
    * - Contract must be unpaused.
    */
    function pause() external onlyRole(PAUSER_ROLE) whenNotPaused {
        _beforePause();
        _pause();
    }

    /**
    * @dev Unpauses the contract.
    * Requirements:
    * - Caller must have 'PAUSER_ROLE';
    * - Contract must be unpaused;
    */
    function unpause() external onlyRole(PAUSER_ROLE) whenPaused {
        _beforeUnpause();
        _unpause();
    }
}




/**
 * @dev Interface of a contract module which allows to withdraw assets.
 */
interface IWithdrawable {
    /**
     * @dev Emitted when network main currency withdrawal occurs.
     */
    event Withdrawal(address to, string reason);
    /**
     * @dev Emitted when ERC20 asset withdrawal occurs.
     */
    event WithdrawalERC20(address asset, address to, string reason);
    /**
     * @dev Emitted when ERC721 asset withdrawal occurs.
     */
    event WithdrawalERC721(address asset, uint256[] ids, address to, string reason);
    /**
     * @dev Emitted when ERC1155 asset withdrawal occurs.
     */
    event WithdrawalERC1155(address asset, uint256[] ids, address to, string reason);

    /**
    * @dev Withdraws all balance of the network main currency.
    * Emits a {Withdrawal} event.
    */
    function withdraw(address payable to, string calldata reason) external;

    /**
    * @dev Withdraws all balance of specified ERC20 asset.
    * Emits a {WithdrawalERC20} event.
    */
    function withdrawERC20(address asset, address to, string calldata reason) external;

    /**
    * @dev Withdraws all of specified ERC721 asset with ids.
    * Emits a {WithdrawalERC721} event.
    */
    function withdrawERC721(address asset, uint256[] calldata ids, address to, string calldata reason) external;

    /**
    * @dev Withdraws all balances of specified ERC1155 asset with ids.
    * Emits a {WithdrawalERC1155} event.
    */
    function withdrawERC1155(address asset, uint256[] calldata ids, address to, string calldata reason) external;
}



/**
 * @dev Contract module which allows to perform basic checks on arguments.
 */
abstract contract RequirementsChecker {
    uint256 internal constant inf = type(uint256).max;

    function _requireNonZeroAddress(address _address, string memory paramName) internal pure {
        require(_address != address(0), string(abi.encodePacked(paramName, ": cannot use zero address")));
    }

    function _requireArrayData(address[] memory _array, string memory paramName) internal pure {
        require(_array.length != 0, string(abi.encodePacked(paramName, ": cannot be empty")));
    }

    function _requireArrayData(uint256[] memory _array, string memory paramName) internal pure {
        require(_array.length != 0, string(abi.encodePacked(paramName, ": cannot be empty")));
    }

    function _requireStringData(string memory _string, string memory paramName) internal pure {
        require(bytes(_string).length != 0, string(abi.encodePacked(paramName, ": cannot be empty")));
    }

    function _requireSameLengthArrays(address[] memory _array1, uint256[] memory _array2, string memory paramName1, string memory paramName2) internal pure {
        require(_array1.length == _array2.length, string(abi.encodePacked(paramName1, ", ", paramName2, ": lengths must be equal")));
    }

    function _requireInRange(uint256 value, uint256 minValue, uint256 maxValue, string memory paramName) internal pure {
        string memory maxValueString = maxValue == inf ? "inf" : Strings.toString(maxValue);
        require(minValue <= value && (maxValue == inf || value <= maxValue), string(abi.encodePacked(paramName, ": must be in [", Strings.toString(minValue), "..", maxValueString, "] range")));
    }
}



/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.
 */
interface IERC721Receiver is IERC165 {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}



/**
 * @dev Implementation of the {IERC721Receiver} interface.
 */
abstract contract ERC721Holder is ERC165Storage, IERC721Receiver {

    constructor() {
        _registerInterface(type(IERC721Receiver).interfaceId);
    }

    /**
     * @dev See {IERC721Receiver-onERC721Received}.
     * Always returns `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
}



/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}



/**
 * @dev Interface of extension of {IERC165} that allows to handle receipts on receiving {IERC1155} assets.
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. _msgSender())
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. _msgSender())
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}



/**
 * Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
 *
 * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be stuck.
 */
contract ERC1155Holder is ERC165Storage, IERC1155Receiver {

    constructor() {
        _registerInterface(type(IERC1155Receiver).interfaceId);
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}



/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transfered from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}



/**
 * @dev Contract module which allows authorized account to withdraw assets in case of emergency.
 */
abstract contract Withdrawable is AccessControl, RequirementsChecker, ERC721Holder, ERC1155Holder, IWithdrawable {

    constructor () {
        _registerInterface(type(IWithdrawable).interfaceId);
    }

    /**
    * @dev Withdraws all balance of the network main currency.
    * Emits a {Withdrawal} event.
    */
    function withdraw(address payable to, string calldata reason) external onlyRole(ADMIN_ROLE) {
        _requireNonZeroAddress(to, "to");
        _requireStringData(reason, "reason");
        _beforeWithdrawal(to);

        (bool success,) = to.call{value: address(this).balance}("");
        require(success, "Withdraw failed");
        emit Withdrawal(to, reason);
    }

    /**
    * @dev Withdraws all balance of specified ERC20 asset.
    * Emits a {WithdrawalERC20} event.
    */
    function withdrawERC20(address asset, address to, string calldata reason) external onlyRole(ADMIN_ROLE) {
        _requireNonZeroAddress(asset, "asset");
        _requireNonZeroAddress(to, "to");
        _requireStringData(reason, "reason");
        _beforeWithdrawalERC20(asset, to);

        IERC20 token = IERC20(asset);        
        token.transfer(to, token.balanceOf(address(this)));
        emit WithdrawalERC20(asset, to, reason);
    }

    /**
    * @dev Withdraws all of specified ERC721 asset with ids.
    * Emits a {WithdrawalERC721} event.
    */
    function withdrawERC721(address asset, uint256[] calldata ids, address to, string calldata reason) external onlyRole(ADMIN_ROLE) {
        _requireNonZeroAddress(asset, "asset");
        _requireNonZeroAddress(to, "to");
        _requireArrayData(ids, "ids");
        _requireStringData(reason, "reason");
        _beforeWithdrawalERC721(asset, ids, to);

        IERC721 token = IERC721(asset);
        for(uint i = 0; i < ids.length; i++)
            token.safeTransferFrom(address(this), to, ids[i], "");
        emit WithdrawalERC721(asset, ids, to, reason);
    }

    /**
    * @dev Withdraws all balances of specified ERC1155 asset with ids.
    * Emits a {WithdrawalERC1155} event.
    */
    function withdrawERC1155(address asset, uint256[] calldata ids, address to, string calldata reason) external onlyRole(ADMIN_ROLE) {
        _requireNonZeroAddress(asset, "asset");
        _requireNonZeroAddress(to, "to");
        _requireArrayData(ids, "ids");
        _requireStringData(reason, "reason");
        _beforeWithdrawalERC1155(asset, ids, to);

        IERC1155 token = IERC1155(asset);

        address[] memory addresses = new address[](ids.length);
        for(uint i = 0; i < ids.length; i++)
            addresses[i] = address(this); // actually only this one, but multiple times to call balanceOfBatch

        uint256[] memory balances = token.balanceOfBatch(addresses, ids);
        token.safeBatchTransferFrom(address(this), to, ids, balances, "");
        emit WithdrawalERC1155(asset, ids, to, reason);
    }

    /**
    * @dev This function is called before withdrawal takes place.
    * Override to add custom conditions or actions.
    */
    function _beforeWithdrawal(address to) internal virtual {
    }

    /**
    * @dev This function is called before ERC20 withdrawal takes place.
    * Override to add custom conditions or actions.
    */
    function _beforeWithdrawalERC20(address asset, address to) internal virtual {
    }

    /**
    * @dev This function is called before ERC721 withdrawal takes place.
    * Override to add custom conditions or actions.
    */
    function _beforeWithdrawalERC721(address asset, uint256[] calldata ids, address to) internal virtual {
    }

    /**
    * @dev This function is called before ERC1155 withdrawal takes place.
    * Override to add custom conditions or actions.
    */
    function _beforeWithdrawalERC1155(address asset, uint256[] calldata ids, address to) internal virtual {
    }
}




/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}



/**
 * @dev Partial interface for FearWolf contract (only what we need from it here).
 */
interface IFearWolf is IAccessControl {
    function setInitialOwner(address initialOwner, uint256 wolvesCount) external;
    function DISTRIBUTOR_ROLE() external view returns (bytes32);
}

/**
 * @dev Contract for distribution FEAR Wolf NFT within INO Sale and public sale phases.
 */
contract FearWolfDistributor is AccessControl, Pausable, Withdrawable, ReentrancyGuard {
    using SafeMath for uint256;
    using Strings for uint256;

    /**
    * @dev Emitted when number of wolves an account can reserve on INO Sale is changed.
    */
    event PresaleWolvesPerAccountLimitChanged(uint256 presaleWolvesPerAccountLimit);
    /**
    * @dev Emitted when number of wolves possible to mint in one call is changed.
    */
    event BatchMintingLimitChanged(uint256 batchMintingLimit);
    /**
    * @dev Emitted when INO Sale / Public Sale start timestamps are changed.
    */
    event DatesChanged(uint256 whitelistedPresaleStart, uint256 publicPresaleStart, uint256 saleStart, uint256 claimingStart);
    /**
    * @dev Emitted when prices are changed.
    */
    event PricesChanged(uint256 presalePrice, uint256 salePriceMax, uint256 salePriceMin);
    /**
    * @dev Emitted when dutch auction parameters are changed.
    */
    event DutchAuctionParametersChanged(uint256 dutchAuctionStep, uint256 dutchAuctionStepDuration);
    /**
    * @dev Emitted when wolves count is changed.
    */
    event WolvesCountChanged(uint256 presaleWolvesCount, uint256 saleWolvesCount, uint256 giftWolvesCount);
    /**
    * @dev Emitted when FEAR Wolf contract address is set.
    */
    event FearWolfContractAddressSet(address fearWolfContractAddress);
    /**
    * @dev Emitted when FEAR Wolf is reserved.
    */
    event WolvesReserved(address indexed account, uint256 amount);
    /**
    * @dev Emitted when FEAR Wolf is claimed.
    */
    event WolvesClaimed(address indexed account, uint256 amount);
    /**
    * @dev Emitted when FEAR Wolf is bought.
    */
    event WolvesBought(address indexed account, uint256 price, uint256 amount);
    /**
    * @dev Emitted when FEAR Wolf is gifted.
    */
    event WolvesGifted(address indexed account, uint256 amount);


    /**
    * @dev Number of wolves an account can reserve on INO Sale.
    */
    uint256 public presaleWolvesPerAccountLimit = 5;

    /**
    * @dev Number of wolves available for minting at once.
    */
    uint256 public batchMintingLimit = 10;

    /**
    * @dev Total numbers of wolves reserved during INO Sale.
    */
    uint256 public totalWolvesReserved;
    /**
    * @dev Total numbers of wolves bought during Public Sale.
    */
    uint256 public totalWolvesBought;

    // Timestamps
    uint256 public whitelistedPresaleStart;
    uint256 public publicPresaleStart;
    uint256 public saleStart;
    uint256 public claimingStart;

    // Prices in ETH
    uint256 public presalePrice = 1 * 10 ** 17; // 0.10 ETH
    uint256 public salePriceMax = 2 * 10 ** 17; // 0.20 ETH
    uint256 public salePriceMin = 18 * 10 ** 16; // 0.18 ETH

    // Dutch Auction - 0.001 ETH price drop every 2 hours, 40 hours totally
    uint256 public dutchAuctionStep = 1 * 10 ** 15;
    uint256 public dutchAuctionStepDuration = 2 hours;

    // Wolves Counts
    uint256 public initialPresaleWolvesCount = 2000;
    uint256 public initialSaleWolvesCount = 4000;
    uint256 private presaleWolvesCount = 2000;
    uint256 private saleWolvesCount = 4000;
    uint256 private giftWolvesCount = 66;

    /**
    * @dev FEAR Wolf contract address.
    */
    address public fearWolfContractAddress;
    IFearWolf private fearWolfContract;

    // address => wolves reserved on INO Sale
    mapping (address => uint256) private wolvesReserved;

    // address => wolves bought on Public Sale
    mapping (address => uint256) private wolvesBought;

    // address => true for already claimed reserved wolves
    mapping (address => bool) private claimed;

    // address => true for whitelisted
    mapping (address => bool) private whitelisted;


    constructor() {
        whitelistedPresaleStart = block.timestamp + 7 days;
        publicPresaleStart = whitelistedPresaleStart + 4 days;
        saleStart = whitelistedPresaleStart + 7 days;
        claimingStart = whitelistedPresaleStart + 14 days;
    }

    function _beforeUnpause() internal view virtual override {
        require(fearWolfContractAddress != address(0), "FEAR Wolf contract must be set before unpausing");
        require(fearWolfContract.hasRole(fearWolfContract.DISTRIBUTOR_ROLE(), address(this)), "Distributor role missing");
    }

    /**
    * @dev Returns whitelisted status for the caller.
    * @return True if the caller is whitelisted, false - otherwise.
    */
    function getMyWhitelistedStatus() external view returns (bool) {
        return whitelisted[_msgSender()];
    }

    /**
    * @dev Returns number of FEAR Wolves reserved for the caller.
    * @return Number of FEAR Wolves.
    */
    function getMyNumberOfWolvesReserved() external view returns (uint256) {
        return wolvesReserved[_msgSender()];
    }

    /**
    * @dev Returns number of FEAR Wolves claimed by the caller.
    * @return Number of FEAR Wolves.
    */
    function getMyNumberOfWolvesClaimed() external view returns (uint256) {
        return claimed[_msgSender()] ? wolvesReserved[_msgSender()] : 0;
    }

    /**
    * @dev Returns number of FEAR Wolves bought by the caller.
    * @return Number of FEAR Wolves.
    */
    function getMyNumberOfWolvesBought() external view returns (uint256) {
        return wolvesBought[_msgSender()];
    }

    /**
    * @dev Returns number of FEAR Wolves left available for reservation on INO Sale.
    * @return Number of FEAR Wolves.
    */
    function getPresaleWolvesAvailable() external view returns (uint256) {
        if (block.timestamp < saleStart)
            return presaleWolvesCount;
        else
            return 0;
    }

    /**
    * @dev Returns number of FEAR Wolves left available for buying on Public Sale.
    * @return Number of FEAR Wolves.
    */
    function getPublicSaleWolvesAvailable() external view returns (uint256) {
        if (block.timestamp < saleStart)
            return saleWolvesCount;
        else
            return presaleWolvesCount + saleWolvesCount; // unsold INO Sale wolves are added to wolves available for sale
    }

    /**
    * @dev Returns number of FEAR Wolves left available for gifting.
    * @return Number of FEAR Wolves.
    */
    function getGiftWolvesAvailable() external view returns (uint256) {
        return giftWolvesCount;
    }

    /**
    * @dev Returns current FEAR Wolf price in ETH for Public Sale.
    * @return Amount of ETH.
    */
    function getCurrentPrice() public view returns (uint256) {
        if (block.timestamp < saleStart)
            return salePriceMax;

        uint256 stepsCount = (block.timestamp - saleStart) / dutchAuctionStepDuration;
        if (stepsCount < (salePriceMax - salePriceMin) / dutchAuctionStep)
            return salePriceMax - stepsCount * dutchAuctionStep;
        else
            return salePriceMin;
    }


    /**
    * @dev Allows caller to reserve FEAR Wolf by paying ETH at INO Sale's price.
    * @param wolvesCount Number of wolves to reserve.
    * Requirements:
    * - Contract must not be paused;
    * - INO Sale phase must be active;
    * - Unless Public INO Sale is active, user must be whitelisted to reserve a wolf;
    * - Caller must be a wallet address and not a contract;
    * - Number of wolves to reserve must be greater than zero;
    * - Number of wolves to reserve must be less than or equal to wolves left available for reservation;
    * - The sum of wolves to reserve and wolves reserved by the caller already must be less or equal to maximum allowed number of reserved wolves per account;
    * - Sum of ETH sent must be exactly equal to INO Sale's price multiplied by number of wolves to reserve.
    * Emits {WolvesReserved} event on success.
    */
    function reserveWolves(uint256 wolvesCount) external payable whenNotPaused nonReentrant {
        address caller = _msgSender();

        require(block.timestamp >= whitelistedPresaleStart, "INO phase is not active yet");
        require(block.timestamp < saleStart, "INO phase is over");
        require(block.timestamp >= publicPresaleStart || whitelisted[caller], "Only whitelisted users can reserve a wolf now");

        require(tx.origin == caller, "Contracts are not allowed");
        require(wolvesCount > 0, "Cannot reserve zero wolves");
        require(presaleWolvesCount >= wolvesCount, "Not enough wolves available for reservation");
        require(wolvesReserved[caller] + wolvesCount <= presaleWolvesPerAccountLimit, "Amount of wolves to reserve exceeds INO wolves per account limit");

        require(msg.value >= wolvesCount.mul(presalePrice), "Insufficient ETH sent");
        require(msg.value <= wolvesCount.mul(presalePrice), "Too much ETH sent");
        
        presaleWolvesCount -= wolvesCount;
        totalWolvesReserved += wolvesCount;
        wolvesReserved[caller] += wolvesCount;

        emit WolvesReserved(caller, wolvesCount);
    }

    /**
    * @dev Allows caller to claim reserved FEAR Wolf.
    * Requirements:
    * - Contract must not be paused;
    * - Claiming phase must already started;
    * - Caller must have at least one FEAR wolf reserved;
    * - Caller have not claimed their FEAR wolves yet.
    * Emits {WolvesClaimed} event on success.
    */
    function claimWolves() external whenNotPaused nonReentrant {
        address caller = _msgSender();
        uint256 wolvesCount = wolvesReserved[caller];

        require(block.timestamp >= claimingStart, "Claiming is not active yet");
        require(wolvesCount > 0, "You don't have any wolves reserved");
        require(!claimed[caller], "You have claimed your wolves already");
        
        claimed[caller] = true;
        fearWolfContract.setInitialOwner(caller, wolvesCount);
        emit WolvesClaimed(caller, wolvesCount);
    }

    /**
    * @dev Allows caller to buy FEAR Wolf during Public Sale phase.
    * @param wolvesCount Number of wolves to buy.
    * Requirements:
    * - Contract must not be paused;
    * - Public Sale phase must be active;
    * - Caller must be a wallet address and not a contract;
    * - Number of wolves to buy must be greater than zero;
    * - Number of wolves to buy must be less than or equal to wolves left available for buying at Public Sale;
    * - Number of wolves to buy must be less than or equal to number of wolves available for minting at once;
    * - Sum of ETH sent must be greater or equal to current price (dutch auction takes place) multiplied by number of wolves to buy.
    * Emits {WolvesBought} event on success.
    */
    function buyWolves(uint256 wolvesCount) external payable whenNotPaused nonReentrant {
        address caller = _msgSender();
        uint256 price = getCurrentPrice();

        require(block.timestamp >= saleStart, "Public sale is not active yet");
        require(tx.origin == caller, "Contracts are not allowed");
        require(wolvesCount > 0, "Cannot buy zero wolves");
        require(presaleWolvesCount + saleWolvesCount >= wolvesCount, "Not enough wolves available for buying");
        require(wolvesCount <= batchMintingLimit, string(abi.encodePacked("Cannot buy more than ", batchMintingLimit.toString(), " at once")));
        require(msg.value >= wolvesCount.mul(price), "Insufficient ETH sent");

        if (presaleWolvesCount > 0) {
            // moving any wolves left after presale to public sale
            saleWolvesCount += presaleWolvesCount;
            presaleWolvesCount = 0;
        }

        saleWolvesCount -= wolvesCount;
        totalWolvesBought += wolvesCount;
        wolvesBought[caller] += wolvesCount;

        fearWolfContract.setInitialOwner(caller, wolvesCount);
        emit WolvesBought(caller, price, wolvesCount);
    }


    function setDates(uint256 _whitelistedPresaleStart, uint256 _publicPresaleStart, uint256 _saleStart, uint256 _claimingStart) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < whitelistedPresaleStart ||
                        (whitelistedPresaleStart == _whitelistedPresaleStart
                        && publicPresaleStart == _publicPresaleStart), "Too late, presale is already active");
        require(block.timestamp < saleStart, "Too late, sale is already active");
        require((block.timestamp < _whitelistedPresaleStart || whitelistedPresaleStart == _whitelistedPresaleStart)
                && (block.timestamp < _publicPresaleStart || publicPresaleStart == _publicPresaleStart)
                && block.timestamp < _saleStart
                && block.timestamp < _claimingStart, "Cannot set timestamps to the past");
        require(_whitelistedPresaleStart < _publicPresaleStart
                && _publicPresaleStart < _saleStart
                && _saleStart < _claimingStart, "Wrong timestamps order");

        whitelistedPresaleStart = _whitelistedPresaleStart;
        publicPresaleStart = _publicPresaleStart;
        saleStart = _saleStart;
        claimingStart = _claimingStart;
        emit DatesChanged(whitelistedPresaleStart, publicPresaleStart, saleStart, claimingStart);
    }
    function setPrices(uint256 _presalePrice, uint256 _salePriceMax, uint256 _salePriceMin) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < whitelistedPresaleStart || _presalePrice == presalePrice, "Too late, presale is already active");
        require(block.timestamp < saleStart, "Too late, sale is already active");
        require(_salePriceMax >= _salePriceMin, "Wrong max/min sale prices order");
        presalePrice = _presalePrice;
        salePriceMax = _salePriceMax;
        salePriceMin = _salePriceMin;
        emit PricesChanged(presalePrice, salePriceMax, salePriceMin);
    }
    function setPresaleWolvesPerAccountLimit(uint256 _presaleWolvesPerAccountLimit) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < whitelistedPresaleStart, "Too late, presale is already active");
        require(_presaleWolvesPerAccountLimit <= batchMintingLimit, "Cannot set presaleWolvesPerAccountLimit greater than batchMintingLimit");
        presaleWolvesPerAccountLimit = _presaleWolvesPerAccountLimit;
        emit PresaleWolvesPerAccountLimitChanged(presaleWolvesPerAccountLimit);
    }
    function setBatchMintingLimit(uint256 _batchMintingLimit) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < saleStart, "Too late, sale is already active");
        require(presaleWolvesPerAccountLimit <= _batchMintingLimit, "Cannot set batchMintingLimit less than presaleWolvesPerAccountLimit");
        batchMintingLimit = _batchMintingLimit;
        emit BatchMintingLimitChanged(batchMintingLimit);
    }
    function setDutchAuctionParameters(uint256 _dutchAuctionStep, uint256 _dutchAuctionStepDuration) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < saleStart, "Too late, sale is already active");
        dutchAuctionStep = _dutchAuctionStep;
        dutchAuctionStepDuration = _dutchAuctionStepDuration;
        emit DutchAuctionParametersChanged(dutchAuctionStep, dutchAuctionStepDuration);
    }
    function setWolvesCount(uint256 _presaleWolvesCount, uint256 _saleWolvesCount, uint256 _giftWolvesCount) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < whitelistedPresaleStart || initialPresaleWolvesCount == _presaleWolvesCount, "Too late, presale is already active");
        require(block.timestamp < saleStart, "Too late, sale is already active");

        presaleWolvesCount = _presaleWolvesCount;
        initialPresaleWolvesCount = _presaleWolvesCount;
        saleWolvesCount = _saleWolvesCount;
        initialSaleWolvesCount = _saleWolvesCount;
        giftWolvesCount = _giftWolvesCount;
        emit WolvesCountChanged(presaleWolvesCount, saleWolvesCount, giftWolvesCount);
    }
    function setFearWolfContractAddress(address _address) external onlyRole(MANAGER_ROLE) {
        require(block.timestamp < whitelistedPresaleStart, "Too late, presale is already active");
        require(_address != address(0), "Cannot set zero address");
        fearWolfContractAddress = _address;
        fearWolfContract = IFearWolf(fearWolfContractAddress);
        emit FearWolfContractAddressSet(fearWolfContractAddress);
    }

    function addWhitelistedAddress(address _address) external onlyRole(ADMIN_ROLE) {
        whitelisted[_address] = true;
    }

    function addWhitelistedAddresses(address[] calldata _addresses) external onlyRole(ADMIN_ROLE) {
        for (uint i = 0; i < _addresses.length; i++)
            whitelisted[_addresses[i]] = true;
    }

    function giftWolves(address _address, uint256 wolvesCount) external whenNotPaused nonReentrant onlyRole(ADMIN_ROLE) {
        require(giftWolvesCount >= wolvesCount, "Not enough wolves left to gift");
        require(wolvesCount <= batchMintingLimit, string(abi.encodePacked("Cannot gift more than ", batchMintingLimit.toString(), " at once")));
        giftWolvesCount -= wolvesCount;
        fearWolfContract.setInitialOwner(_address, wolvesCount);
        emit WolvesGifted(_address, wolvesCount);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"batchMintingLimit","type":"uint256"}],"name":"BatchMintingLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"whitelistedPresaleStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"publicPresaleStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"saleStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimingStart","type":"uint256"}],"name":"DatesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"dutchAuctionStep","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dutchAuctionStepDuration","type":"uint256"}],"name":"DutchAuctionParametersChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fearWolfContractAddress","type":"address"}],"name":"FearWolfContractAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"presaleWolvesPerAccountLimit","type":"uint256"}],"name":"PresaleWolvesPerAccountLimitChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"presalePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"salePriceMax","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"salePriceMin","type":"uint256"}],"name":"PricesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"Withdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"WithdrawalERC1155","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"WithdrawalERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"WithdrawalERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WolvesBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WolvesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"presaleWolvesCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"saleWolvesCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"giftWolvesCount","type":"uint256"}],"name":"WolvesCountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WolvesGifted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WolvesReserved","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addWhitelistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addWhitelistedAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batchMintingLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wolvesCount","type":"uint256"}],"name":"buyWolves","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimWolves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimingStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dutchAuctionStep","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dutchAuctionStepDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fearWolfContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGiftWolvesAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyNumberOfWolvesBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyNumberOfWolvesClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyNumberOfWolvesReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyWhitelistedStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPresaleWolvesAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPublicSaleWolvesAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"wolvesCount","type":"uint256"}],"name":"giftWolves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialPresaleWolvesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialSaleWolvesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleWolvesPerAccountLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicPresaleStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wolvesCount","type":"uint256"}],"name":"reserveWolves","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"salePriceMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salePriceMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_batchMintingLimit","type":"uint256"}],"name":"setBatchMintingLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_whitelistedPresaleStart","type":"uint256"},{"internalType":"uint256","name":"_publicPresaleStart","type":"uint256"},{"internalType":"uint256","name":"_saleStart","type":"uint256"},{"internalType":"uint256","name":"_claimingStart","type":"uint256"}],"name":"setDates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dutchAuctionStep","type":"uint256"},{"internalType":"uint256","name":"_dutchAuctionStepDuration","type":"uint256"}],"name":"setDutchAuctionParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setFearWolfContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_presaleWolvesPerAccountLimit","type":"uint256"}],"name":"setPresaleWolvesPerAccountLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_presalePrice","type":"uint256"},{"internalType":"uint256","name":"_salePriceMax","type":"uint256"},{"internalType":"uint256","name":"_salePriceMin","type":"uint256"}],"name":"setPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_presaleWolvesCount","type":"uint256"},{"internalType":"uint256","name":"_saleWolvesCount","type":"uint256"},{"internalType":"uint256","name":"_giftWolvesCount","type":"uint256"}],"name":"setWolvesCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWolvesBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWolvesReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistedPresaleStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"withdrawERC1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"reason","type":"string"}],"name":"withdrawERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526005600455600a60055567016345785d8a0000600c556702c68af0bb140000600d5567027f7d0bdb920000600e5566038d7ea4c68000600f55611c206010556107d0601155610fa06012556107d0601355610fa060145560426015553480156200006d57600080fd5b5062000080637965db0b60e01b62000190565b6200009363149bdbdd60e21b3362000214565b620000a76420b236b4b760d91b3362000214565b620000c46626b0b730b3b2b960c91b63149bdbdd60e21b62000237565b620000d6631cf1473b60e31b62000190565b620000f2652830bab9b2b960d11b63149bdbdd60e21b62000237565b6002805460ff1916600117905562000111630a85bd0160e11b62000190565b62000123630271189760e51b62000190565b62000135630b9d782160e31b62000190565b6001600355620001494262093a8062000316565b60088190556200015d906205460062000316565b600955600854620001729062093a8062000316565b600a5560085462000187906212750062000316565b600b556200033d565b6001600160e01b03198082161415620001ef5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b6200022082826200028e565b620002338263149bdbdd60e21b62000237565b5050565b60008281526001602081905260409091200154819060405184907fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff90600090a4600091825260016020819052604090922090910155565b60008281526001602090815260408083206001600160a01b038516845290915290205460ff16620002335760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b600082198211156200033857634e487b7160e01b600052601160045260246000fd5b500190565b613e52806200034d6000396000f3fe6080604052600436106103755760003560e01c80637e8c7f08116101d1578063bc197c8111610102578063eaed3b0c116100a0578063f23a6e611161006f578063f23a6e6114610978578063f5e13712146109a4578063fc681bda146109ba578063ff7f536b146109d057600080fd5b8063eaed3b0c14610905578063eb91d37e14610925578063ec87621c1461093a578063ee776b231461095857600080fd5b8063caeba137116100dc578063caeba137146108a0578063d547741f146108b5578063d8b8a311146108d5578063e63ab1e9146108e857600080fd5b8063bc197c8114610834578063bd66238114610860578063ca2cfc201461088057600080fd5b806396324d481161016f578063ab0bcc4111610149578063ab0bcc41146107d3578063ab97cfe7146107e9578063b4486886146107ff578063bbe2c3fc1461081f57600080fd5b806396324d4814610773578063a082a06514610793578063a88fe42d146107b357600080fd5b80638feee0dd116101ab5780638feee0dd146106ef5780639060c7c31461072757806391d148541461073d5780639373ceb21461075d57600080fd5b80637e8c7f08146106aa5780638456cb59146106c55780638b9177f4146106da57600080fd5b806336568abe116102ab5780636176b0941161024957806375b238fc1161022357806375b238fc1461062e5780637697acf71461064a57806377c985171461066a57806378ef4b601461068a57600080fd5b80636176b094146105e357806365784834146105f85780636e6b11011461060e57600080fd5b80634638d0c0116102855780634638d0c01461058a5780635558a805146105a05780635c975abb146105b657806360fe2655146105ce57600080fd5b806336568abe146105405780633f4ba83a14610560578063435076fa1461057557600080fd5b8063248a9ca31161031857806329975b43116102f257806329975b43146104d45780632f2ff15d146104f45780633171eac61461051457806335a98df01461052a57600080fd5b8063248a9ca31461046d57806325b01d0f1461049e57806326ed82dc146104b457600080fd5b80630bc424f6116103545780630bc424f6146103e9578063150b7a02146103fe578063188a2fbe14610442578063235b7b681461045857600080fd5b80620e7fa81461037a57806301adcef2146103a357806301ffc9a7146103b9575b600080fd5b34801561038657600080fd5b50610390600c5481565b6040519081526020015b60405180910390f35b3480156103af57600080fd5b5061039060125481565b3480156103c557600080fd5b506103d96103d436600461316e565b6109f5565b604051901515815260200161039a565b6103fc6103f7366004613198565b610a35565b005b34801561040a57600080fd5b5061042961041936600461327b565b630a85bd0160e11b949350505050565b6040516001600160e01b0319909116815260200161039a565b34801561044e57600080fd5b50610390600e5481565b34801561046457600080fd5b50610390610dcc565b34801561047957600080fd5b50610390610488366004613198565b6000908152600160208190526040909120015490565b3480156104aa57600080fd5b5061039060095481565b3480156104c057600080fd5b506103fc6104cf366004613198565b610de5565b3480156104e057600080fd5b506103fc6104ef3660046132e6565b610edf565b34801561050057600080fd5b506103fc61050f366004613303565b610f17565b34801561052057600080fd5b5061039060105481565b34801561053657600080fd5b5061039060055481565b34801561054c57600080fd5b506103fc61055b366004613303565b610f43565b34801561056c57600080fd5b506103fc610fc1565b34801561058157600080fd5b50610390611031565b34801561059657600080fd5b5061039060115481565b3480156105ac57600080fd5b5061039060075481565b3480156105c257600080fd5b5060025460ff166103d9565b3480156105da57600080fd5b5061039061105e565b3480156105ef57600080fd5b5061039061108a565b34801561060457600080fd5b5061039060085481565b34801561061a57600080fd5b506103fc61062936600461337b565b6110ad565b34801561063a57600080fd5b506103906420b236b4b760d91b81565b34801561065657600080fd5b506103fc6106653660046133cf565b611218565b34801561067657600080fd5b506103fc6106853660046133f1565b611296565b34801561069657600080fd5b506103fc6106a5366004613461565b61135a565b3480156106b657600080fd5b5061039063149bdbdd60e21b81565b3480156106d157600080fd5b506103fc611639565b3480156106e657600080fd5b506103fc611678565b3480156106fb57600080fd5b5060165461070f906001600160a01b031681565b6040516001600160a01b03909116815260200161039a565b34801561073357600080fd5b50610390600d5481565b34801561074957600080fd5b506103d9610758366004613303565b6118c4565b34801561076957600080fd5b5061039060065481565b34801561077f57600080fd5b506103fc61078e3660046134f7565b6118ef565b34801561079f57600080fd5b506103fc6107ae366004613461565b611aa6565b3480156107bf57600080fd5b506103fc6107ce3660046133f1565b611cc3565b3480156107df57600080fd5b50610390600a5481565b3480156107f557600080fd5b50610390600f5481565b34801561080b57600080fd5b506103fc61081a366004613523565b611dc3565b34801561082b57600080fd5b50601554610390565b34801561084057600080fd5b5061042961084f3660046135e3565b63bc197c8160e01b95945050505050565b34801561086c57600080fd5b506103fc61087b366004613198565b611f7a565b34801561088c57600080fd5b506103fc61089b366004613690565b612069565b3480156108ac57600080fd5b506103906120f4565b3480156108c157600080fd5b506103fc6108d0366004613303565b6120ff565b6103fc6108e3366004613198565b612126565b3480156108f457600080fd5b50610390652830bab9b2b960d11b81565b34801561091157600080fd5b506103fc6109203660046136d1565b61257a565b34801561093157600080fd5b5061039061277c565b34801561094657600080fd5b506103906626b0b730b3b2b960c91b81565b34801561096457600080fd5b506103fc6109733660046132e6565b6127fa565b34801561098457600080fd5b50610429610993366004613735565b63f23a6e6160e01b95945050505050565b3480156109b057600080fd5b5061039060045481565b3480156109c657600080fd5b50610390600b5481565b3480156109dc57600080fd5b50336000908152601b602052604090205460ff166103d9565b60006301ffc9a760e01b6001600160e01b031983161480610a2f57506001600160e01b0319821660009081526020819052604090205460ff165b92915050565b60025460ff1615610a615760405162461bcd60e51b8152600401610a589061379d565b60405180910390fd5b60026003541415610a845760405162461bcd60e51b8152600401610a58906137c7565b6002600355336000610a9461277c565b9050600a54421015610ae85760405162461bcd60e51b815260206004820152601d60248201527f5075626c69632073616c65206973206e6f7420616374697665207965740000006044820152606401610a58565b326001600160a01b03831614610b3c5760405162461bcd60e51b815260206004820152601960248201527810dbdb9d1c9858dd1cc8185c99481b9bdd08185b1b1bddd959603a1b6044820152606401610a58565b60008311610b855760405162461bcd60e51b815260206004820152601660248201527543616e6e6f7420627579207a65726f20776f6c76657360501b6044820152606401610a58565b82601454601354610b969190613814565b1015610bf35760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f75676820776f6c76657320617661696c61626c6520666f7220604482015265627579696e6760d01b6064820152608401610a58565b600554831115610c046005546128e0565b604051602001610c149190613858565b60405160208183030381529060405290610c415760405162461bcd60e51b8152600401610a5891906138a7565b50610c4c83826129e5565b341015610c935760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610a58565b60135415610cba5760135460146000828254610caf9190613814565b909155505060006013555b8260146000828254610ccc91906138da565b925050819055508260076000828254610ce59190613814565b90915550506001600160a01b03821660009081526019602052604081208054859290610d12908490613814565b909155505060175460405163a75a904960e01b81526001600160a01b038481166004830152602482018690529091169063a75a904990604401600060405180830381600087803b158015610d6557600080fd5b505af1158015610d79573d6000803e3d6000fd5b505060408051848152602081018790526001600160a01b03861693507fbc75db7cacdfdc08e841c130f68070070bfb190dcc20ef0db5565ba52e20f0169250015b60405180910390a25050600160035550565b6000600a54421015610ddf575060135490565b50600090565b6626b0b730b3b2b960c91b610dfa8133612a6b565b6008544210610e1b5760405162461bcd60e51b8152600401610a58906138f1565b600554821115610ea25760405162461bcd60e51b815260206004820152604660248201527f43616e6e6f74207365742070726573616c65576f6c7665735065724163636f7560448201527f6e744c696d69742067726561746572207468616e2062617463684d696e74696e60648201526519d31a5b5a5d60d21b608482015260a401610a58565b60048290556040518281527ff6ae6873a6f8d6e698acfa20b0b4435a0d084086301071b5e12e1a769ed8630b906020015b60405180910390a15050565b6420b236b4b760d91b610ef28133612a6b565b506001600160a01b03166000908152601b60205260409020805460ff19166001179055565b60008281526001602081905260409091200154610f348133612a6b565b610f3e8383612acd565b505050565b6001600160a01b0381163314610fb35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a58565b610fbd8282612b38565b5050565b652830bab9b2b960d11b610fd58133612a6b565b60025460ff1661101e5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a58565b611026612b9f565b61102e612d57565b50565b6000601881335b6001600160a01b03166001600160a01b0316815260200190815260200160002054905090565b336000908152601a602052604081205460ff1661107b5750600090565b6018600033611038565b905090565b6000600a5442101561109d575060145490565b6014546013546110859190613814565b6420b236b4b760d91b6110c08133612a6b565b6110e48460405180604001604052806002815260200161746f60f01b815250612dea565b61114183838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b6000846001600160a01b03164760405160006040518083038185875af1925050503d806000811461118e576040519150601f19603f3d011682016040523d82523d6000602084013e611193565b606091505b50509050806111d65760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606401610a58565b7f2ec36606a096222bbdda5d6499755ee3f0ad7a6b54bb2d14bdcb6ab3a25a40388585856040516112099392919061395d565b60405180910390a15050505050565b6626b0b730b3b2b960c91b61122d8133612a6b565b600a54421061124e5760405162461bcd60e51b8152600401610a589061398b565b600f839055601082905560408051848152602081018490527fe17a8b6c5a3b11210ca105d617c802256e1f7e351e6d904463f2910fb69ea7a3910160405180910390a1505050565b6626b0b730b3b2b960c91b6112ab8133612a6b565b6008544210806112bc575083601154145b6112d85760405162461bcd60e51b8152600401610a58906138f1565b600a5442106112f95760405162461bcd60e51b8152600401610a589061398b565b6013849055601184905560148390556012839055601582905560408051858152602081018590529081018390527f6a96916dce9022150831fd5318a74b714b097283bceea7d2d975803a64ee5b15906060015b60405180910390a150505050565b6420b236b4b760d91b61136d8133612a6b565b6113948760405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b6113b88460405180604001604052806002815260200161746f60f01b815250612dea565b61140f8686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051808201909152600381526269647360e81b60208201529150612e359050565b61146c83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b866000866001600160401b03811115611487576114876131c6565b6040519080825280602002602001820160405280156114b0578160200160208202803683370190505b50905060005b878110156114fb57308282815181106114d1576114d16139c0565b6001600160a01b0390921660209283029190910190910152806114f3816139d6565b9150506114b6565b506040516313849cfd60e21b81526000906001600160a01b03841690634e1273f49061152f9085908d908d90600401613a27565b60006040518083038186803b15801561154757600080fd5b505afa15801561155b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115839190810190613a89565b604051631759616b60e11b81529091506001600160a01b03841690632eb2c2d6906115ba9030908b908e908e908890600401613b0e565b600060405180830381600087803b1580156115d457600080fd5b505af11580156115e8573d6000803e3d6000fd5b505050507f21aff44ae0e91a2040a97537ae3c9d0f4079c5a106165076503e9cd874318f418a8a8a8a8a8a60405161162596959493929190613b8f565b60405180910390a150505050505050505050565b652830bab9b2b960d11b61164d8133612a6b565b60025460ff16156116705760405162461bcd60e51b8152600401610a589061379d565b61102e612e4c565b60025460ff161561169b5760405162461bcd60e51b8152600401610a589061379d565b600260035414156116be5760405162461bcd60e51b8152600401610a58906137c7565b600260035533600081815260186020526040902054600b544210156117255760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e67206973206e6f7420616374697665207965740000000000006044820152606401610a58565b600081116117805760405162461bcd60e51b815260206004820152602260248201527f596f7520646f6e2774206861766520616e7920776f6c76657320726573657276604482015261195960f21b6064820152608401610a58565b6001600160a01b0382166000908152601a602052604090205460ff16156117f55760405162461bcd60e51b8152602060048201526024808201527f596f75206861766520636c61696d656420796f757220776f6c76657320616c726044820152636561647960e01b6064820152608401610a58565b6001600160a01b038281166000818152601a602052604090819020805460ff19166001179055601754905163a75a904960e01b81526004810192909252602482018490529091169063a75a904990604401600060405180830381600087803b15801561186057600080fd5b505af1158015611874573d6000803e3d6000fd5b50505050816001600160a01b03167f862d73aae7d15fa0e86436f23819591f7215ed3a374f76e7933c6ad621419367826040516118b391815260200190565b60405180910390a250506001600355565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60025460ff16156119125760405162461bcd60e51b8152600401610a589061379d565b600260035414156119355760405162461bcd60e51b8152600401610a58906137c7565b60026003556420b236b4b760d91b61194d8133612a6b565b81601554101561199f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820776f6c766573206c65667420746f206769667400006044820152606401610a58565b6005548211156119b06005546128e0565b6040516020016119c09190613bdb565b604051602081830303815290604052906119ed5760405162461bcd60e51b8152600401610a5891906138a7565b508160156000828254611a0091906138da565b909155505060175460405163a75a904960e01b81526001600160a01b038581166004830152602482018590529091169063a75a904990604401600060405180830381600087803b158015611a5357600080fd5b505af1158015611a67573d6000803e3d6000fd5b50505050826001600160a01b03167fb6e998ea2c56d63d30b28dfae0940848bdb94c483257e11403a39ec5b747d68a83604051610dba91815260200190565b6420b236b4b760d91b611ab98133612a6b565b611ae08760405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b611b048460405180604001604052806002815260200161746f60f01b815250612dea565b611b5b8686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051808201909152600381526269647360e81b60208201529150612e359050565b611bb883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b8660005b86811015611c7757816001600160a01b031663b88d4fde30888b8b86818110611be757611be76139c0565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152608060648201526000608482015260a401600060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b505050508080611c6f906139d6565b915050611bbc565b507f6987697ab2642f042066492c5998ea1f25192ec2a6032e443019dd4a5c5799a2888888888888604051611cb196959493929190613b8f565b60405180910390a15050505050505050565b6626b0b730b3b2b960c91b611cd88133612a6b565b600854421080611ce95750600c5484145b611d055760405162461bcd60e51b8152600401610a58906138f1565b600a544210611d265760405162461bcd60e51b8152600401610a589061398b565b81831015611d765760405162461bcd60e51b815260206004820152601f60248201527f57726f6e67206d61782f6d696e2073616c6520707269636573206f72646572006044820152606401610a58565b600c849055600d839055600e82905560408051858152602081018590529081018390527f8d0d8ae74d5cbaf1f430bf9645898cdb4b4051cbe2d03ac7e653c7e4d90f61419060600161134c565b6626b0b730b3b2b960c91b611dd88133612a6b565b600854421080611df5575084600854148015611df5575083600954145b611e115760405162461bcd60e51b8152600401610a58906138f1565b600a544210611e325760405162461bcd60e51b8152600401610a589061398b565b84421080611e41575084600854145b8015611e57575083421080611e57575083600954145b8015611e6257508242105b8015611e6d57508142105b611ec35760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f74207365742074696d657374616d707320746f20746865207061736044820152601d60fa1b6064820152608401610a58565b8385108015611ed157508284105b8015611edc57508183105b611f215760405162461bcd60e51b81526020600482015260166024820152752bb937b733903a34b6b2b9ba30b6b8399037b93232b960511b6044820152606401610a58565b60088590556009849055600a839055600b8290556040805186815260208101869052908101849052606081018390527fe3a844abba1e79c425f423a61c70553856381c92af277a815042eaa058099e2090608001611209565b6626b0b730b3b2b960c91b611f8f8133612a6b565b600a544210611fb05760405162461bcd60e51b8152600401610a589061398b565b8160045411156120345760405162461bcd60e51b815260206004820152604360248201527f43616e6e6f74207365742062617463684d696e74696e674c696d6974206c657360448201527f73207468616e2070726573616c65576f6c7665735065724163636f756e744c696064820152621b5a5d60ea1b608482015260a401610a58565b60058290556040518281527f7e217fda4a94a1b7da64ee2a8763fbb0b72fb731974d22a50499946057a31a7590602001610ed3565b6420b236b4b760d91b61207c8133612a6b565b60005b828110156120ee576001601b600086868581811061209f5761209f6139c0565b90506020020160208101906120b491906132e6565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806120e6816139d6565b91505061207f565b50505050565b600060198133611038565b6000828152600160208190526040909120015461211c8133612a6b565b610f3e8383612b38565b60025460ff16156121495760405162461bcd60e51b8152600401610a589061379d565b6002600354141561216c5760405162461bcd60e51b8152600401610a58906137c7565b600260035560085433904210156121c55760405162461bcd60e51b815260206004820152601b60248201527f494e4f207068617365206973206e6f74206163746976652079657400000000006044820152606401610a58565b600a54421061220a5760405162461bcd60e51b815260206004820152601160248201527024a72790383430b9b29034b99037bb32b960791b6044820152606401610a58565b6009544210158061223357506001600160a01b0381166000908152601b602052604090205460ff165b6122955760405162461bcd60e51b815260206004820152602d60248201527f4f6e6c792077686974656c69737465642075736572732063616e20726573657260448201526c7665206120776f6c66206e6f7760981b6064820152608401610a58565b326001600160a01b038216146122e95760405162461bcd60e51b815260206004820152601960248201527810dbdb9d1c9858dd1cc8185c99481b9bdd08185b1b1bddd959603a1b6044820152606401610a58565b600082116123395760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742072657365727665207a65726f20776f6c7665730000000000006044820152606401610a58565b81601354101561239f5760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f75676820776f6c76657320617661696c61626c6520666f722060448201526a3932b9b2b93b30ba34b7b760a91b6064820152608401610a58565b6004546001600160a01b0382166000908152601860205260409020546123c6908490613814565b111561243c576040805162461bcd60e51b81526020600482015260248101919091527f416d6f756e74206f6620776f6c76657320746f2072657365727665206578636560448201527f65647320494e4f20776f6c76657320706572206163636f756e74206c696d69746064820152608401610a58565b600c5461244a9083906129e5565b3410156124915760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610a58565b600c5461249f9083906129e5565b3411156124e25760405162461bcd60e51b8152602060048201526011602482015270151bdbc81b5d58da08115512081cd95b9d607a1b6044820152606401610a58565b81601360008282546124f491906138da565b92505081905550816006600082825461250d9190613814565b90915550506001600160a01b0381166000908152601860205260408120805484929061253a908490613814565b90915550506040518281526001600160a01b038216907ff852e51d7d7c3c1e0223d37501a8eb6be5339b3ee492eef7af89a4f94be8c0ad906020016118b3565b6420b236b4b760d91b61258d8133612a6b565b6125b48560405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b6125d88460405180604001604052806002815260200161746f60f01b815250612dea565b61263583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b6040516370a0823160e01b815230600482015285906001600160a01b0382169063a9059cbb90879083906370a082319060240160206040518083038186803b15801561268057600080fd5b505afa158015612694573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b89190613c2b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156126fe57600080fd5b505af1158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190613c44565b507ff219add0525a642c0e89d5831d7e2f2586cb2e567a1c9f29199ddad0ed6bd5868686868660405161276c9493929190613c66565b60405180910390a1505050505050565b6000600a5442101561278f5750600d5490565b6000601054600a54426127a291906138da565b6127ac9190613cb3565b9050600f54600e54600d546127c191906138da565b6127cb9190613cb3565b8110156127f257600f546127df9082613cc7565b600d546127ec91906138da565b91505090565b5050600e5490565b6626b0b730b3b2b960c91b61280f8133612a6b565b60085442106128305760405162461bcd60e51b8152600401610a58906138f1565b6001600160a01b0382166128865760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420736574207a65726f20616464726573730000000000000000006044820152606401610a58565b601680546001600160a01b0384166001600160a01b0319918216811790925560178054909116821790556040519081527fd378da77352bb87155d21b7b010fdc46cfbc12725012d456464c91763ecde8b790602001610ed3565b6060816129045750506040805180820190915260018152600360fc1b602082015290565b8160005b811561292e5780612918816139d6565b91506129279050600a83613cb3565b9150612908565b6000816001600160401b03811115612948576129486131c6565b6040519080825280601f01601f191660200182016040528015612972576020820181803683370190505b5090505b84156129dd576129876001836138da565b9150612994600a86613ce6565b61299f906030613814565b60f81b8183815181106129b4576129b46139c0565b60200101906001600160f81b031916908160001a9053506129d6600a86613cb3565b9450612976565b949350505050565b6000826129f457506000610a2f565b6000612a008385613cc7565b905082612a0d8583613cb3565b14612a645760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610a58565b9392505050565b612a7582826118c4565b610fbd57612a8d816001600160a01b03166014612ea4565b612a968361303f565b604051602001612aa7929190613cfa565b60408051601f198184030181529082905262461bcd60e51b8252610a58916004016138a7565b612ad782826118c4565b610fbd5760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b612b4282826118c4565b15610fbd5760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6016546001600160a01b0316612c0f5760405162461bcd60e51b815260206004820152602f60248201527f4645415220576f6c6620636f6e7472616374206d75737420626520736574206260448201526e65666f726520756e70617573696e6760881b6064820152608401610a58565b60175460408051633c2f61f360e21b815290516001600160a01b03909216916391d1485491839163f0bd87cc91600480820192602092909190829003018186803b158015612c5c57600080fd5b505afa158015612c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c949190613c2b565b6040516001600160e01b031960e084901b168152600481019190915230602482015260440160206040518083038186803b158015612cd157600080fd5b505afa158015612ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d099190613c44565b612d555760405162461bcd60e51b815260206004820152601860248201527f4469737472696275746f7220726f6c65206d697373696e6700000000000000006044820152606401610a58565b565b60025460ff16612da05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a58565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516001600160a01b038316151590612e08908390602001613d6f565b60405160208183030381529060405290610f3e5760405162461bcd60e51b8152600401610a5891906138a7565b81516000141581604051602001612e089190613db0565b60025460ff1615612e6f5760405162461bcd60e51b8152600401610a589061379d565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612dcd3390565b60606000612eb3836002613cc7565b612ebe906002613814565b6001600160401b03811115612ed557612ed56131c6565b6040519080825280601f01601f191660200182016040528015612eff576020820181803683370190505b509050600360fc1b81600081518110612f1a57612f1a6139c0565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f4957612f496139c0565b60200101906001600160f81b031916908160001a9053506000612f6d846002613cc7565b612f78906001613814565b90505b6001811115612ff0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fac57612fac6139c0565b1a60f81b828281518110612fc257612fc26139c0565b60200101906001600160f81b031916908160001a90535060049490941c93612fe981613de5565b9050612f7b565b508315612a645760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a58565b606060005b60208160ff161080156130785750828160ff1660208110613067576130676139c0565b1a60f81b6001600160f81b03191615155b1561308f578061308781613dfc565b915050613044565b60008160ff166001600160401b038111156130ac576130ac6131c6565b6040519080825280601f01601f1916602001820160405280156130d6576020820181803683370190505b509050600091505b60208260ff161080156131125750838260ff1660208110613101576131016139c0565b1a60f81b6001600160f81b03191615155b15612a6457838260ff166020811061312c5761312c6139c0565b1a60f81b818360ff1681518110613145576131456139c0565b60200101906001600160f81b031916908160001a9053508161316681613dfc565b9250506130de565b60006020828403121561318057600080fd5b81356001600160e01b031981168114612a6457600080fd5b6000602082840312156131aa57600080fd5b5035919050565b6001600160a01b038116811461102e57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613204576132046131c6565b604052919050565b600082601f83011261321d57600080fd5b81356001600160401b03811115613236576132366131c6565b613249601f8201601f19166020016131dc565b81815284602083860101111561325e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561329157600080fd5b843561329c816131b1565b935060208501356132ac816131b1565b92506040850135915060608501356001600160401b038111156132ce57600080fd5b6132da8782880161320c565b91505092959194509250565b6000602082840312156132f857600080fd5b8135612a64816131b1565b6000806040838503121561331657600080fd5b823591506020830135613328816131b1565b809150509250929050565b60008083601f84011261334557600080fd5b5081356001600160401b0381111561335c57600080fd5b60208301915083602082850101111561337457600080fd5b9250929050565b60008060006040848603121561339057600080fd5b833561339b816131b1565b925060208401356001600160401b038111156133b657600080fd5b6133c286828701613333565b9497909650939450505050565b600080604083850312156133e257600080fd5b50508035926020909101359150565b60008060006060848603121561340657600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261342f57600080fd5b5081356001600160401b0381111561344657600080fd5b6020830191508360208260051b850101111561337457600080fd5b6000806000806000806080878903121561347a57600080fd5b8635613485816131b1565b955060208701356001600160401b03808211156134a157600080fd5b6134ad8a838b0161341d565b9097509550604089013591506134c2826131b1565b909350606088013590808211156134d857600080fd5b506134e589828a01613333565b979a9699509497509295939492505050565b6000806040838503121561350a57600080fd5b8235613515816131b1565b946020939093013593505050565b6000806000806080858703121561353957600080fd5b5050823594602084013594506040840135936060013592509050565b60006001600160401b0382111561356e5761356e6131c6565b5060051b60200190565b600082601f83011261358957600080fd5b8135602061359e61359983613555565b6131dc565b82815260059290921b840181019181810190868411156135bd57600080fd5b8286015b848110156135d857803583529183019183016135c1565b509695505050505050565b600080600080600060a086880312156135fb57600080fd5b8535613606816131b1565b94506020860135613616816131b1565b935060408601356001600160401b038082111561363257600080fd5b61363e89838a01613578565b9450606088013591508082111561365457600080fd5b61366089838a01613578565b9350608088013591508082111561367657600080fd5b506136838882890161320c565b9150509295509295909350565b600080602083850312156136a357600080fd5b82356001600160401b038111156136b957600080fd5b6136c58582860161341d565b90969095509350505050565b600080600080606085870312156136e757600080fd5b84356136f2816131b1565b93506020850135613702816131b1565b925060408501356001600160401b0381111561371d57600080fd5b61372987828801613333565b95989497509550505050565b600080600080600060a0868803121561374d57600080fd5b8535613758816131b1565b94506020860135613768816131b1565b9350604086013592506060860135915060808601356001600160401b0381111561379157600080fd5b6136838882890161320c565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115613827576138276137fe565b500190565b60005b8381101561384757818101518382015260200161382f565b838111156120ee5750506000910152565b74021b0b73737ba10313abc9036b7b932903a3430b71605d1b81526000825161388881601585016020870161382c565b67206174206f6e636560c01b6015939091019283015250601d01919050565b60208152600082518060208401526138c681604085016020870161382c565b601f01601f19169190910160400192915050565b6000828210156138ec576138ec6137fe565b500390565b60208082526023908201527f546f6f206c6174652c2070726573616c6520697320616c72656164792061637460408201526269766560e81b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03841681526040602082018190526000906139829083018486613934565b95945050505050565b6020808252818101527f546f6f206c6174652c2073616c6520697320616c726561647920616374697665604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156139ea576139ea6137fe565b5060010190565b81835260006001600160fb1b03831115613a0a57600080fd5b8260051b8083602087013760009401602001938452509192915050565b604080825284519082018190526000906020906060840190828801845b82811015613a695781516001600160a01b031684529284019290840190600101613a44565b50505083810382850152613a7e8186886139f1565b979650505050505050565b60006020808385031215613a9c57600080fd5b82516001600160401b03811115613ab257600080fd5b8301601f81018513613ac357600080fd5b8051613ad161359982613555565b81815260059190911b82018301908381019087831115613af057600080fd5b928401925b82841015613a7e57835182529284019290840190613af5565b600060018060a01b03808816835260208188168185015260a06040850152613b3a60a0850187896139f1565b8481036060860152855180825282870193509082019060005b81811015613b6f57845183529383019391830191600101613b53565b505084810360808601526000815281810193505050509695505050505050565b600060018060a01b03808916835260806020840152613bb260808401888a6139f1565b81871660408501528381036060850152613bcd818688613934565b9a9950505050505050505050565b75021b0b73737ba1033b4b33a1036b7b932903a3430b7160551b815260008251613c0c81601685016020870161382c565b67206174206f6e636560c01b6016939091019283015250601e01919050565b600060208284031215613c3d57600080fd5b5051919050565b600060208284031215613c5657600080fd5b81518015158114612a6457600080fd5b6001600160a01b03858116825284166020820152606060408201819052600090613c939083018486613934565b9695505050505050565b634e487b7160e01b600052601260045260246000fd5b600082613cc257613cc2613c9d565b500490565b6000816000190483118215151615613ce157613ce16137fe565b500290565b600082613cf557613cf5613c9d565b500690565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613d3281601785016020880161382c565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613d6381602884016020880161382c565b01602801949350505050565b60008251613d8181846020870161382c565b7f3a2063616e6e6f7420757365207a65726f206164647265737300000000000000920191825250601901919050565b60008251613dc281846020870161382c565b703a2063616e6e6f7420626520656d70747960781b920191825250601101919050565b600081613df457613df46137fe565b506000190190565b600060ff821660ff811415613e1357613e136137fe565b6001019291505056fea2646970667358221220fc947642a734a44d35b15f53b1bbf35cf22a7f071314779ab306b159472328a964736f6c63430008090033

Deployed Bytecode

0x6080604052600436106103755760003560e01c80637e8c7f08116101d1578063bc197c8111610102578063eaed3b0c116100a0578063f23a6e611161006f578063f23a6e6114610978578063f5e13712146109a4578063fc681bda146109ba578063ff7f536b146109d057600080fd5b8063eaed3b0c14610905578063eb91d37e14610925578063ec87621c1461093a578063ee776b231461095857600080fd5b8063caeba137116100dc578063caeba137146108a0578063d547741f146108b5578063d8b8a311146108d5578063e63ab1e9146108e857600080fd5b8063bc197c8114610834578063bd66238114610860578063ca2cfc201461088057600080fd5b806396324d481161016f578063ab0bcc4111610149578063ab0bcc41146107d3578063ab97cfe7146107e9578063b4486886146107ff578063bbe2c3fc1461081f57600080fd5b806396324d4814610773578063a082a06514610793578063a88fe42d146107b357600080fd5b80638feee0dd116101ab5780638feee0dd146106ef5780639060c7c31461072757806391d148541461073d5780639373ceb21461075d57600080fd5b80637e8c7f08146106aa5780638456cb59146106c55780638b9177f4146106da57600080fd5b806336568abe116102ab5780636176b0941161024957806375b238fc1161022357806375b238fc1461062e5780637697acf71461064a57806377c985171461066a57806378ef4b601461068a57600080fd5b80636176b094146105e357806365784834146105f85780636e6b11011461060e57600080fd5b80634638d0c0116102855780634638d0c01461058a5780635558a805146105a05780635c975abb146105b657806360fe2655146105ce57600080fd5b806336568abe146105405780633f4ba83a14610560578063435076fa1461057557600080fd5b8063248a9ca31161031857806329975b43116102f257806329975b43146104d45780632f2ff15d146104f45780633171eac61461051457806335a98df01461052a57600080fd5b8063248a9ca31461046d57806325b01d0f1461049e57806326ed82dc146104b457600080fd5b80630bc424f6116103545780630bc424f6146103e9578063150b7a02146103fe578063188a2fbe14610442578063235b7b681461045857600080fd5b80620e7fa81461037a57806301adcef2146103a357806301ffc9a7146103b9575b600080fd5b34801561038657600080fd5b50610390600c5481565b6040519081526020015b60405180910390f35b3480156103af57600080fd5b5061039060125481565b3480156103c557600080fd5b506103d96103d436600461316e565b6109f5565b604051901515815260200161039a565b6103fc6103f7366004613198565b610a35565b005b34801561040a57600080fd5b5061042961041936600461327b565b630a85bd0160e11b949350505050565b6040516001600160e01b0319909116815260200161039a565b34801561044e57600080fd5b50610390600e5481565b34801561046457600080fd5b50610390610dcc565b34801561047957600080fd5b50610390610488366004613198565b6000908152600160208190526040909120015490565b3480156104aa57600080fd5b5061039060095481565b3480156104c057600080fd5b506103fc6104cf366004613198565b610de5565b3480156104e057600080fd5b506103fc6104ef3660046132e6565b610edf565b34801561050057600080fd5b506103fc61050f366004613303565b610f17565b34801561052057600080fd5b5061039060105481565b34801561053657600080fd5b5061039060055481565b34801561054c57600080fd5b506103fc61055b366004613303565b610f43565b34801561056c57600080fd5b506103fc610fc1565b34801561058157600080fd5b50610390611031565b34801561059657600080fd5b5061039060115481565b3480156105ac57600080fd5b5061039060075481565b3480156105c257600080fd5b5060025460ff166103d9565b3480156105da57600080fd5b5061039061105e565b3480156105ef57600080fd5b5061039061108a565b34801561060457600080fd5b5061039060085481565b34801561061a57600080fd5b506103fc61062936600461337b565b6110ad565b34801561063a57600080fd5b506103906420b236b4b760d91b81565b34801561065657600080fd5b506103fc6106653660046133cf565b611218565b34801561067657600080fd5b506103fc6106853660046133f1565b611296565b34801561069657600080fd5b506103fc6106a5366004613461565b61135a565b3480156106b657600080fd5b5061039063149bdbdd60e21b81565b3480156106d157600080fd5b506103fc611639565b3480156106e657600080fd5b506103fc611678565b3480156106fb57600080fd5b5060165461070f906001600160a01b031681565b6040516001600160a01b03909116815260200161039a565b34801561073357600080fd5b50610390600d5481565b34801561074957600080fd5b506103d9610758366004613303565b6118c4565b34801561076957600080fd5b5061039060065481565b34801561077f57600080fd5b506103fc61078e3660046134f7565b6118ef565b34801561079f57600080fd5b506103fc6107ae366004613461565b611aa6565b3480156107bf57600080fd5b506103fc6107ce3660046133f1565b611cc3565b3480156107df57600080fd5b50610390600a5481565b3480156107f557600080fd5b50610390600f5481565b34801561080b57600080fd5b506103fc61081a366004613523565b611dc3565b34801561082b57600080fd5b50601554610390565b34801561084057600080fd5b5061042961084f3660046135e3565b63bc197c8160e01b95945050505050565b34801561086c57600080fd5b506103fc61087b366004613198565b611f7a565b34801561088c57600080fd5b506103fc61089b366004613690565b612069565b3480156108ac57600080fd5b506103906120f4565b3480156108c157600080fd5b506103fc6108d0366004613303565b6120ff565b6103fc6108e3366004613198565b612126565b3480156108f457600080fd5b50610390652830bab9b2b960d11b81565b34801561091157600080fd5b506103fc6109203660046136d1565b61257a565b34801561093157600080fd5b5061039061277c565b34801561094657600080fd5b506103906626b0b730b3b2b960c91b81565b34801561096457600080fd5b506103fc6109733660046132e6565b6127fa565b34801561098457600080fd5b50610429610993366004613735565b63f23a6e6160e01b95945050505050565b3480156109b057600080fd5b5061039060045481565b3480156109c657600080fd5b50610390600b5481565b3480156109dc57600080fd5b50336000908152601b602052604090205460ff166103d9565b60006301ffc9a760e01b6001600160e01b031983161480610a2f57506001600160e01b0319821660009081526020819052604090205460ff165b92915050565b60025460ff1615610a615760405162461bcd60e51b8152600401610a589061379d565b60405180910390fd5b60026003541415610a845760405162461bcd60e51b8152600401610a58906137c7565b6002600355336000610a9461277c565b9050600a54421015610ae85760405162461bcd60e51b815260206004820152601d60248201527f5075626c69632073616c65206973206e6f7420616374697665207965740000006044820152606401610a58565b326001600160a01b03831614610b3c5760405162461bcd60e51b815260206004820152601960248201527810dbdb9d1c9858dd1cc8185c99481b9bdd08185b1b1bddd959603a1b6044820152606401610a58565b60008311610b855760405162461bcd60e51b815260206004820152601660248201527543616e6e6f7420627579207a65726f20776f6c76657360501b6044820152606401610a58565b82601454601354610b969190613814565b1015610bf35760405162461bcd60e51b815260206004820152602660248201527f4e6f7420656e6f75676820776f6c76657320617661696c61626c6520666f7220604482015265627579696e6760d01b6064820152608401610a58565b600554831115610c046005546128e0565b604051602001610c149190613858565b60405160208183030381529060405290610c415760405162461bcd60e51b8152600401610a5891906138a7565b50610c4c83826129e5565b341015610c935760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610a58565b60135415610cba5760135460146000828254610caf9190613814565b909155505060006013555b8260146000828254610ccc91906138da565b925050819055508260076000828254610ce59190613814565b90915550506001600160a01b03821660009081526019602052604081208054859290610d12908490613814565b909155505060175460405163a75a904960e01b81526001600160a01b038481166004830152602482018690529091169063a75a904990604401600060405180830381600087803b158015610d6557600080fd5b505af1158015610d79573d6000803e3d6000fd5b505060408051848152602081018790526001600160a01b03861693507fbc75db7cacdfdc08e841c130f68070070bfb190dcc20ef0db5565ba52e20f0169250015b60405180910390a25050600160035550565b6000600a54421015610ddf575060135490565b50600090565b6626b0b730b3b2b960c91b610dfa8133612a6b565b6008544210610e1b5760405162461bcd60e51b8152600401610a58906138f1565b600554821115610ea25760405162461bcd60e51b815260206004820152604660248201527f43616e6e6f74207365742070726573616c65576f6c7665735065724163636f7560448201527f6e744c696d69742067726561746572207468616e2062617463684d696e74696e60648201526519d31a5b5a5d60d21b608482015260a401610a58565b60048290556040518281527ff6ae6873a6f8d6e698acfa20b0b4435a0d084086301071b5e12e1a769ed8630b906020015b60405180910390a15050565b6420b236b4b760d91b610ef28133612a6b565b506001600160a01b03166000908152601b60205260409020805460ff19166001179055565b60008281526001602081905260409091200154610f348133612a6b565b610f3e8383612acd565b505050565b6001600160a01b0381163314610fb35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a58565b610fbd8282612b38565b5050565b652830bab9b2b960d11b610fd58133612a6b565b60025460ff1661101e5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a58565b611026612b9f565b61102e612d57565b50565b6000601881335b6001600160a01b03166001600160a01b0316815260200190815260200160002054905090565b336000908152601a602052604081205460ff1661107b5750600090565b6018600033611038565b905090565b6000600a5442101561109d575060145490565b6014546013546110859190613814565b6420b236b4b760d91b6110c08133612a6b565b6110e48460405180604001604052806002815260200161746f60f01b815250612dea565b61114183838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b6000846001600160a01b03164760405160006040518083038185875af1925050503d806000811461118e576040519150601f19603f3d011682016040523d82523d6000602084013e611193565b606091505b50509050806111d65760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b6044820152606401610a58565b7f2ec36606a096222bbdda5d6499755ee3f0ad7a6b54bb2d14bdcb6ab3a25a40388585856040516112099392919061395d565b60405180910390a15050505050565b6626b0b730b3b2b960c91b61122d8133612a6b565b600a54421061124e5760405162461bcd60e51b8152600401610a589061398b565b600f839055601082905560408051848152602081018490527fe17a8b6c5a3b11210ca105d617c802256e1f7e351e6d904463f2910fb69ea7a3910160405180910390a1505050565b6626b0b730b3b2b960c91b6112ab8133612a6b565b6008544210806112bc575083601154145b6112d85760405162461bcd60e51b8152600401610a58906138f1565b600a5442106112f95760405162461bcd60e51b8152600401610a589061398b565b6013849055601184905560148390556012839055601582905560408051858152602081018590529081018390527f6a96916dce9022150831fd5318a74b714b097283bceea7d2d975803a64ee5b15906060015b60405180910390a150505050565b6420b236b4b760d91b61136d8133612a6b565b6113948760405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b6113b88460405180604001604052806002815260200161746f60f01b815250612dea565b61140f8686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051808201909152600381526269647360e81b60208201529150612e359050565b61146c83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b866000866001600160401b03811115611487576114876131c6565b6040519080825280602002602001820160405280156114b0578160200160208202803683370190505b50905060005b878110156114fb57308282815181106114d1576114d16139c0565b6001600160a01b0390921660209283029190910190910152806114f3816139d6565b9150506114b6565b506040516313849cfd60e21b81526000906001600160a01b03841690634e1273f49061152f9085908d908d90600401613a27565b60006040518083038186803b15801561154757600080fd5b505afa15801561155b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115839190810190613a89565b604051631759616b60e11b81529091506001600160a01b03841690632eb2c2d6906115ba9030908b908e908e908890600401613b0e565b600060405180830381600087803b1580156115d457600080fd5b505af11580156115e8573d6000803e3d6000fd5b505050507f21aff44ae0e91a2040a97537ae3c9d0f4079c5a106165076503e9cd874318f418a8a8a8a8a8a60405161162596959493929190613b8f565b60405180910390a150505050505050505050565b652830bab9b2b960d11b61164d8133612a6b565b60025460ff16156116705760405162461bcd60e51b8152600401610a589061379d565b61102e612e4c565b60025460ff161561169b5760405162461bcd60e51b8152600401610a589061379d565b600260035414156116be5760405162461bcd60e51b8152600401610a58906137c7565b600260035533600081815260186020526040902054600b544210156117255760405162461bcd60e51b815260206004820152601a60248201527f436c61696d696e67206973206e6f7420616374697665207965740000000000006044820152606401610a58565b600081116117805760405162461bcd60e51b815260206004820152602260248201527f596f7520646f6e2774206861766520616e7920776f6c76657320726573657276604482015261195960f21b6064820152608401610a58565b6001600160a01b0382166000908152601a602052604090205460ff16156117f55760405162461bcd60e51b8152602060048201526024808201527f596f75206861766520636c61696d656420796f757220776f6c76657320616c726044820152636561647960e01b6064820152608401610a58565b6001600160a01b038281166000818152601a602052604090819020805460ff19166001179055601754905163a75a904960e01b81526004810192909252602482018490529091169063a75a904990604401600060405180830381600087803b15801561186057600080fd5b505af1158015611874573d6000803e3d6000fd5b50505050816001600160a01b03167f862d73aae7d15fa0e86436f23819591f7215ed3a374f76e7933c6ad621419367826040516118b391815260200190565b60405180910390a250506001600355565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60025460ff16156119125760405162461bcd60e51b8152600401610a589061379d565b600260035414156119355760405162461bcd60e51b8152600401610a58906137c7565b60026003556420b236b4b760d91b61194d8133612a6b565b81601554101561199f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f75676820776f6c766573206c65667420746f206769667400006044820152606401610a58565b6005548211156119b06005546128e0565b6040516020016119c09190613bdb565b604051602081830303815290604052906119ed5760405162461bcd60e51b8152600401610a5891906138a7565b508160156000828254611a0091906138da565b909155505060175460405163a75a904960e01b81526001600160a01b038581166004830152602482018590529091169063a75a904990604401600060405180830381600087803b158015611a5357600080fd5b505af1158015611a67573d6000803e3d6000fd5b50505050826001600160a01b03167fb6e998ea2c56d63d30b28dfae0940848bdb94c483257e11403a39ec5b747d68a83604051610dba91815260200190565b6420b236b4b760d91b611ab98133612a6b565b611ae08760405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b611b048460405180604001604052806002815260200161746f60f01b815250612dea565b611b5b8686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051808201909152600381526269647360e81b60208201529150612e359050565b611bb883838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b8660005b86811015611c7757816001600160a01b031663b88d4fde30888b8b86818110611be757611be76139c0565b6040516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909316602485015250602090910201356044820152608060648201526000608482015260a401600060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b505050508080611c6f906139d6565b915050611bbc565b507f6987697ab2642f042066492c5998ea1f25192ec2a6032e443019dd4a5c5799a2888888888888604051611cb196959493929190613b8f565b60405180910390a15050505050505050565b6626b0b730b3b2b960c91b611cd88133612a6b565b600854421080611ce95750600c5484145b611d055760405162461bcd60e51b8152600401610a58906138f1565b600a544210611d265760405162461bcd60e51b8152600401610a589061398b565b81831015611d765760405162461bcd60e51b815260206004820152601f60248201527f57726f6e67206d61782f6d696e2073616c6520707269636573206f72646572006044820152606401610a58565b600c849055600d839055600e82905560408051858152602081018590529081018390527f8d0d8ae74d5cbaf1f430bf9645898cdb4b4051cbe2d03ac7e653c7e4d90f61419060600161134c565b6626b0b730b3b2b960c91b611dd88133612a6b565b600854421080611df5575084600854148015611df5575083600954145b611e115760405162461bcd60e51b8152600401610a58906138f1565b600a544210611e325760405162461bcd60e51b8152600401610a589061398b565b84421080611e41575084600854145b8015611e57575083421080611e57575083600954145b8015611e6257508242105b8015611e6d57508142105b611ec35760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f74207365742074696d657374616d707320746f20746865207061736044820152601d60fa1b6064820152608401610a58565b8385108015611ed157508284105b8015611edc57508183105b611f215760405162461bcd60e51b81526020600482015260166024820152752bb937b733903a34b6b2b9ba30b6b8399037b93232b960511b6044820152606401610a58565b60088590556009849055600a839055600b8290556040805186815260208101869052908101849052606081018390527fe3a844abba1e79c425f423a61c70553856381c92af277a815042eaa058099e2090608001611209565b6626b0b730b3b2b960c91b611f8f8133612a6b565b600a544210611fb05760405162461bcd60e51b8152600401610a589061398b565b8160045411156120345760405162461bcd60e51b815260206004820152604360248201527f43616e6e6f74207365742062617463684d696e74696e674c696d6974206c657360448201527f73207468616e2070726573616c65576f6c7665735065724163636f756e744c696064820152621b5a5d60ea1b608482015260a401610a58565b60058290556040518281527f7e217fda4a94a1b7da64ee2a8763fbb0b72fb731974d22a50499946057a31a7590602001610ed3565b6420b236b4b760d91b61207c8133612a6b565b60005b828110156120ee576001601b600086868581811061209f5761209f6139c0565b90506020020160208101906120b491906132e6565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806120e6816139d6565b91505061207f565b50505050565b600060198133611038565b6000828152600160208190526040909120015461211c8133612a6b565b610f3e8383612b38565b60025460ff16156121495760405162461bcd60e51b8152600401610a589061379d565b6002600354141561216c5760405162461bcd60e51b8152600401610a58906137c7565b600260035560085433904210156121c55760405162461bcd60e51b815260206004820152601b60248201527f494e4f207068617365206973206e6f74206163746976652079657400000000006044820152606401610a58565b600a54421061220a5760405162461bcd60e51b815260206004820152601160248201527024a72790383430b9b29034b99037bb32b960791b6044820152606401610a58565b6009544210158061223357506001600160a01b0381166000908152601b602052604090205460ff165b6122955760405162461bcd60e51b815260206004820152602d60248201527f4f6e6c792077686974656c69737465642075736572732063616e20726573657260448201526c7665206120776f6c66206e6f7760981b6064820152608401610a58565b326001600160a01b038216146122e95760405162461bcd60e51b815260206004820152601960248201527810dbdb9d1c9858dd1cc8185c99481b9bdd08185b1b1bddd959603a1b6044820152606401610a58565b600082116123395760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742072657365727665207a65726f20776f6c7665730000000000006044820152606401610a58565b81601354101561239f5760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f75676820776f6c76657320617661696c61626c6520666f722060448201526a3932b9b2b93b30ba34b7b760a91b6064820152608401610a58565b6004546001600160a01b0382166000908152601860205260409020546123c6908490613814565b111561243c576040805162461bcd60e51b81526020600482015260248101919091527f416d6f756e74206f6620776f6c76657320746f2072657365727665206578636560448201527f65647320494e4f20776f6c76657320706572206163636f756e74206c696d69746064820152608401610a58565b600c5461244a9083906129e5565b3410156124915760405162461bcd60e51b8152602060048201526015602482015274125b9cdd59999a58da595b9d08115512081cd95b9d605a1b6044820152606401610a58565b600c5461249f9083906129e5565b3411156124e25760405162461bcd60e51b8152602060048201526011602482015270151bdbc81b5d58da08115512081cd95b9d607a1b6044820152606401610a58565b81601360008282546124f491906138da565b92505081905550816006600082825461250d9190613814565b90915550506001600160a01b0381166000908152601860205260408120805484929061253a908490613814565b90915550506040518281526001600160a01b038216907ff852e51d7d7c3c1e0223d37501a8eb6be5339b3ee492eef7af89a4f94be8c0ad906020016118b3565b6420b236b4b760d91b61258d8133612a6b565b6125b48560405180604001604052806005815260200164185cdcd95d60da1b815250612dea565b6125d88460405180604001604052806002815260200161746f60f01b815250612dea565b61263583838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260068152653932b0b9b7b760d11b60208201529150612e359050565b6040516370a0823160e01b815230600482015285906001600160a01b0382169063a9059cbb90879083906370a082319060240160206040518083038186803b15801561268057600080fd5b505afa158015612694573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b89190613c2b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156126fe57600080fd5b505af1158015612712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127369190613c44565b507ff219add0525a642c0e89d5831d7e2f2586cb2e567a1c9f29199ddad0ed6bd5868686868660405161276c9493929190613c66565b60405180910390a1505050505050565b6000600a5442101561278f5750600d5490565b6000601054600a54426127a291906138da565b6127ac9190613cb3565b9050600f54600e54600d546127c191906138da565b6127cb9190613cb3565b8110156127f257600f546127df9082613cc7565b600d546127ec91906138da565b91505090565b5050600e5490565b6626b0b730b3b2b960c91b61280f8133612a6b565b60085442106128305760405162461bcd60e51b8152600401610a58906138f1565b6001600160a01b0382166128865760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f7420736574207a65726f20616464726573730000000000000000006044820152606401610a58565b601680546001600160a01b0384166001600160a01b0319918216811790925560178054909116821790556040519081527fd378da77352bb87155d21b7b010fdc46cfbc12725012d456464c91763ecde8b790602001610ed3565b6060816129045750506040805180820190915260018152600360fc1b602082015290565b8160005b811561292e5780612918816139d6565b91506129279050600a83613cb3565b9150612908565b6000816001600160401b03811115612948576129486131c6565b6040519080825280601f01601f191660200182016040528015612972576020820181803683370190505b5090505b84156129dd576129876001836138da565b9150612994600a86613ce6565b61299f906030613814565b60f81b8183815181106129b4576129b46139c0565b60200101906001600160f81b031916908160001a9053506129d6600a86613cb3565b9450612976565b949350505050565b6000826129f457506000610a2f565b6000612a008385613cc7565b905082612a0d8583613cb3565b14612a645760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610a58565b9392505050565b612a7582826118c4565b610fbd57612a8d816001600160a01b03166014612ea4565b612a968361303f565b604051602001612aa7929190613cfa565b60408051601f198184030181529082905262461bcd60e51b8252610a58916004016138a7565b612ad782826118c4565b610fbd5760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b612b4282826118c4565b15610fbd5760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6016546001600160a01b0316612c0f5760405162461bcd60e51b815260206004820152602f60248201527f4645415220576f6c6620636f6e7472616374206d75737420626520736574206260448201526e65666f726520756e70617573696e6760881b6064820152608401610a58565b60175460408051633c2f61f360e21b815290516001600160a01b03909216916391d1485491839163f0bd87cc91600480820192602092909190829003018186803b158015612c5c57600080fd5b505afa158015612c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c949190613c2b565b6040516001600160e01b031960e084901b168152600481019190915230602482015260440160206040518083038186803b158015612cd157600080fd5b505afa158015612ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d099190613c44565b612d555760405162461bcd60e51b815260206004820152601860248201527f4469737472696275746f7220726f6c65206d697373696e6700000000000000006044820152606401610a58565b565b60025460ff16612da05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a58565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516001600160a01b038316151590612e08908390602001613d6f565b60405160208183030381529060405290610f3e5760405162461bcd60e51b8152600401610a5891906138a7565b81516000141581604051602001612e089190613db0565b60025460ff1615612e6f5760405162461bcd60e51b8152600401610a589061379d565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612dcd3390565b60606000612eb3836002613cc7565b612ebe906002613814565b6001600160401b03811115612ed557612ed56131c6565b6040519080825280601f01601f191660200182016040528015612eff576020820181803683370190505b509050600360fc1b81600081518110612f1a57612f1a6139c0565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f4957612f496139c0565b60200101906001600160f81b031916908160001a9053506000612f6d846002613cc7565b612f78906001613814565b90505b6001811115612ff0576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fac57612fac6139c0565b1a60f81b828281518110612fc257612fc26139c0565b60200101906001600160f81b031916908160001a90535060049490941c93612fe981613de5565b9050612f7b565b508315612a645760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a58565b606060005b60208160ff161080156130785750828160ff1660208110613067576130676139c0565b1a60f81b6001600160f81b03191615155b1561308f578061308781613dfc565b915050613044565b60008160ff166001600160401b038111156130ac576130ac6131c6565b6040519080825280601f01601f1916602001820160405280156130d6576020820181803683370190505b509050600091505b60208260ff161080156131125750838260ff1660208110613101576131016139c0565b1a60f81b6001600160f81b03191615155b15612a6457838260ff166020811061312c5761312c6139c0565b1a60f81b818360ff1681518110613145576131456139c0565b60200101906001600160f81b031916908160001a9053508161316681613dfc565b9250506130de565b60006020828403121561318057600080fd5b81356001600160e01b031981168114612a6457600080fd5b6000602082840312156131aa57600080fd5b5035919050565b6001600160a01b038116811461102e57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613204576132046131c6565b604052919050565b600082601f83011261321d57600080fd5b81356001600160401b03811115613236576132366131c6565b613249601f8201601f19166020016131dc565b81815284602083860101111561325e57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561329157600080fd5b843561329c816131b1565b935060208501356132ac816131b1565b92506040850135915060608501356001600160401b038111156132ce57600080fd5b6132da8782880161320c565b91505092959194509250565b6000602082840312156132f857600080fd5b8135612a64816131b1565b6000806040838503121561331657600080fd5b823591506020830135613328816131b1565b809150509250929050565b60008083601f84011261334557600080fd5b5081356001600160401b0381111561335c57600080fd5b60208301915083602082850101111561337457600080fd5b9250929050565b60008060006040848603121561339057600080fd5b833561339b816131b1565b925060208401356001600160401b038111156133b657600080fd5b6133c286828701613333565b9497909650939450505050565b600080604083850312156133e257600080fd5b50508035926020909101359150565b60008060006060848603121561340657600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261342f57600080fd5b5081356001600160401b0381111561344657600080fd5b6020830191508360208260051b850101111561337457600080fd5b6000806000806000806080878903121561347a57600080fd5b8635613485816131b1565b955060208701356001600160401b03808211156134a157600080fd5b6134ad8a838b0161341d565b9097509550604089013591506134c2826131b1565b909350606088013590808211156134d857600080fd5b506134e589828a01613333565b979a9699509497509295939492505050565b6000806040838503121561350a57600080fd5b8235613515816131b1565b946020939093013593505050565b6000806000806080858703121561353957600080fd5b5050823594602084013594506040840135936060013592509050565b60006001600160401b0382111561356e5761356e6131c6565b5060051b60200190565b600082601f83011261358957600080fd5b8135602061359e61359983613555565b6131dc565b82815260059290921b840181019181810190868411156135bd57600080fd5b8286015b848110156135d857803583529183019183016135c1565b509695505050505050565b600080600080600060a086880312156135fb57600080fd5b8535613606816131b1565b94506020860135613616816131b1565b935060408601356001600160401b038082111561363257600080fd5b61363e89838a01613578565b9450606088013591508082111561365457600080fd5b61366089838a01613578565b9350608088013591508082111561367657600080fd5b506136838882890161320c565b9150509295509295909350565b600080602083850312156136a357600080fd5b82356001600160401b038111156136b957600080fd5b6136c58582860161341d565b90969095509350505050565b600080600080606085870312156136e757600080fd5b84356136f2816131b1565b93506020850135613702816131b1565b925060408501356001600160401b0381111561371d57600080fd5b61372987828801613333565b95989497509550505050565b600080600080600060a0868803121561374d57600080fd5b8535613758816131b1565b94506020860135613768816131b1565b9350604086013592506060860135915060808601356001600160401b0381111561379157600080fd5b6136838882890161320c565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115613827576138276137fe565b500190565b60005b8381101561384757818101518382015260200161382f565b838111156120ee5750506000910152565b74021b0b73737ba10313abc9036b7b932903a3430b71605d1b81526000825161388881601585016020870161382c565b67206174206f6e636560c01b6015939091019283015250601d01919050565b60208152600082518060208401526138c681604085016020870161382c565b601f01601f19169190910160400192915050565b6000828210156138ec576138ec6137fe565b500390565b60208082526023908201527f546f6f206c6174652c2070726573616c6520697320616c72656164792061637460408201526269766560e81b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b03841681526040602082018190526000906139829083018486613934565b95945050505050565b6020808252818101527f546f6f206c6174652c2073616c6520697320616c726561647920616374697665604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60006000198214156139ea576139ea6137fe565b5060010190565b81835260006001600160fb1b03831115613a0a57600080fd5b8260051b8083602087013760009401602001938452509192915050565b604080825284519082018190526000906020906060840190828801845b82811015613a695781516001600160a01b031684529284019290840190600101613a44565b50505083810382850152613a7e8186886139f1565b979650505050505050565b60006020808385031215613a9c57600080fd5b82516001600160401b03811115613ab257600080fd5b8301601f81018513613ac357600080fd5b8051613ad161359982613555565b81815260059190911b82018301908381019087831115613af057600080fd5b928401925b82841015613a7e57835182529284019290840190613af5565b600060018060a01b03808816835260208188168185015260a06040850152613b3a60a0850187896139f1565b8481036060860152855180825282870193509082019060005b81811015613b6f57845183529383019391830191600101613b53565b505084810360808601526000815281810193505050509695505050505050565b600060018060a01b03808916835260806020840152613bb260808401888a6139f1565b81871660408501528381036060850152613bcd818688613934565b9a9950505050505050505050565b75021b0b73737ba1033b4b33a1036b7b932903a3430b7160551b815260008251613c0c81601685016020870161382c565b67206174206f6e636560c01b6016939091019283015250601e01919050565b600060208284031215613c3d57600080fd5b5051919050565b600060208284031215613c5657600080fd5b81518015158114612a6457600080fd5b6001600160a01b03858116825284166020820152606060408201819052600090613c939083018486613934565b9695505050505050565b634e487b7160e01b600052601260045260246000fd5b600082613cc257613cc2613c9d565b500490565b6000816000190483118215151615613ce157613ce16137fe565b500290565b600082613cf557613cf5613c9d565b500690565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613d3281601785016020880161382c565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613d6381602884016020880161382c565b01602801949350505050565b60008251613d8181846020870161382c565b7f3a2063616e6e6f7420757365207a65726f206164647265737300000000000000920191825250601901919050565b60008251613dc281846020870161382c565b703a2063616e6e6f7420626520656d70747960781b920191825250601101919050565b600081613df457613df46137fe565b506000190190565b600060ff821660ff811415613e1357613e136137fe565b6001019291505056fea2646970667358221220fc947642a734a44d35b15f53b1bbf35cf22a7f071314779ab306b159472328a964736f6c63430008090033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.