ETH Price: $3,550.93 (+6.73%)

Token

Cerby Token (CERBY)
 

Overview

Max Total Supply

14,230,973,827.291318715868878266 CERBY

Holders

2,391 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.000000000000000001 CERBY

Value
$0.00
0x011ea68c15f4a8316da45c1e7844311cdd0ba149
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Cerby Token is a Cross-Chain Token Standard aiming to allow users to easily bridge between blockchains and DLT networks.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
DefiFactoryToken

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-05-24
*/

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

/*
🌎 Website: https://DefiFactory.finance
💻 Dashboard: https://app.defifactory.fi
👉 Telegram: https://t.me/DefiFactoryBot?start=info-join
*/

struct TaxAmountsInput {
    address sender;
    address recipient;
    uint transferAmount;
    uint senderRealBalance;
    uint recipientRealBalance;
}
struct TaxAmountsOutput {
    uint senderRealBalance;
    uint recipientRealBalance;
    uint burnAndRewardAmount;
    uint recipientGetsAmount;
}
struct TemporaryReferralRealAmountsBulk {
    address addr;
    uint realBalance;
}

interface INoBotsTech {
    function prepareTaxAmounts(
        TaxAmountsInput calldata taxAmountsInput
    ) 
        external
        returns(TaxAmountsOutput memory taxAmountsOutput);
    
    function getTemporaryReferralRealAmountsBulk(address[] calldata addrs)
        external
        view
        returns (TemporaryReferralRealAmountsBulk[] memory);
        
    function prepareHumanAddressMintOrBurnRewardsAmounts(bool isMint, address account, uint desiredAmountToMintOrBurn)
        external
        returns (uint realAmountToMintOrBurn);
        
    function getBalance(address account, uint accountBalance)
        external
        view
        returns(uint);
        
    function getRealBalance(address account, uint accountBalance)
        external
        view
        returns(uint);
        
    function getRealBalanceTeamVestingContract(uint accountBalance)
        external
        view
        returns(uint);
        
    function getTotalSupply()
        external
        view
        returns (uint);
        
    function grantRole(bytes32 role, address account) 
        external;
        
    function getCalculatedReferrerRewards(address addr, address[] calldata referrals)
        external
        view
        returns (uint);
        
    function getCachedReferrerRewards(address addr)
        external
        view
        returns (uint);
    
    function updateReferrersRewards(address[] calldata referrals)
        external;
    
    function clearReferrerRewards(address addr)
        external;
    
    function chargeCustomTax(uint taxAmount, uint accountBalance)
        external
        returns (uint);
    
    function chargeCustomTaxTeamVestingContract(uint taxAmount, uint accountBalance)
        external
        returns (uint);
        
    function registerReferral(address referral, address referrer)
        external;
        
    function filterNonZeroReferrals(address[] calldata referrals)
        external
        view
        returns (address[] memory);
        
    function publicForcedUpdateCacheMultiplier()
        external;
    
    event MultiplierUpdated(uint newMultiplier);
    event BotTransactionDetected(address from, address to, uint transferAmount, uint taxedAmount);
    event ReferrerRewardUpdated(address referrer, uint amount);
    event ReferralRegistered(address referral, address referrer);
    event ReferrerReplaced(address referral, address referrerFrom, address referrerTo);
}

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender 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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "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);
    }

    /**
     * @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] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

}

/**
 * @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 External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function renounceRole(bytes32 role, address account) external;
}

/**
 * @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, msg.sender));
 *     ...
 * }
 * ```
 *
 * 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}.
 *
 * By default, the admin role for all roles is `ROLE_ADMIN`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `ROLE_ADMIN` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping (address => bool) members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant ROLE_ADMIN = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    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 {_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 Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @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`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     */
    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.toHexString(uint256(role), 32)
            )));
        }
    }

    /**
     * @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) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @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 Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable {
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping (bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {grantRole} to track enumerable memberships
     */
    function grantRole(bytes32 role, address account) public virtual override {
        super.grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {revokeRole} to track enumerable memberships
     */
    function revokeRole(bytes32 role, address account) public virtual override {
        super.revokeRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {renounceRole} to track enumerable memberships
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        super.renounceRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {_setupRole} to track enumerable memberships
     */
    function _setupRole(bytes32 role, address account) internal virtual override {
        super._setupRole(role, account);
        _roleMembers[role].add(account);
    }
}

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

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

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

/**
 * @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 Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping (address => uint256) internal _RealBalances;

    mapping (address => mapping (address => uint256)) internal _allowances;


    string internal _name;
    string internal _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The defaut value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // overriden in parent contract
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _RealBalances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) { }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);

        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual { }


    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
}

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
                v := add(shr(255, vs), 27)
            }
        } else {
            revert("ECDSA: invalid signature length");
        }

        return recover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
        require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;
    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                typeHash,
                name,
                version,
                block.chainid,
                address(this)
            )
        );
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }
}

/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping (address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {
    }

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {
        // solhint-disable-next-line not-rely-on-time
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(
            abi.encode(
                _PERMIT_TYPEHASH,
                owner,
                spender,
                value,
                _useNonce(owner),
                deadline
            )
        );

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}

contract DefiFactoryToken is Context, AccessControlEnumerable, ERC20, ERC20Permit {
    bytes32 public constant ROLE_MINTER = keccak256("ROLE_MINTER");
    bytes32 public constant ROLE_BURNER = keccak256("ROLE_BURNER");
    bytes32 public constant ROLE_TRANSFERER = keccak256("ROLE_TRANSFERER");
    bytes32 public constant ROLE_MODERATOR = keccak256("ROLE_MODERATOR");
    bytes32 public constant ROLE_TAXER = keccak256("ROLE_TAXER");
    
    uint constant NOBOTS_TECH_CONTRACT_ID = 0;
    uint constant TEAM_VESTING_CONTRACT_ID = 1;
    
    address[] utilsContracts;
    
    struct AccessSettings {
        bool isMinter;
        bool isBurner;
        bool isTransferer;
        bool isModerator;
        bool isTaxer;
        
        address addr;
    }
    
    bool public isPaused;
    
    address constant BURN_ADDRESS = address(0x0);
    
    event VestedAmountClaimed(address recipient, uint amount);
    event UpdatedUtilsContracts(AccessSettings[] accessSettings);
    event TransferCustom(address sender, address recipient, uint amount);
    event MintHumanAddress(address recipient, uint amount);
    event BurnHumanAddress(address sender, uint amount);
    event ClaimedReferralRewards(address recipient, uint amount);
    
    event MintedByBridge(address recipient, uint amount);
    event BurnedByBridge(address sender, uint amount);

    constructor() 
        ERC20("Defi Factory Token", "DEFT") 
        ERC20Permit("Defi Factory Token")
    {
        _setupRole(ROLE_ADMIN, _msgSender());
        _setupRole(ROLE_MINTER, _msgSender());
        _setupRole(ROLE_BURNER, _msgSender());
        _setupRole(ROLE_TRANSFERER, _msgSender());
        _setupRole(ROLE_MODERATOR, _msgSender());
        _setupRole(ROLE_TAXER, _msgSender());
    }
    
    modifier notPausedContract {
        require(
            !isPaused,
            "DEFT: paused"
        );
        _;
    }
    
    modifier pausedContract {
        require(
            isPaused,
            "DEFT: !paused"
        );
        _;
    }
    
    function updateNameAndSymbol(string calldata __name, string calldata __symbol)
        external
        onlyRole(ROLE_ADMIN)
    {
        _name = __name;
        _symbol = __symbol;
    }
    
    function balanceOf(address account) 
        public 
        view 
        override 
        returns(uint) 
    {
        return INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]).
            getBalance(account, _RealBalances[account]);
    }
    
    function totalSupply() 
        public 
        view 
        override 
        returns (uint) 
    {
        return INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]).
            getTotalSupply();
    }
    
    function pauseContract()
        external
        notPausedContract
        onlyRole(ROLE_ADMIN)
    {
        isPaused = true;
    }
    
    function resumeContract()
        external
        pausedContract
        onlyRole(ROLE_ADMIN)
    {
        isPaused = false;
    }
    
    function transfer(address recipient, uint256 amount) 
        public 
        notPausedContract
        virtual 
        override 
        returns (bool) 
    {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }
    
    function transferFrom(address sender, address recipient, uint256 amount) 
        public 
        notPausedContract
        virtual 
        override 
        returns (bool) 
    {
        require(
            sender != BURN_ADDRESS,
            "DEFT: !burn"
        );
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "DEFT: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);

        return true;
    }
    
    function moderatorTransferFromWhilePaused(address sender, address recipient, uint256 amount) 
        external 
        pausedContract
        onlyRole(ROLE_MODERATOR)
        returns (bool) 
    {
        require(
            sender != BURN_ADDRESS,
            "DEFT: !burn"
        );
        _transfer(sender, recipient, amount);

        return true;
    }
    
    function transferCustom(address sender, address recipient, uint256 amount)
        external
        notPausedContract
        onlyRole(ROLE_TRANSFERER)
    {
        require(
            sender != BURN_ADDRESS,
            "DEFT: !burn"
        );
        _transfer(sender, recipient, amount);
        
        emit TransferCustom(sender, recipient, amount);
    }
    
    function _transfer(address sender, address recipient, uint amount) 
        internal
        virtual 
        override 
    {
        require(
            recipient != BURN_ADDRESS,
            "DEFT: !burn"
        );
        require(
            sender != recipient,
            "DEFT: !self"
        );
        
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        TaxAmountsOutput memory taxAmountsOutput = iNoBotsTech.prepareTaxAmounts(
            TaxAmountsInput(
                sender,
                recipient,
                amount,
                _RealBalances[sender],
                _RealBalances[recipient]
            )
        );
        
        _RealBalances[sender] = taxAmountsOutput.senderRealBalance;
        _RealBalances[recipient] = taxAmountsOutput.recipientRealBalance;
        
        emit Transfer(sender, recipient, taxAmountsOutput.recipientGetsAmount);
        emit Transfer(sender, BURN_ADDRESS, taxAmountsOutput.burnAndRewardAmount);
    }
    
    function transferFromTeamVestingContract(address recipient, uint256 amount)
        external
        notPausedContract
    {
        address vestingContract = utilsContracts[TEAM_VESTING_CONTRACT_ID];
        require(vestingContract == _msgSender(), "DEFT: !VESTING_CONTRACT");
        
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        _RealBalances[vestingContract] -= amount;
        _RealBalances[recipient] += 
            iNoBotsTech.getRealBalanceTeamVestingContract(amount);
        
        iNoBotsTech.publicForcedUpdateCacheMultiplier();
        
        emit Transfer(vestingContract, recipient, amount);
        emit VestedAmountClaimed(recipient, amount);
    }
    
    function registerReferral(address referrer)
        public
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        return iNoBotsTech.registerReferral(_msgSender(), referrer);
    }
    
    function getTemporaryReferralRealAmountsBulk(address[] calldata addrs)
        external
        view
        returns (TemporaryReferralRealAmountsBulk[] memory)
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        return iNoBotsTech.getTemporaryReferralRealAmountsBulk(addrs);
    }
    
    function getCachedReferrerRewards(address addr)
        external
        view
        returns(uint)
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        return iNoBotsTech.getCachedReferrerRewards(addr);
    }
    
    function getCalculatedReferrerRewards(address addr, address[] calldata referrals)
        external
        view
        returns(uint)
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        return iNoBotsTech.getCalculatedReferrerRewards(addr, referrals);
    }
    
    function filterNonZeroReferrals(address[] calldata referrals)
        external
        view
        returns (address[] memory)
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        return iNoBotsTech.filterNonZeroReferrals(referrals);
    }
    
    function claimReferrerRewards(address[] calldata referrals)
        external
        notPausedContract
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        iNoBotsTech.updateReferrersRewards(referrals);
        
        uint rewards = iNoBotsTech.getCachedReferrerRewards(_msgSender());
        require(rewards > 0, "DEFT: !rewards");
        
        iNoBotsTech.clearReferrerRewards(_msgSender());
        _mintHumanAddress(_msgSender(), rewards);
        
        emit ClaimedReferralRewards(_msgSender(), rewards);
    }
    
    function chargeCustomTax(address from, uint amount)
        external
        notPausedContract
        onlyRole(ROLE_TAXER)
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        _RealBalances[from] = iNoBotsTech.chargeCustomTax(amount, _RealBalances[from]);
    }
    
    function updateUtilsContracts(AccessSettings[] calldata accessSettings)
        external
        onlyRole(ROLE_ADMIN)
    {
        for(uint i = 0; i < utilsContracts.length; i++)
        {
            revokeRole(ROLE_MINTER, utilsContracts[i]);
            revokeRole(ROLE_BURNER, utilsContracts[i]);
            revokeRole(ROLE_TRANSFERER, utilsContracts[i]);
            revokeRole(ROLE_MODERATOR, utilsContracts[i]);
            revokeRole(ROLE_TAXER, utilsContracts[i]);
        }
        delete utilsContracts;
        
        for(uint i = 0; i < accessSettings.length; i++)
        {
            if (accessSettings[i].isMinter) grantRole(ROLE_MINTER, accessSettings[i].addr);
            if (accessSettings[i].isBurner) grantRole(ROLE_BURNER, accessSettings[i].addr);
            if (accessSettings[i].isTransferer) grantRole(ROLE_TRANSFERER, accessSettings[i].addr);
            if (accessSettings[i].isModerator) grantRole(ROLE_MODERATOR, accessSettings[i].addr);
            if (accessSettings[i].isTaxer) grantRole(ROLE_TAXER, accessSettings[i].addr);
            
            utilsContracts.push(accessSettings[i].addr);
        }
        
        emit UpdatedUtilsContracts(accessSettings);
    }
    
    function getUtilsContractAtPos(uint pos)
        external
        view
        returns (address)
    {
        return utilsContracts[pos];
    }
    
    function getUtilsContractsCount()
        external
        view
        returns(uint)
    {
        return utilsContracts.length;
    }
    
    function mintByBridge(address to, uint desiredAmountToMint) 
        external
        notPausedContract
        onlyRole(ROLE_MINTER)
    {
        _mintHumanAddress(to, desiredAmountToMint);
        emit MintedByBridge(to, desiredAmountToMint);
    }
    
    function mintHumanAddress(address to, uint desiredAmountToMint) 
        external
        notPausedContract
        onlyRole(ROLE_MINTER)
    {
        _mintHumanAddress(to, desiredAmountToMint);
        emit MintHumanAddress(to, desiredAmountToMint);
    }
    
    function _mintHumanAddress(address to, uint desiredAmountToMint) 
        private
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        uint realAmountToMint = 
            iNoBotsTech.
                prepareHumanAddressMintOrBurnRewardsAmounts(
                    true,
                    to,
                    desiredAmountToMint
                );
        
        _RealBalances[to] += realAmountToMint;
        iNoBotsTech.publicForcedUpdateCacheMultiplier();
        
        emit Transfer(address(0), to, desiredAmountToMint);
    }

    function burnByBridge(address from, uint desiredAmountToBurn)
        external
        notPausedContract
        onlyRole(ROLE_BURNER)
    {
        _burnHumanAddress(from, desiredAmountToBurn);
        emit BurnedByBridge(from, desiredAmountToBurn);
    }

    function burnHumanAddress(address from, uint desiredAmountToBurn)
        external
        notPausedContract
        onlyRole(ROLE_BURNER)
    {
        _burnHumanAddress(from, desiredAmountToBurn);
        emit BurnHumanAddress(from, desiredAmountToBurn);
    }

    function _burnHumanAddress(address from, uint desiredAmountToBurn)
        private
    {
        INoBotsTech iNoBotsTech = INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]);
        uint realAmountToBurn = 
            INoBotsTech(utilsContracts[NOBOTS_TECH_CONTRACT_ID]).
                prepareHumanAddressMintOrBurnRewardsAmounts(
                    false,
                    from,
                    desiredAmountToBurn
                );
        
        _RealBalances[from] -= realAmountToBurn;
        iNoBotsTech.publicForcedUpdateCacheMultiplier();
        
        emit Transfer(from, address(0), desiredAmountToBurn);
    }
    
    function getChainId() 
        external 
        view 
        returns (uint) 
    {
        return block.chainid;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnHumanAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnedByBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimedReferralRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintHumanAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MintedByBridge","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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferCustom","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bool","name":"isMinter","type":"bool"},{"internalType":"bool","name":"isBurner","type":"bool"},{"internalType":"bool","name":"isTransferer","type":"bool"},{"internalType":"bool","name":"isModerator","type":"bool"},{"internalType":"bool","name":"isTaxer","type":"bool"},{"internalType":"address","name":"addr","type":"address"}],"indexed":false,"internalType":"struct DefiFactoryToken.AccessSettings[]","name":"accessSettings","type":"tuple[]"}],"name":"UpdatedUtilsContracts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VestedAmountClaimed","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_BURNER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_MINTER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_MODERATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_TAXER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_TRANSFERER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"desiredAmountToBurn","type":"uint256"}],"name":"burnByBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"desiredAmountToBurn","type":"uint256"}],"name":"burnHumanAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"chargeCustomTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrals","type":"address[]"}],"name":"claimReferrerRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"referrals","type":"address[]"}],"name":"filterNonZeroReferrals","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getCachedReferrerRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"address[]","name":"referrals","type":"address[]"}],"name":"getCalculatedReferrerRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","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":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"}],"name":"getTemporaryReferralRealAmountsBulk","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"realBalance","type":"uint256"}],"internalType":"struct TemporaryReferralRealAmountsBulk[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pos","type":"uint256"}],"name":"getUtilsContractAtPos","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUtilsContractsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"desiredAmountToMint","type":"uint256"}],"name":"mintByBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"desiredAmountToMint","type":"uint256"}],"name":"mintHumanAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"moderatorTransferFromWhilePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referrer","type":"address"}],"name":"registerReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resumeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferCustom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFromTeamVestingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"__name","type":"string"},{"internalType":"string","name":"__symbol","type":"string"}],"name":"updateNameAndSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"isMinter","type":"bool"},{"internalType":"bool","name":"isBurner","type":"bool"},{"internalType":"bool","name":"isTransferer","type":"bool"},{"internalType":"bool","name":"isModerator","type":"bool"},{"internalType":"bool","name":"isTaxer","type":"bool"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct DefiFactoryToken.AccessSettings[]","name":"accessSettings","type":"tuple[]"}],"name":"updateUtilsContracts","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b50604051806040016040528060128152602001712232b334902330b1ba37b93c902a37b5b2b760711b81525080604051806040016040528060018152602001603160f81b815250604051806040016040528060128152602001712232b334902330b1ba37b93c902a37b5b2b760711b815250604051806040016040528060048152602001631111519560e21b8152508160049080519060200190620000de9291906200042c565b508051620000f49060059060208401906200042c565b5050825160208085019190912083519184019190912060c082905260e08190524660a0529091507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620001498184846200025f565b60805261010052506200016e935060009250620001689150506200029b565b6200029f565b6200019d7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b601461620001686200029b565b620001cc7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d8620001686200029b565b620001fb7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e524620001686200029b565b6200022a7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c1620001686200029b565b620002597f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d1620001686200029b565b6200053b565b600083838346306040516020016200027c959493929190620004d2565b6040516020818303038152906040528051906020012090509392505050565b3390565b620002b68282620002e260201b6200216a1760201c565b6000828152600160209081526040909120620002dd91839062002178620002f2821b17901c565b505050565b620002ee828262000312565b5050565b600062000309836001600160a01b0384166200039c565b90505b92915050565b6200031e8282620003eb565b620002ee576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003586200029b565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620003aa838362000414565b620003e2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030c565b5060006200030c565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60009081526001919091016020526040902054151590565b8280546200043a90620004fe565b90600052602060002090601f0160209004810192826200045e5760008555620004a9565b82601f106200047957805160ff1916838001178555620004a9565b82800160010185558215620004a9579182015b82811115620004a95782518255916020019190600101906200048c565b50620004b7929150620004bb565b5090565b5b80821115620004b75760008155600101620004bc565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b6002810460018216806200051357607f821691505b602082108114156200053557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516141276200058b6000396000612050015260006128ce01526000612910015260006128ef0152600061287c015260006128a501526141276000f3fe608060405234801561001057600080fd5b50600436106103355760003560e01c806368a2972f116101b25780639cff2eba116100f9578063c4bc5da5116100a2578063d505accf1161007c578063d505accf1461065a578063d547741f1461066d578063dd62ed3e14610680578063eaf9d1941461069357610335565b8063c4bc5da514610637578063ca15c8731461063f578063d391014b1461065257610335565b8063b187bd26116100d3578063b187bd2614610609578063b492da9114610611578063c238651b1461062457610335565b80639cff2eba146105d0578063a457c2d7146105e3578063a9059cbb146105f657610335565b80638cbfeb0c1161015b57806392afc33a1161013557806392afc33a146105b857806395d89b41146105c057806397c1d32f146105c857610335565b80638cbfeb0c1461057f5780639010d07c1461059257806391d14854146105a557610335565b80637ecebe001161018c5780637ecebe001461054457806382e17b65146105575780638493712a1461057757610335565b806368a2972f146104fe57806370a082311461051e578063789210b31461053157610335565b806323b872dd1161028157806336568abe1161022a5780634abd991d116102045780634abd991d146104bd57806354ff02d8146104d05780635aacfa5d146104d857806366830b21146104eb57610335565b806336568abe1461048f57806339509351146104a2578063439766ce146104b557610335565b8063313ce5671161025b578063313ce5671461046a5780633408e4701461047f5780633644e5151461048757610335565b806323b872dd14610431578063248a9ca3146104445780632f2ff15d1461045757610335565b80630bb9ff5d116102e35780631bf73b72116102bd5780631bf73b72146104035780631f2eba241461040b578063209ab7111461041e57610335565b80630bb9ff5d146103d357806318160ddd146103e857806318a8ad87146103f057610335565b806306fb1a071161031457806306fb1a071461038b57806306fdde03146103ab578063095ea7b3146103c057610335565b80622457831461033a57806301ffc9a7146103635780630288f0fb14610383575b600080fd5b61034d6103483660046132c0565b6106a6565b60405161035a91906139e0565b60405180910390f35b6103766103713660046135c3565b61077b565b60405161035a91906139b4565b61034d6107c1565b61039e610399366004613566565b6107e5565b60405161035a91906137bf565b6103b3610823565b60405161035a9190613a67565b6103766103ce366004613313565b6108b6565b6103e66103e1366004613313565b6108d4565b005b61034d61097a565b6103e66103fe366004613313565b610a3d565b61034d610ac8565b6103e6610419366004613313565b610ace565b6103e661042c3660046131b7565b610b59565b61037661043f36600461320b565b610bf7565b61034d610452366004613566565b610cd8565b6103e661046536600461357e565b610ced565b610472610d14565b60405161035a9190613f68565b61034d610d19565b61034d610d1d565b6103e661049d36600461357e565b610d27565b6103766104b0366004613313565b610d49565b6103e6610d98565b61034d6104cb3660046131b7565b610dd9565b61034d610eaa565b6103e66104e636600461333e565b610ece565b6103e66104f9366004613313565b611101565b61051161050c36600461333e565b61118c565b60405161035a919061395c565b61034d61052c3660046131b7565b611265565b6103e661053f36600461341c565b61133c565b61034d6105523660046131b7565b611857565b61056a61056536600461333e565b611878565b60405161035a9190613861565b61034d611949565b6103e661058d366004613313565b61196d565b61039e6105a03660046135a2565b611bfa565b6103766105b336600461357e565b611c12565b61034d611c3b565b6103b3611c5f565b61034d611c6e565b6103e66105de36600461320b565b611c92565b6103766105f1366004613313565b611d46565b610376610604366004613313565b611dc1565b610376611df9565b6103e661061f366004613313565b611e02565b61037661063236600461320b565b611f50565b6103e6611fd3565b61034d61064d366004613566565b612010565b61034d612027565b6103e661066836600461324b565b61202c565b6103e661067b36600461357e565b61210e565b61034d61068e3660046131d3565b612118565b6103e66106a13660046135eb565b612143565b60008060076000815481106106cb57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517e2457830000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190622457839061072290889088908890600401613811565b60206040518083038186803b15801561073a57600080fd5b505afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610772919061369b565b95945050505050565b60006001600160e01b031982167f5a05180f0000000000000000000000000000000000000000000000000000000014806107b957506107b98261218d565b90505b919050565b7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c181565b60006007828154811061080857634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031692915050565b60606004805461083290614060565b80601f016020809104026020016040519081016040528092919081815260200182805461085e90614060565b80156108ab5780601f10610880576101008083540402835291602001916108ab565b820191906000526020600020905b81548152906001019060200180831161088e57829003601f168201915b505050505090505b90565b60006108ca6108c36121cb565b84846121cf565b5060015b92915050565b60085460ff16156109005760405162461bcd60e51b81526004016108f790613d8e565b60405180910390fd5b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b6014616109328161092d6121cb565b612283565b61093c83836122e7565b7f099fc78bcf3c24b8cd6ad4eda1e3eb007e511c09c640af1c46437ded34cf10f2838360405161096d929190613834565b60405180910390a1505050565b6000600760008154811061099e57634e487b7160e01b600052603260045260246000fd5b60009182526020918290200154604080517fc4e41b2200000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169263c4e41b2292600480840193829003018186803b158015610a0057600080fd5b505afa158015610a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a38919061369b565b905090565b60085460ff1615610a605760405162461bcd60e51b81526004016108f790613d8e565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d8610a8d8161092d6121cb565b610a978383612476565b7f0a5b82707bc4ce1d57e909b70adb28e393a34c2ab77e30f862ca2e0e9f8da905838360405161096d929190613834565b60075490565b60085460ff1615610af15760405162461bcd60e51b81526004016108f790613d8e565b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b601461610b1e8161092d6121cb565b610b2883836122e7565b7f7d48429c6eb871d47dea691d65bb2d1f99eaf5d33e7a06363b8fafb3f6ea0178838360405161096d929190613834565b60006007600081548110610b7d57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905080635603b9f9610ba26121cb565b846040518363ffffffff1660e01b8152600401610bc09291906137d3565b600060405180830381600087803b158015610bda57600080fd5b505af1158015610bee573d6000803e3d6000fd5b50505050505b50565b60085460009060ff1615610c1d5760405162461bcd60e51b81526004016108f790613d8e565b6001600160a01b038416610c435760405162461bcd60e51b81526004016108f790613c81565b610c4e84848461262b565b6001600160a01b038416600090815260036020526040812081610c6f6121cb565b6001600160a01b03166001600160a01b0316815260200190815260200160002054905082811015610cb25760405162461bcd60e51b81526004016108f790613dc5565b610ccd85610cbe6121cb565b610cc88685614002565b6121cf565b506001949350505050565b60009081526020819052604090206001015490565b610cf78282612859565b6000828152600160205260409020610d0f9082612178565b505050565b601290565b4690565b6000610a38612878565b610d31828261293b565b6000828152600160205260409020610d0f908261297d565b60006108ca610d566121cb565b848460036000610d646121cb565b6001600160a01b03908116825260208083019390935260409182016000908120918b1681529252902054610cc89190613fcb565b60085460ff1615610dbb5760405162461bcd60e51b81526004016108f790613d8e565b6000610dc98161092d6121cb565b506008805460ff19166001179055565b6000806007600081548110610dfe57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f4abd991d0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190634abd991d90610e539086906004016137bf565b60206040518083038186803b158015610e6b57600080fd5b505afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea3919061369b565b9392505050565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d881565b60085460ff1615610ef15760405162461bcd60e51b81526004016108f790613d8e565b60006007600081548110610f1557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f3830551a0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190633830551a90610f6c908690869060040161384d565b600060405180830381600087803b158015610f8657600080fd5b505af1158015610f9a573d6000803e3d6000fd5b505050506000816001600160a01b0316634abd991d610fb76121cb565b6040518263ffffffff1660e01b8152600401610fd391906137bf565b60206040518083038186803b158015610feb57600080fd5b505afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611023919061369b565b9050600081116110455760405162461bcd60e51b81526004016108f790613b06565b816001600160a01b031663e355681961105c6121cb565b6040518263ffffffff1660e01b815260040161107891906137bf565b600060405180830381600087803b15801561109257600080fd5b505af11580156110a6573d6000803e3d6000fd5b505050506110bb6110b56121cb565b826122e7565b7f5b166da4c6bcfd67577f205ac2ee4ef2ce2e24d51237eafb87f82df73f03f6146110e46121cb565b826040516110f3929190613834565b60405180910390a150505050565b60085460ff16156111245760405162461bcd60e51b81526004016108f790613d8e565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d86111518161092d6121cb565b61115b8383612476565b7f3eac2380fcf2b255bd916ae212498a2e55f3c99baab43d3eb29cb6349639d0d2838360405161096d929190613834565b6060600060076000815481106111b257634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f68a2972f0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116915081906368a2972f90611209908790879060040161384d565b60006040518083038186803b15801561122157600080fd5b505afa158015611235573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261125d919081019061348c565b949350505050565b6000600760008154811061128957634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03858116845260029092526040928390205492517f2b04e840000000000000000000000000000000000000000000000000000000008152911691632b04e840916112ec918691600401613834565b60206040518083038186803b15801561130457600080fd5b505afa158015611318573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b9919061369b565b600061134a8161092d6121cb565b60005b6007548110156114dc576113b67faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b6014616007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031661210e565b6113fb7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d86007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114407f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e5246007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114857f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c16007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114ca7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d16007838154811061139c57634e487b7160e01b600052603260045260246000fd5b806114d481614095565b91505061134d565b506114e96007600061305c565b60005b828110156118255783838281811061151457634e487b7160e01b600052603260045260246000fd5b61152a92602060c090920201908101915061354c565b1561158b5761158b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b60146185858481811061157357634e487b7160e01b600052603260045260246000fd5b905060c0020160a001602081019061046591906131b7565b8383828181106115ab57634e487b7160e01b600052603260045260246000fd5b905060c0020160200160208101906115c3919061354c565b1561160c5761160c7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d885858481811061157357634e487b7160e01b600052603260045260246000fd5b83838281811061162c57634e487b7160e01b600052603260045260246000fd5b905060c002016040016020810190611644919061354c565b1561168d5761168d7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e52485858481811061157357634e487b7160e01b600052603260045260246000fd5b8383828181106116ad57634e487b7160e01b600052603260045260246000fd5b905060c0020160600160208101906116c5919061354c565b1561170e5761170e7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c185858481811061157357634e487b7160e01b600052603260045260246000fd5b83838281811061172e57634e487b7160e01b600052603260045260246000fd5b905060c002016080016020810190611746919061354c565b1561178f5761178f7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d185858481811061157357634e487b7160e01b600052603260045260246000fd5b60078484838181106117b157634e487b7160e01b600052603260045260246000fd5b905060c0020160a00160208101906117c991906131b7565b81546001810183556000928352602090922090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039092169190911790558061181d81614095565b9150506114ec565b507f13340c8e795b6b33898709afdee63a73df74c7ca9d8204d3265aa483ac0e4037838360405161096d9291906138ae565b6001600160a01b03811660009081526006602052604081206107b990612992565b60606000600760008154811061189e57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f82e17b650000000000000000000000000000000000000000000000000000000081526001600160a01b03909116915081906382e17b65906118f5908790879060040161384d565b60006040518083038186803b15801561190d57600080fd5b505afa158015611921573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261125d919081019061337e565b7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e52481565b60085460ff16156119905760405162461bcd60e51b81526004016108f790613d8e565b600060076001815481106119b457634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031690506119d36121cb565b6001600160a01b0316816001600160a01b031614611a035760405162461bcd60e51b81526004016108f790613bd1565b60006007600081548110611a2757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038581168452600290925260408320805492909116935085929091611a62908490614002565b90915550506040517fcb1236370000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063cb12363790611aac9086906004016139e0565b60206040518083038186803b158015611ac457600080fd5b505afa158015611ad8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611afc919061369b565b6001600160a01b03851660009081526002602052604081208054909190611b24908490613fcb565b92505081905550806001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051611bc191906139e0565b60405180910390a37f814f4cde641f205fbac4d156545ee0a5850d9338c94b952acec9852c0a52804384846040516110f3929190613834565b6000828152600160205260408120610ea39083612996565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b60146181565b60606005805461083290614060565b7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d181565b60085460ff1615611cb55760405162461bcd60e51b81526004016108f790613d8e565b7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e524611ce28161092d6121cb565b6001600160a01b038416611d085760405162461bcd60e51b81526004016108f790613c81565b611d1384848461262b565b7f4f21c37c3184c9b0bbc63a812b0a1a148f15f1bd6db127e7e562d9b0436803258484846040516110f3939291906137ed565b60008060036000611d556121cb565b6001600160a01b0390811682526020808301939093526040918201600090812091881681529252902054905082811015611da15760405162461bcd60e51b81526004016108f790613e59565b611db7611dac6121cb565b85610cc88685614002565b5060019392505050565b60085460009060ff1615611de75760405162461bcd60e51b81526004016108f790613d8e565b6108ca611df26121cb565b848461262b565b60085460ff1681565b60085460ff1615611e255760405162461bcd60e51b81526004016108f790613d8e565b7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d1611e528161092d6121cb565b60006007600081548110611e7657634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03878116845260029092526040928390205492517f36098758000000000000000000000000000000000000000000000000000000008152911692508291633609875891611edc918791600401613f5a565b602060405180830381600087803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2e919061369b565b6001600160a01b03909416600090815260026020526040902093909355505050565b60085460009060ff16611f755760405162461bcd60e51b81526004016108f790613b9a565b7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c1611fa28161092d6121cb565b6001600160a01b038516611fc85760405162461bcd60e51b81526004016108f790613c81565b610ccd85858561262b565b60085460ff16611ff55760405162461bcd60e51b81526004016108f790613b9a565b60006120038161092d6121cb565b506008805460ff19169055565b60008181526001602052604081206107b9906129a2565b600081565b8342111561204c5760405162461bcd60e51b81526004016108f790613c08565b60007f000000000000000000000000000000000000000000000000000000000000000088888861207b8c6129ad565b89604051602001612091969594939291906139e9565b60405160208183030381529060405280519060200120905060006120b4826129df565b905060006120c4828787876129f2565b9050896001600160a01b0316816001600160a01b0316146120f75760405162461bcd60e51b81526004016108f790613cfa565b6121028a8a8a6121cf565b50505050505050505050565b610d318282612adf565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60006121518161092d6121cb565b61215d6004868661307a565b50610bee6005848461307a565b6121748282612afe565b5050565b6000610ea3836001600160a01b038416612b83565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806107b957506107b982612bcd565b3390565b6001600160a01b0383166121f55760405162461bcd60e51b81526004016108f790613d31565b6001600160a01b03821661221b5760405162461bcd60e51b81526004016108f790613b3d565b6001600160a01b0380841660008181526003602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906122769085906139e0565b60405180910390a3505050565b61228d8282611c12565b612174576122a5816001600160a01b03166014612bff565b6122b0836020612bff565b6040516020016122c192919061373e565b60408051601f198184030181529082905262461bcd60e51b82526108f791600401613a67565b6000600760008154811061230b57634e487b7160e01b600052603260045260246000fd5b60009182526020822001546040516342e58a6360e01b81526001600160a01b03909116925082906342e58a639061234b90600190889088906004016139bf565b602060405180830381600087803b15801561236557600080fd5b505af1158015612379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239d919061369b565b6001600160a01b0385166000908152600260205260408120805492935083929091906123ca908490613fcb565b92505081905550816001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561240c57600080fd5b505af1158015612420573d6000803e3d6000fd5b50505050836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161246891906139e0565b60405180910390a350505050565b6000600760008154811061249a57634e487b7160e01b600052603260045260246000fd5b6000918252602082200154600780546001600160a01b0390921693509082906124d357634e487b7160e01b600052603260045260246000fd5b60009182526020822001546040516342e58a6360e01b81526001600160a01b03909116916342e58a639161250e9190889088906004016139bf565b602060405180830381600087803b15801561252857600080fd5b505af115801561253c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612560919061369b565b6001600160a01b03851660009081526002602052604081208054929350839290919061258d908490614002565b92505081905550816001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156125cf57600080fd5b505af11580156125e3573d6000803e3d6000fd5b5050505060006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161246891906139e0565b6001600160a01b0382166126515760405162461bcd60e51b81526004016108f790613c81565b816001600160a01b0316836001600160a01b031614156126835760405162461bcd60e51b81526004016108f790613e22565b600060076000815481106126a757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546040805160a0810182526001600160a01b038981168083528982168387018190528385018a9052908752600280875284882054606085015290875290945281852054608082015290517f815a61e0000000000000000000000000000000000000000000000000000000008152929091169350839163815a61e09161273b91600401613f13565b608060405180830381600087803b15801561275557600080fd5b505af1158015612769573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278d9190613654565b80516001600160a01b03808816600081815260026020908152604080832095909555850151928916808252908490209290925560608401519251939450909290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef916127fa91906139e0565b60405180910390a360006001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040015160405161284a91906139e0565b60405180910390a35050505050565b61286282610cd8565b61286e8161092d6121cb565b610d0f8383612afe565b60007f00000000000000000000000000000000000000000000000000000000000000004614156128c957507f00000000000000000000000000000000000000000000000000000000000000006108b3565b6129347f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612df6565b90506108b3565b6129436121cb565b6001600160a01b0316816001600160a01b0316146129735760405162461bcd60e51b81526004016108f790613eb6565b6121748282612e30565b6000610ea3836001600160a01b038416612eb3565b5490565b6000610ea38383612fd0565b60006107b982612992565b6001600160a01b03811660009081526006602052604081206129ce81612992565b91506129d981613008565b50919050565b60006107b96129ec612878565b83613011565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612a345760405162461bcd60e51b81526004016108f790613c3f565b8360ff16601b1480612a4957508360ff16601c145b612a655760405162461bcd60e51b81526004016108f790613cb8565b600060018686868660405160008152602001604052604051612a8a9493929190613a49565b6020604051602081039080840390855afa158015612aac573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166107725760405162461bcd60e51b81526004016108f790613a9a565b612ae882610cd8565b612af48161092d6121cb565b610d0f8383612e30565b612b088282611c12565b612174576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612b3f6121cb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000612b8f8383613044565b612bc5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ce565b5060006108ce565b6001600160e01b031981167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b60606000612c0e836002613fe3565b612c19906002613fcb565b67ffffffffffffffff811115612c3f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612c69576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612cae57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612d0757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000612d2b846002613fe3565b612d36906001613fcb565b90505b6001811115612dd7577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110612d8557634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110612da957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612dd081614049565b9050612d39565b508315610ea35760405162461bcd60e51b81526004016108f790613ad1565b60008383834630604051602001612e11959493929190613a1d565b6040516020818303038152906040528051906020012090509392505050565b612e3a8282611c12565b15612174576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055612e6f6121cb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008181526001830160205260408120548015612fc6576000612ed7600183614002565b8554909150600090612eeb90600190614002565b9050818114612f6c576000866000018281548110612f1957634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110612f4a57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f8b57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ce565b60009150506108ce565b6000826000018281548110612ff557634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b80546001019055565b60008282604051602001613026929190613708565b60405160208183030381529060405280519060200120905092915050565b60009081526001919091016020526040902054151590565b5080546000825590600052602060002090810190610bf491906130fe565b82805461308690614060565b90600052602060002090601f0160209004810192826130a857600085556130ee565b82601f106130c15782800160ff198235161785556130ee565b828001600101855582156130ee579182015b828111156130ee5782358255916020019190600101906130d3565b506130fa9291506130fe565b5090565b5b808211156130fa57600081556001016130ff565b80356107bc816140dc565b60008083601f84011261312f578182fd5b50813567ffffffffffffffff811115613146578182fd5b602083019150836020808302850101111561316057600080fd5b9250929050565b803580151581146107bc57600080fd5b60008083601f840112613188578182fd5b50813567ffffffffffffffff81111561319f578182fd5b60208301915083602082850101111561316057600080fd5b6000602082840312156131c8578081fd5b8135610ea3816140dc565b600080604083850312156131e5578081fd5b82356131f0816140dc565b91506020830135613200816140dc565b809150509250929050565b60008060006060848603121561321f578081fd5b833561322a816140dc565b9250602084013561323a816140dc565b929592945050506040919091013590565b600080600080600080600060e0888a031215613265578283fd5b8735613270816140dc565b96506020880135613280816140dc565b95506040880135945060608801359350608088013560ff811681146132a3578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806000604084860312156132d4578283fd5b83356132df816140dc565b9250602084013567ffffffffffffffff8111156132fa578283fd5b6133068682870161311e565b9497909650939450505050565b60008060408385031215613325578182fd5b8235613330816140dc565b946020939093013593505050565b60008060208385031215613350578182fd5b823567ffffffffffffffff811115613366578283fd5b6133728582860161311e565b90969095509350505050565b60006020808385031215613390578182fd5b825167ffffffffffffffff8111156133a6578283fd5b8301601f810185136133b6578283fd5b80516133c96133c482613fa7565b613f76565b81815283810190838501858402850186018910156133e5578687fd5b8694505b838510156134105780516133fc816140dc565b8352600194909401939185019185016133e9565b50979650505050505050565b6000806020838503121561342e578182fd5b823567ffffffffffffffff80821115613445578384fd5b818501915085601f830112613458578384fd5b813581811115613466578485fd5b86602060c08302850101111561347a578485fd5b60209290920196919550909350505050565b6000602080838503121561349e578182fd5b825167ffffffffffffffff8111156134b4578283fd5b8301601f810185136134c4578283fd5b80516134d26133c482613fa7565b818152838101908385016040808502860187018a10156134f0578788fd5b8795505b8486101561353e5780828b03121561350a578788fd5b61351381613f76565b825161351e816140dc565b8152828801518882015284526001959095019492860192908101906134f4565b509098975050505050505050565b60006020828403121561355d578081fd5b610ea382613167565b600060208284031215613577578081fd5b5035919050565b60008060408385031215613590578182fd5b823591506020830135613200816140dc565b600080604083850312156135b4578182fd5b50508035926020909101359150565b6000602082840312156135d4578081fd5b81356001600160e01b031981168114610ea3578182fd5b60008060008060408587031215613600578182fd5b843567ffffffffffffffff80821115613617578384fd5b61362388838901613177565b9096509450602087013591508082111561363b578384fd5b5061364887828801613177565b95989497509550505050565b600060808284031215613665578081fd5b61366f6080613f76565b825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156136ac578081fd5b5051919050565b6001600160a01b03169052565b60008284526020808501945082825b858110156136fd5781356136e2816140dc565b6001600160a01b0316875295820195908201906001016136cf565b509495945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351613776816017850160208801614019565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516137b3816028840160208801614019565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006001600160a01b0385168252604060208301526107726040830184866136c0565b6001600160a01b03929092168252602082015260400190565b60006020825261125d6020830184866136c0565b6020808252825182820181905260009190848201906040850190845b818110156138a25783516001600160a01b03168352928401929184019160010161387d565b50909695505050505050565b6020808252818101839052600090604080840186845b8781101561394f576138d582613167565b151583526138e4858301613167565b1515858401526138f5848301613167565b1515848401526060613908818401613167565b151590840152608061391b838201613167565b15159084015260a061392e838201613113565b61393a828601826136b3565b505060c09283019291909101906001016138c4565b5090979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156139a757815180516001600160a01b03168552860151868501529284019290850190600101613979565b5091979650505050505050565b901515815260200190565b92151583526001600160a01b03919091166020830152604082015260600190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152613a86816040850160208701614019565b601f01601f19169190910160400192915050565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b6020808252600e908201527f444546543a202172657761726473000000000000000000000000000000000000604082015260600190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600d908201527f444546543a202170617573656400000000000000000000000000000000000000604082015260600190565b60208082526017908201527f444546543a202156455354494e475f434f4e5452414354000000000000000000604082015260600190565b6020808252601d908201527f45524332305065726d69743a206578706972656420646561646c696e65000000604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b6020808252600b908201527f444546543a20216275726e000000000000000000000000000000000000000000604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252601e908201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604082015260600190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600c908201527f444546543a207061757365640000000000000000000000000000000000000000604082015260600190565b60208082526027908201527f444546543a207472616e7366657220616d6f756e74206578636565647320616c60408201527f6c6f77616e636500000000000000000000000000000000000000000000000000606082015260800190565b6020808252600b908201527f444546543a202173656c66000000000000000000000000000000000000000000604082015260600190565b60208082526025908201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760408201527f207a65726f000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201527f20726f6c657320666f722073656c660000000000000000000000000000000000606082015260800190565b600060a0820190506001600160a01b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151608083015292915050565b918252602082015260400190565b60ff91909116815260200190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f9f57613f9f6140c6565b604052919050565b600067ffffffffffffffff821115613fc157613fc16140c6565b5060209081020190565b60008219821115613fde57613fde6140b0565b500190565b6000816000190483118215151615613ffd57613ffd6140b0565b500290565b600082821015614014576140146140b0565b500390565b60005b8381101561403457818101518382015260200161401c565b83811115614043576000848401525b50505050565b600081614058576140586140b0565b506000190190565b60028104600182168061407457607f821691505b602082108114156129d957634e487b7160e01b600052602260045260246000fd5b60006000198214156140a9576140a96140b0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610bf457600080fdfea2646970667358221220696d4922b0b23ae3f3f6f9c632fa2af5c4ec3041a14cdc576fb1e77a016f5cf764736f6c63430008010033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103355760003560e01c806368a2972f116101b25780639cff2eba116100f9578063c4bc5da5116100a2578063d505accf1161007c578063d505accf1461065a578063d547741f1461066d578063dd62ed3e14610680578063eaf9d1941461069357610335565b8063c4bc5da514610637578063ca15c8731461063f578063d391014b1461065257610335565b8063b187bd26116100d3578063b187bd2614610609578063b492da9114610611578063c238651b1461062457610335565b80639cff2eba146105d0578063a457c2d7146105e3578063a9059cbb146105f657610335565b80638cbfeb0c1161015b57806392afc33a1161013557806392afc33a146105b857806395d89b41146105c057806397c1d32f146105c857610335565b80638cbfeb0c1461057f5780639010d07c1461059257806391d14854146105a557610335565b80637ecebe001161018c5780637ecebe001461054457806382e17b65146105575780638493712a1461057757610335565b806368a2972f146104fe57806370a082311461051e578063789210b31461053157610335565b806323b872dd1161028157806336568abe1161022a5780634abd991d116102045780634abd991d146104bd57806354ff02d8146104d05780635aacfa5d146104d857806366830b21146104eb57610335565b806336568abe1461048f57806339509351146104a2578063439766ce146104b557610335565b8063313ce5671161025b578063313ce5671461046a5780633408e4701461047f5780633644e5151461048757610335565b806323b872dd14610431578063248a9ca3146104445780632f2ff15d1461045757610335565b80630bb9ff5d116102e35780631bf73b72116102bd5780631bf73b72146104035780631f2eba241461040b578063209ab7111461041e57610335565b80630bb9ff5d146103d357806318160ddd146103e857806318a8ad87146103f057610335565b806306fb1a071161031457806306fb1a071461038b57806306fdde03146103ab578063095ea7b3146103c057610335565b80622457831461033a57806301ffc9a7146103635780630288f0fb14610383575b600080fd5b61034d6103483660046132c0565b6106a6565b60405161035a91906139e0565b60405180910390f35b6103766103713660046135c3565b61077b565b60405161035a91906139b4565b61034d6107c1565b61039e610399366004613566565b6107e5565b60405161035a91906137bf565b6103b3610823565b60405161035a9190613a67565b6103766103ce366004613313565b6108b6565b6103e66103e1366004613313565b6108d4565b005b61034d61097a565b6103e66103fe366004613313565b610a3d565b61034d610ac8565b6103e6610419366004613313565b610ace565b6103e661042c3660046131b7565b610b59565b61037661043f36600461320b565b610bf7565b61034d610452366004613566565b610cd8565b6103e661046536600461357e565b610ced565b610472610d14565b60405161035a9190613f68565b61034d610d19565b61034d610d1d565b6103e661049d36600461357e565b610d27565b6103766104b0366004613313565b610d49565b6103e6610d98565b61034d6104cb3660046131b7565b610dd9565b61034d610eaa565b6103e66104e636600461333e565b610ece565b6103e66104f9366004613313565b611101565b61051161050c36600461333e565b61118c565b60405161035a919061395c565b61034d61052c3660046131b7565b611265565b6103e661053f36600461341c565b61133c565b61034d6105523660046131b7565b611857565b61056a61056536600461333e565b611878565b60405161035a9190613861565b61034d611949565b6103e661058d366004613313565b61196d565b61039e6105a03660046135a2565b611bfa565b6103766105b336600461357e565b611c12565b61034d611c3b565b6103b3611c5f565b61034d611c6e565b6103e66105de36600461320b565b611c92565b6103766105f1366004613313565b611d46565b610376610604366004613313565b611dc1565b610376611df9565b6103e661061f366004613313565b611e02565b61037661063236600461320b565b611f50565b6103e6611fd3565b61034d61064d366004613566565b612010565b61034d612027565b6103e661066836600461324b565b61202c565b6103e661067b36600461357e565b61210e565b61034d61068e3660046131d3565b612118565b6103e66106a13660046135eb565b612143565b60008060076000815481106106cb57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517e2457830000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190622457839061072290889088908890600401613811565b60206040518083038186803b15801561073a57600080fd5b505afa15801561074e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610772919061369b565b95945050505050565b60006001600160e01b031982167f5a05180f0000000000000000000000000000000000000000000000000000000014806107b957506107b98261218d565b90505b919050565b7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c181565b60006007828154811061080857634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031692915050565b60606004805461083290614060565b80601f016020809104026020016040519081016040528092919081815260200182805461085e90614060565b80156108ab5780601f10610880576101008083540402835291602001916108ab565b820191906000526020600020905b81548152906001019060200180831161088e57829003601f168201915b505050505090505b90565b60006108ca6108c36121cb565b84846121cf565b5060015b92915050565b60085460ff16156109005760405162461bcd60e51b81526004016108f790613d8e565b60405180910390fd5b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b6014616109328161092d6121cb565b612283565b61093c83836122e7565b7f099fc78bcf3c24b8cd6ad4eda1e3eb007e511c09c640af1c46437ded34cf10f2838360405161096d929190613834565b60405180910390a1505050565b6000600760008154811061099e57634e487b7160e01b600052603260045260246000fd5b60009182526020918290200154604080517fc4e41b2200000000000000000000000000000000000000000000000000000000815290516001600160a01b039092169263c4e41b2292600480840193829003018186803b158015610a0057600080fd5b505afa158015610a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a38919061369b565b905090565b60085460ff1615610a605760405162461bcd60e51b81526004016108f790613d8e565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d8610a8d8161092d6121cb565b610a978383612476565b7f0a5b82707bc4ce1d57e909b70adb28e393a34c2ab77e30f862ca2e0e9f8da905838360405161096d929190613834565b60075490565b60085460ff1615610af15760405162461bcd60e51b81526004016108f790613d8e565b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b601461610b1e8161092d6121cb565b610b2883836122e7565b7f7d48429c6eb871d47dea691d65bb2d1f99eaf5d33e7a06363b8fafb3f6ea0178838360405161096d929190613834565b60006007600081548110610b7d57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905080635603b9f9610ba26121cb565b846040518363ffffffff1660e01b8152600401610bc09291906137d3565b600060405180830381600087803b158015610bda57600080fd5b505af1158015610bee573d6000803e3d6000fd5b50505050505b50565b60085460009060ff1615610c1d5760405162461bcd60e51b81526004016108f790613d8e565b6001600160a01b038416610c435760405162461bcd60e51b81526004016108f790613c81565b610c4e84848461262b565b6001600160a01b038416600090815260036020526040812081610c6f6121cb565b6001600160a01b03166001600160a01b0316815260200190815260200160002054905082811015610cb25760405162461bcd60e51b81526004016108f790613dc5565b610ccd85610cbe6121cb565b610cc88685614002565b6121cf565b506001949350505050565b60009081526020819052604090206001015490565b610cf78282612859565b6000828152600160205260409020610d0f9082612178565b505050565b601290565b4690565b6000610a38612878565b610d31828261293b565b6000828152600160205260409020610d0f908261297d565b60006108ca610d566121cb565b848460036000610d646121cb565b6001600160a01b03908116825260208083019390935260409182016000908120918b1681529252902054610cc89190613fcb565b60085460ff1615610dbb5760405162461bcd60e51b81526004016108f790613d8e565b6000610dc98161092d6121cb565b506008805460ff19166001179055565b6000806007600081548110610dfe57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f4abd991d0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190634abd991d90610e539086906004016137bf565b60206040518083038186803b158015610e6b57600080fd5b505afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea3919061369b565b9392505050565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d881565b60085460ff1615610ef15760405162461bcd60e51b81526004016108f790613d8e565b60006007600081548110610f1557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f3830551a0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911691508190633830551a90610f6c908690869060040161384d565b600060405180830381600087803b158015610f8657600080fd5b505af1158015610f9a573d6000803e3d6000fd5b505050506000816001600160a01b0316634abd991d610fb76121cb565b6040518263ffffffff1660e01b8152600401610fd391906137bf565b60206040518083038186803b158015610feb57600080fd5b505afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611023919061369b565b9050600081116110455760405162461bcd60e51b81526004016108f790613b06565b816001600160a01b031663e355681961105c6121cb565b6040518263ffffffff1660e01b815260040161107891906137bf565b600060405180830381600087803b15801561109257600080fd5b505af11580156110a6573d6000803e3d6000fd5b505050506110bb6110b56121cb565b826122e7565b7f5b166da4c6bcfd67577f205ac2ee4ef2ce2e24d51237eafb87f82df73f03f6146110e46121cb565b826040516110f3929190613834565b60405180910390a150505050565b60085460ff16156111245760405162461bcd60e51b81526004016108f790613d8e565b7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d86111518161092d6121cb565b61115b8383612476565b7f3eac2380fcf2b255bd916ae212498a2e55f3c99baab43d3eb29cb6349639d0d2838360405161096d929190613834565b6060600060076000815481106111b257634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f68a2972f0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116915081906368a2972f90611209908790879060040161384d565b60006040518083038186803b15801561122157600080fd5b505afa158015611235573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261125d919081019061348c565b949350505050565b6000600760008154811061128957634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03858116845260029092526040928390205492517f2b04e840000000000000000000000000000000000000000000000000000000008152911691632b04e840916112ec918691600401613834565b60206040518083038186803b15801561130457600080fd5b505afa158015611318573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b9919061369b565b600061134a8161092d6121cb565b60005b6007548110156114dc576113b67faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b6014616007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031661210e565b6113fb7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d86007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114407f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e5246007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114857f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c16007838154811061139c57634e487b7160e01b600052603260045260246000fd5b6114ca7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d16007838154811061139c57634e487b7160e01b600052603260045260246000fd5b806114d481614095565b91505061134d565b506114e96007600061305c565b60005b828110156118255783838281811061151457634e487b7160e01b600052603260045260246000fd5b61152a92602060c090920201908101915061354c565b1561158b5761158b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b60146185858481811061157357634e487b7160e01b600052603260045260246000fd5b905060c0020160a001602081019061046591906131b7565b8383828181106115ab57634e487b7160e01b600052603260045260246000fd5b905060c0020160200160208101906115c3919061354c565b1561160c5761160c7fb5b5a86cc252b1b75a439c6ff372933ceb0690188924e6461150adeb00ab80d885858481811061157357634e487b7160e01b600052603260045260246000fd5b83838281811061162c57634e487b7160e01b600052603260045260246000fd5b905060c002016040016020810190611644919061354c565b1561168d5761168d7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e52485858481811061157357634e487b7160e01b600052603260045260246000fd5b8383828181106116ad57634e487b7160e01b600052603260045260246000fd5b905060c0020160600160208101906116c5919061354c565b1561170e5761170e7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c185858481811061157357634e487b7160e01b600052603260045260246000fd5b83838281811061172e57634e487b7160e01b600052603260045260246000fd5b905060c002016080016020810190611746919061354c565b1561178f5761178f7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d185858481811061157357634e487b7160e01b600052603260045260246000fd5b60078484838181106117b157634e487b7160e01b600052603260045260246000fd5b905060c0020160a00160208101906117c991906131b7565b81546001810183556000928352602090922090910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039092169190911790558061181d81614095565b9150506114ec565b507f13340c8e795b6b33898709afdee63a73df74c7ca9d8204d3265aa483ac0e4037838360405161096d9291906138ae565b6001600160a01b03811660009081526006602052604081206107b990612992565b60606000600760008154811061189e57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546040517f82e17b650000000000000000000000000000000000000000000000000000000081526001600160a01b03909116915081906382e17b65906118f5908790879060040161384d565b60006040518083038186803b15801561190d57600080fd5b505afa158015611921573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261125d919081019061337e565b7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e52481565b60085460ff16156119905760405162461bcd60e51b81526004016108f790613d8e565b600060076001815481106119b457634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031690506119d36121cb565b6001600160a01b0316816001600160a01b031614611a035760405162461bcd60e51b81526004016108f790613bd1565b60006007600081548110611a2757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038581168452600290925260408320805492909116935085929091611a62908490614002565b90915550506040517fcb1236370000000000000000000000000000000000000000000000000000000081526001600160a01b0382169063cb12363790611aac9086906004016139e0565b60206040518083038186803b158015611ac457600080fd5b505afa158015611ad8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611afc919061369b565b6001600160a01b03851660009081526002602052604081208054909190611b24908490613fcb565b92505081905550806001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b6657600080fd5b505af1158015611b7a573d6000803e3d6000fd5b50505050836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051611bc191906139e0565b60405180910390a37f814f4cde641f205fbac4d156545ee0a5850d9338c94b952acec9852c0a52804384846040516110f3929190613834565b6000828152600160205260408120610ea39083612996565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b7faeaef46186eb59f884e36929b6d682a6ae35e1e43d8f05f058dcefb92b60146181565b60606005805461083290614060565b7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d181565b60085460ff1615611cb55760405162461bcd60e51b81526004016108f790613d8e565b7f02a8464c3e212c8f1064432774c6cc3e76f14bd7ccdafd9a1d1cf9b43b51e524611ce28161092d6121cb565b6001600160a01b038416611d085760405162461bcd60e51b81526004016108f790613c81565b611d1384848461262b565b7f4f21c37c3184c9b0bbc63a812b0a1a148f15f1bd6db127e7e562d9b0436803258484846040516110f3939291906137ed565b60008060036000611d556121cb565b6001600160a01b0390811682526020808301939093526040918201600090812091881681529252902054905082811015611da15760405162461bcd60e51b81526004016108f790613e59565b611db7611dac6121cb565b85610cc88685614002565b5060019392505050565b60085460009060ff1615611de75760405162461bcd60e51b81526004016108f790613d8e565b6108ca611df26121cb565b848461262b565b60085460ff1681565b60085460ff1615611e255760405162461bcd60e51b81526004016108f790613d8e565b7f5772712b2943d95a931c0b3a7ddf59cba41b664500d9b93626000a17809f04d1611e528161092d6121cb565b60006007600081548110611e7657634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03878116845260029092526040928390205492517f36098758000000000000000000000000000000000000000000000000000000008152911692508291633609875891611edc918791600401613f5a565b602060405180830381600087803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2e919061369b565b6001600160a01b03909416600090815260026020526040902093909355505050565b60085460009060ff16611f755760405162461bcd60e51b81526004016108f790613b9a565b7f233299fc8224c0cb5b2b8b651b93354cf11d5245f1374bb37773608ffa1913c1611fa28161092d6121cb565b6001600160a01b038516611fc85760405162461bcd60e51b81526004016108f790613c81565b610ccd85858561262b565b60085460ff16611ff55760405162461bcd60e51b81526004016108f790613b9a565b60006120038161092d6121cb565b506008805460ff19169055565b60008181526001602052604081206107b9906129a2565b600081565b8342111561204c5760405162461bcd60e51b81526004016108f790613c08565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861207b8c6129ad565b89604051602001612091969594939291906139e9565b60405160208183030381529060405280519060200120905060006120b4826129df565b905060006120c4828787876129f2565b9050896001600160a01b0316816001600160a01b0316146120f75760405162461bcd60e51b81526004016108f790613cfa565b6121028a8a8a6121cf565b50505050505050505050565b610d318282612adf565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60006121518161092d6121cb565b61215d6004868661307a565b50610bee6005848461307a565b6121748282612afe565b5050565b6000610ea3836001600160a01b038416612b83565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806107b957506107b982612bcd565b3390565b6001600160a01b0383166121f55760405162461bcd60e51b81526004016108f790613d31565b6001600160a01b03821661221b5760405162461bcd60e51b81526004016108f790613b3d565b6001600160a01b0380841660008181526003602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906122769085906139e0565b60405180910390a3505050565b61228d8282611c12565b612174576122a5816001600160a01b03166014612bff565b6122b0836020612bff565b6040516020016122c192919061373e565b60408051601f198184030181529082905262461bcd60e51b82526108f791600401613a67565b6000600760008154811061230b57634e487b7160e01b600052603260045260246000fd5b60009182526020822001546040516342e58a6360e01b81526001600160a01b03909116925082906342e58a639061234b90600190889088906004016139bf565b602060405180830381600087803b15801561236557600080fd5b505af1158015612379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239d919061369b565b6001600160a01b0385166000908152600260205260408120805492935083929091906123ca908490613fcb565b92505081905550816001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561240c57600080fd5b505af1158015612420573d6000803e3d6000fd5b50505050836001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161246891906139e0565b60405180910390a350505050565b6000600760008154811061249a57634e487b7160e01b600052603260045260246000fd5b6000918252602082200154600780546001600160a01b0390921693509082906124d357634e487b7160e01b600052603260045260246000fd5b60009182526020822001546040516342e58a6360e01b81526001600160a01b03909116916342e58a639161250e9190889088906004016139bf565b602060405180830381600087803b15801561252857600080fd5b505af115801561253c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612560919061369b565b6001600160a01b03851660009081526002602052604081208054929350839290919061258d908490614002565b92505081905550816001600160a01b031663e8ac6e4e6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156125cf57600080fd5b505af11580156125e3573d6000803e3d6000fd5b5050505060006001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161246891906139e0565b6001600160a01b0382166126515760405162461bcd60e51b81526004016108f790613c81565b816001600160a01b0316836001600160a01b031614156126835760405162461bcd60e51b81526004016108f790613e22565b600060076000815481106126a757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546040805160a0810182526001600160a01b038981168083528982168387018190528385018a9052908752600280875284882054606085015290875290945281852054608082015290517f815a61e0000000000000000000000000000000000000000000000000000000008152929091169350839163815a61e09161273b91600401613f13565b608060405180830381600087803b15801561275557600080fd5b505af1158015612769573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278d9190613654565b80516001600160a01b03808816600081815260026020908152604080832095909555850151928916808252908490209290925560608401519251939450909290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef916127fa91906139e0565b60405180910390a360006001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040015160405161284a91906139e0565b60405180910390a35050505050565b61286282610cd8565b61286e8161092d6121cb565b610d0f8383612afe565b60007f00000000000000000000000000000000000000000000000000000000000000014614156128c957507f96ded2f296fa7485a7df8bca43276511bf4a974a2b67c64c51720c159ba148426108b3565b6129347f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f9b7555cee7d8d1f28094435c4a9470c9eaf720c49e00f1a5b09c1e4e4d9438507fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6612df6565b90506108b3565b6129436121cb565b6001600160a01b0316816001600160a01b0316146129735760405162461bcd60e51b81526004016108f790613eb6565b6121748282612e30565b6000610ea3836001600160a01b038416612eb3565b5490565b6000610ea38383612fd0565b60006107b982612992565b6001600160a01b03811660009081526006602052604081206129ce81612992565b91506129d981613008565b50919050565b60006107b96129ec612878565b83613011565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115612a345760405162461bcd60e51b81526004016108f790613c3f565b8360ff16601b1480612a4957508360ff16601c145b612a655760405162461bcd60e51b81526004016108f790613cb8565b600060018686868660405160008152602001604052604051612a8a9493929190613a49565b6020604051602081039080840390855afa158015612aac573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166107725760405162461bcd60e51b81526004016108f790613a9a565b612ae882610cd8565b612af48161092d6121cb565b610d0f8383612e30565b612b088282611c12565b612174576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612b3f6121cb565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000612b8f8383613044565b612bc5575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ce565b5060006108ce565b6001600160e01b031981167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b60606000612c0e836002613fe3565b612c19906002613fcb565b67ffffffffffffffff811115612c3f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612c69576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612cae57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612d0757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000612d2b846002613fe3565b612d36906001613fcb565b90505b6001811115612dd7577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110612d8557634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110612da957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612dd081614049565b9050612d39565b508315610ea35760405162461bcd60e51b81526004016108f790613ad1565b60008383834630604051602001612e11959493929190613a1d565b6040516020818303038152906040528051906020012090509392505050565b612e3a8282611c12565b15612174576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055612e6f6121cb565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008181526001830160205260408120548015612fc6576000612ed7600183614002565b8554909150600090612eeb90600190614002565b9050818114612f6c576000866000018281548110612f1957634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110612f4a57634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f8b57634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ce565b60009150506108ce565b6000826000018281548110612ff557634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b80546001019055565b60008282604051602001613026929190613708565b60405160208183030381529060405280519060200120905092915050565b60009081526001919091016020526040902054151590565b5080546000825590600052602060002090810190610bf491906130fe565b82805461308690614060565b90600052602060002090601f0160209004810192826130a857600085556130ee565b82601f106130c15782800160ff198235161785556130ee565b828001600101855582156130ee579182015b828111156130ee5782358255916020019190600101906130d3565b506130fa9291506130fe565b5090565b5b808211156130fa57600081556001016130ff565b80356107bc816140dc565b60008083601f84011261312f578182fd5b50813567ffffffffffffffff811115613146578182fd5b602083019150836020808302850101111561316057600080fd5b9250929050565b803580151581146107bc57600080fd5b60008083601f840112613188578182fd5b50813567ffffffffffffffff81111561319f578182fd5b60208301915083602082850101111561316057600080fd5b6000602082840312156131c8578081fd5b8135610ea3816140dc565b600080604083850312156131e5578081fd5b82356131f0816140dc565b91506020830135613200816140dc565b809150509250929050565b60008060006060848603121561321f578081fd5b833561322a816140dc565b9250602084013561323a816140dc565b929592945050506040919091013590565b600080600080600080600060e0888a031215613265578283fd5b8735613270816140dc565b96506020880135613280816140dc565b95506040880135945060608801359350608088013560ff811681146132a3578384fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806000604084860312156132d4578283fd5b83356132df816140dc565b9250602084013567ffffffffffffffff8111156132fa578283fd5b6133068682870161311e565b9497909650939450505050565b60008060408385031215613325578182fd5b8235613330816140dc565b946020939093013593505050565b60008060208385031215613350578182fd5b823567ffffffffffffffff811115613366578283fd5b6133728582860161311e565b90969095509350505050565b60006020808385031215613390578182fd5b825167ffffffffffffffff8111156133a6578283fd5b8301601f810185136133b6578283fd5b80516133c96133c482613fa7565b613f76565b81815283810190838501858402850186018910156133e5578687fd5b8694505b838510156134105780516133fc816140dc565b8352600194909401939185019185016133e9565b50979650505050505050565b6000806020838503121561342e578182fd5b823567ffffffffffffffff80821115613445578384fd5b818501915085601f830112613458578384fd5b813581811115613466578485fd5b86602060c08302850101111561347a578485fd5b60209290920196919550909350505050565b6000602080838503121561349e578182fd5b825167ffffffffffffffff8111156134b4578283fd5b8301601f810185136134c4578283fd5b80516134d26133c482613fa7565b818152838101908385016040808502860187018a10156134f0578788fd5b8795505b8486101561353e5780828b03121561350a578788fd5b61351381613f76565b825161351e816140dc565b8152828801518882015284526001959095019492860192908101906134f4565b509098975050505050505050565b60006020828403121561355d578081fd5b610ea382613167565b600060208284031215613577578081fd5b5035919050565b60008060408385031215613590578182fd5b823591506020830135613200816140dc565b600080604083850312156135b4578182fd5b50508035926020909101359150565b6000602082840312156135d4578081fd5b81356001600160e01b031981168114610ea3578182fd5b60008060008060408587031215613600578182fd5b843567ffffffffffffffff80821115613617578384fd5b61362388838901613177565b9096509450602087013591508082111561363b578384fd5b5061364887828801613177565b95989497509550505050565b600060808284031215613665578081fd5b61366f6080613f76565b825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156136ac578081fd5b5051919050565b6001600160a01b03169052565b60008284526020808501945082825b858110156136fd5781356136e2816140dc565b6001600160a01b0316875295820195908201906001016136cf565b509495945050505050565b7f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b60007f416363657373436f6e74726f6c3a206163636f756e742000000000000000000082528351613776816017850160208801614019565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516137b3816028840160208801614019565b01602801949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60006001600160a01b0385168252604060208301526107726040830184866136c0565b6001600160a01b03929092168252602082015260400190565b60006020825261125d6020830184866136c0565b6020808252825182820181905260009190848201906040850190845b818110156138a25783516001600160a01b03168352928401929184019160010161387d565b50909695505050505050565b6020808252818101839052600090604080840186845b8781101561394f576138d582613167565b151583526138e4858301613167565b1515858401526138f5848301613167565b1515848401526060613908818401613167565b151590840152608061391b838201613167565b15159084015260a061392e838201613113565b61393a828601826136b3565b505060c09283019291909101906001016138c4565b5090979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156139a757815180516001600160a01b03168552860151868501529284019290850190600101613979565b5091979650505050505050565b901515815260200190565b92151583526001600160a01b03919091166020830152604082015260600190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082528251806020840152613a86816040850160208701614019565b601f01601f19169190910160400192915050565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b6020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b6020808252600e908201527f444546543a202172657761726473000000000000000000000000000000000000604082015260600190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560408201527f7373000000000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600d908201527f444546543a202170617573656400000000000000000000000000000000000000604082015260600190565b60208082526017908201527f444546543a202156455354494e475f434f4e5452414354000000000000000000604082015260600190565b6020808252601d908201527f45524332305065726d69743a206578706972656420646561646c696e65000000604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b6020808252600b908201527f444546543a20216275726e000000000000000000000000000000000000000000604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252601e908201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604082015260600190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460408201527f7265737300000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252600c908201527f444546543a207061757365640000000000000000000000000000000000000000604082015260600190565b60208082526027908201527f444546543a207472616e7366657220616d6f756e74206578636565647320616c60408201527f6c6f77616e636500000000000000000000000000000000000000000000000000606082015260800190565b6020808252600b908201527f444546543a202173656c66000000000000000000000000000000000000000000604082015260600190565b60208082526025908201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760408201527f207a65726f000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201527f20726f6c657320666f722073656c660000000000000000000000000000000000606082015260800190565b600060a0820190506001600160a01b038084511683528060208501511660208401525060408301516040830152606083015160608301526080830151608083015292915050565b918252602082015260400190565b60ff91909116815260200190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613f9f57613f9f6140c6565b604052919050565b600067ffffffffffffffff821115613fc157613fc16140c6565b5060209081020190565b60008219821115613fde57613fde6140b0565b500190565b6000816000190483118215151615613ffd57613ffd6140b0565b500290565b600082821015614014576140146140b0565b500390565b60005b8381101561403457818101518382015260200161401c565b83811115614043576000848401525b50505050565b600081614058576140586140b0565b506000190190565b60028104600182168061407457607f821691505b602082108114156129d957634e487b7160e01b600052602260045260246000fd5b60006000198214156140a9576140a96140b0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610bf457600080fdfea2646970667358221220696d4922b0b23ae3f3f6f9c632fa2af5c4ec3041a14cdc576fb1e77a016f5cf764736f6c63430008010033

Deployed Bytecode Sourcemap

55220:13046:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62635:314;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26189:227;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;55524:68::-;;;:::i;65445:150::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;35828:100::-;;;:::i;:::-;;;;;;;:::i;37930:169::-;;;;;;:::i;:::-;;:::i;66030:264::-;;;;;;:::i;:::-;;:::i;:::-;;57790:214;;;:::i;67192:269::-;;;;;;:::i;:::-;;:::i;65607:141::-;;;:::i;65760:258::-;;;;;;:::i;:::-;;:::i;61764:232::-;;;;;;:::i;:::-;;:::i;58577:588::-;;;;;;:::i;:::-;;:::i;12938:123::-;;;;;;:::i;:::-;;:::i;27560:165::-;;;;;;:::i;:::-;;:::i;36790:93::-;;;:::i;:::-;;;;;;;:::i;68137:126::-;;;:::i;54753:115::-;;;:::i;28083:174::-;;;;;;:::i;:::-;;:::i;39105:215::-;;;;;;:::i;:::-;;:::i;58016:139::-;;;:::i;62358:265::-;;;;;;:::i;:::-;;:::i;55378:62::-;;;:::i;63268:587::-;;;;;;:::i;:::-;;:::i;66921:263::-;;;;;;:::i;:::-;;:::i;62008:338::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;57525:253::-;;;;;;:::i;:::-;;:::i;64197:1236::-;;;;;;:::i;:::-;;:::i;54495:128::-;;;;;;:::i;:::-;;:::i;62961:295::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;55447:70::-;;;:::i;61015:737::-;;;;;;:::i;:::-;;:::i;27015:145::-;;;;;;:::i;:::-;;:::i;11936:139::-;;;;;;:::i;:::-;;:::i;55309:62::-;;;:::i;36047:104::-;;;:::i;55599:60::-;;;:::i;59563:376::-;;;;;;:::i;:::-;;:::i;39823:377::-;;;;;;:::i;:::-;;:::i;58317:248::-;;;;;;:::i;:::-;;:::i;56013:20::-;;;:::i;63867:318::-;;;;;;:::i;:::-;;:::i;59177:374::-;;;;;;:::i;:::-;;:::i;58167:138::-;;;:::i;27334:134::-;;;;;;:::i;:::-;;:::i;9909:41::-;;;:::i;53658:771::-;;;;;;:::i;:::-;;:::i;27818:170::-;;;;;;:::i;:::-;;:::i;37632:151::-;;;;;;:::i;:::-;;:::i;57319:194::-;;;;;;:::i;:::-;;:::i;62635:314::-;62766:4;62788:23;62826:14;55712:1;62826:39;;;;;;-1:-1:-1;;;62826:39:0;;;;;;;;;;;;;;;;;;;62884:57;;;;;-1:-1:-1;;;;;62826:39:0;;;;-1:-1:-1;62826:39:0;;62884:40;;:57;;62925:4;;62931:9;;;;62884:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62877:64;62635:314;-1:-1:-1;;;;;62635:314:0:o;26189:227::-;26274:4;-1:-1:-1;;;;;;26298:57:0;;26313:42;26298:57;;:110;;;26372:36;26396:11;26372:23;:36::i;:::-;26291:117;;26189:227;;;;:::o;55524:68::-;55565:27;55524:68;:::o;65445:150::-;65536:7;65568:14;65583:3;65568:19;;;;;;-1:-1:-1;;;65568:19:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65568:19:0;;65445:150;-1:-1:-1;;65445:150:0:o;35828:100::-;35882:13;35915:5;35908:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35828:100;;:::o;37930:169::-;38013:4;38030:39;38039:12;:10;:12::i;:::-;38053:7;38062:6;38030:8;:39::i;:::-;-1:-1:-1;38087:4:0;37930:169;;;;;:::o;66030:264::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;;;;;;;;;55347:24:::1;11505:30;11516:4;11522:12;:10;:12::i;:::-;11505:10;:30::i;:::-;66187:42:::2;66205:2;66209:19;66187:17;:42::i;:::-;66245:41;66262:2;66266:19;66245:41;;;;;;;:::i;:::-;;;;;;;;57160:1:::1;66030:264:::0;;:::o;57790:214::-;57883:4;57925:14;55712:1;57925:39;;;;;;-1:-1:-1;;;57925:39:0;;;;;;;;;;;;;;;;;;;;57913:83;;;;;;;;-1:-1:-1;;;;;57925:39:0;;;;57913:81;;:83;;;;;;;;;;57925:39;57913:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57906:90;;57790:214;:::o;67192:269::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;55416:24:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;67350:44:::2;67368:4;67374:19;67350:17;:44::i;:::-;67410:43;67427:4;67433:19;67410:43;;;;;;;:::i;65607:141::-:0;65719:14;:21;65607:141;:::o;65760:258::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;55347:24:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;65913:42:::2;65931:2;65935:19;65913:17;:42::i;:::-;65971:39;65986:2;65990:19;65971:39;;;;;;;:::i;61764:232::-:0;61840:23;61878:14;55712:1;61878:39;;;;;;-1:-1:-1;;;61878:39:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61878:39:0;;-1:-1:-1;61878:39:0;61936:28;61965:12;:10;:12::i;:::-;61979:8;61936:52;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61929:59;61764:232;;:::o;58577:588::-;57101:8;;58750:4;;57101:8;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;58795:22:0;::::1;58773:83;;;;-1:-1:-1::0;;;58773:83:0::1;;;;;;;:::i;:::-;58867:36;58877:6;58885:9;58896:6;58867:9;:36::i;:::-;-1:-1:-1::0;;;;;58943:19:0;::::1;58916:24;58943:19:::0;;;:11:::1;:19;::::0;;;;58916:24;58963:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;58943:33:0::1;-1:-1:-1::0;;;;;58943:33:0::1;;;;;;;;;;;;;58916:60;;59015:6;58995:16;:26;;58987:78;;;;-1:-1:-1::0;;;58987:78:0::1;;;;;;;:::i;:::-;59076:57;59085:6;59093:12;:10;:12::i;:::-;59107:25;59126:6:::0;59107:16;:25:::1;:::i;:::-;59076:8;:57::i;:::-;-1:-1:-1::0;59153:4:0::1;::::0;58577:588;-1:-1:-1;;;;58577:588:0:o;12938:123::-;13004:7;13031:12;;;;;;;;;;:22;;;;12938:123::o;27560:165::-;27645:30;27661:4;27667:7;27645:15;:30::i;:::-;27686:18;;;;:12;:18;;;;;:31;;27709:7;27686:22;:31::i;:::-;;27560:165;;:::o;36790:93::-;36873:2;36790:93;:::o;68137:126::-;68242:13;68137:126;:::o;54753:115::-;54813:7;54840:20;:18;:20::i;28083:174::-;28171:33;28190:4;28196:7;28171:18;:33::i;:::-;28215:18;;;;:12;:18;;;;;:34;;28241:7;28215:25;:34::i;39105:215::-;39193:4;39210:80;39219:12;:10;:12::i;:::-;39233:7;39279:10;39242:11;:25;39254:12;:10;:12::i;:::-;-1:-1:-1;;;;;39242:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;39242:25:0;;;:34;;;;;;;;;;:47;;;;:::i;58016:139::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;9946:4:::1;11505:30;9946:4:::0;11522:12:::1;:10;:12::i;11505:30::-;-1:-1:-1::0;58132:8:0::2;:15:::0;;-1:-1:-1;;58132:15:0::2;58143:4;58132:15;::::0;;58016:139::o;62358:265::-;62455:4;62477:23;62515:14;55712:1;62515:39;;;;;;-1:-1:-1;;;62515:39:0;;;;;;;;;;;;;;;;;;;62573:42;;;;;-1:-1:-1;;;;;62515:39:0;;;;-1:-1:-1;62515:39:0;;62573:36;;:42;;62610:4;;62573:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62566:49;62358:265;-1:-1:-1;;;62358:265:0:o;55378:62::-;55416:24;55378:62;:::o;63268:587::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;63389:23:::1;63427:14;55712:1;63427:39;;;;;;-1:-1:-1::0;;;63427:39:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;63478:45:::1;::::0;;;;-1:-1:-1;;;;;63427:39:0;;::::1;::::0;-1:-1:-1;63427:39:0;;63478:34:::1;::::0;:45:::1;::::0;63513:9;;;;63478:45:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;63544:12;63559:11;-1:-1:-1::0;;;;;63559:36:0::1;;63596:12;:10;:12::i;:::-;63559:50;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63544:65;;63638:1;63628:7;:11;63620:38;;;;-1:-1:-1::0;;;63620:38:0::1;;;;;;;:::i;:::-;63679:11;-1:-1:-1::0;;;;;63679:32:0::1;;63712:12;:10;:12::i;:::-;63679:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;63736:40;63754:12;:10;:12::i;:::-;63768:7;63736:17;:40::i;:::-;63802:45;63825:12;:10;:12::i;:::-;63839:7;63802:45;;;;;;;:::i;:::-;;;;;;;;57160:1;;63268:587:::0;;:::o;66921:263::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;55416:24:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;67075:44:::2;67093:4;67099:19;67075:17;:44::i;:::-;67135:41;67150:4;67156:19;67135:41;;;;;;;:::i;62008:338::-:0;62129:41;62188:23;62226:14;55712:1;62226:39;;;;;;-1:-1:-1;;;62226:39:0;;;;;;;;;;;;;;;;;;;62284:54;;;;;-1:-1:-1;;;;;62226:39:0;;;;-1:-1:-1;62226:39:0;;62284:47;;:54;;62332:5;;;;62284:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;62284:54:0;;;;;;;;;;;;:::i;:::-;62277:61;62008:338;-1:-1:-1;;;;62008:338:0:o;57525:253::-;57630:4;57672:14;55712:1;57672:39;;;;;;-1:-1:-1;;;57672:39:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57747:22:0;;;;;:13;:22;;;;;;;;;57660:110;;;;;57672:39;;;57660:77;;:110;;57738:7;;57660:110;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;64197:1236::-;9946:4;11505:30;9946:4;11522:12;:10;:12::i;11505:30::-;64337:6:::1;64333:360;64353:14;:21:::0;64349:25;::::1;64333:360;;;64405:42;55347:24;64429:14;64444:1;64429:17;;;;;;-1:-1:-1::0;;;64429:17:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;64429:17:0::1;64405:10;:42::i;:::-;64462;55416:24;64486:14;64501:1;64486:17;;;;;;-1:-1:-1::0;;;64486:17:0::1;;;;;;;;64462:42;64519:46;55489:28;64547:14;64562:1;64547:17;;;;;;-1:-1:-1::0;;;64547:17:0::1;;;;;;;;64519:46;64580:45;55565:27;64607:14;64622:1;64607:17;;;;;;-1:-1:-1::0;;;64607:17:0::1;;;;;;;;64580:45;64640:41;55636:23;64663:14;64678:1;64663:17;;;;;;-1:-1:-1::0;;;64663:17:0::1;;;;;;;;64640:41;64376:3:::0;::::1;::::0;::::1;:::i;:::-;;;;64333:360;;;-1:-1:-1::0;64703:21:0::1;64710:14;;64703:21;:::i;:::-;64749:6;64745:618;64761:25:::0;;::::1;64745:618;;;64821:14;;64836:1;64821:17;;;;;-1:-1:-1::0;;;64821:17:0::1;;;;;;;;;:26;::::0;::::1;:17;::::0;;::::1;;:26:::0;;::::1;::::0;-1:-1:-1;64821:26:0::1;:::i;:::-;64817:78;;;64849:46;55347:24;64872:14;;64887:1;64872:17;;;;;-1:-1:-1::0;;;64872:17:0::1;;;;;;;;;;;;;;:22;;;;;;;;;;:::i;64849:46::-;64914:14;;64929:1;64914:17;;;;;-1:-1:-1::0;;;64914:17:0::1;;;;;;;;;;;;;;:26;;;;;;;;;;:::i;:::-;64910:78;;;64942:46;55416:24;64965:14;;64980:1;64965:17;;;;;-1:-1:-1::0;;;64965:17:0::1;;;;;;;;64942:46;65007:14;;65022:1;65007:17;;;;;-1:-1:-1::0;;;65007:17:0::1;;;;;;;;;;;;;;:30;;;;;;;;;;:::i;:::-;65003:86;;;65039:50;55489:28;65066:14;;65081:1;65066:17;;;;;-1:-1:-1::0;;;65066:17:0::1;;;;;;;;65039:50;65108:14;;65123:1;65108:17;;;;;-1:-1:-1::0;;;65108:17:0::1;;;;;;;;;;;;;;:29;;;;;;;;;;:::i;:::-;65104:84;;;65139:49;55565:27;65165:14;;65180:1;65165:17;;;;;-1:-1:-1::0;;;65165:17:0::1;;;;;;;;65139:49;65207:14;;65222:1;65207:17;;;;;-1:-1:-1::0;;;65207:17:0::1;;;;;;;;;;;;;;:25;;;;;;;;;;:::i;:::-;65203:76;;;65234:45;55636:23;65256:14;;65271:1;65256:17;;;;;-1:-1:-1::0;;;65256:17:0::1;;;;;;;;65234:45;65308:14;65328;;65343:1;65328:17;;;;;-1:-1:-1::0;;;65328:17:0::1;;;;;;;;;;;;;;:22;;;;;;;;;;:::i;:::-;65308:43:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;65308:43:0;;;::::1;::::0;;;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;65308:43:0;;::::1;::::0;;;::::1;::::0;;64788:3;::::1;::::0;::::1;:::i;:::-;;;;64745:618;;;;65388:37;65410:14;;65388:37;;;;;;;:::i;54495:128::-:0;-1:-1:-1;;;;;54591:14:0;;54564:7;54591:14;;;:7;:14;;;;;:24;;:22;:24::i;62961:295::-;63073:16;63107:23;63145:14;55712:1;63145:39;;;;;;-1:-1:-1;;;63145:39:0;;;;;;;;;;;;;;;;;;;63203:45;;;;;-1:-1:-1;;;;;63145:39:0;;;;-1:-1:-1;63145:39:0;;63203:34;;:45;;63238:9;;;;63203:45;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63203:45:0;;;;;;;;;;;;:::i;55447:70::-;55489:28;55447:70;:::o;61015:737::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;61152:23:::1;61178:14;55761:1;61178:40;;;;;;-1:-1:-1::0;;;61178:40:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;61178:40:0::1;::::0;-1:-1:-1;61256:12:0::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;61237:31:0::1;:15;-1:-1:-1::0;;;;;61237:31:0::1;;61229:67;;;;-1:-1:-1::0;;;61229:67:0::1;;;;;;;:::i;:::-;61317:23;61355:14;55712:1;61355:39;;;;;;-1:-1:-1::0;;;61355:39:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;61406:30:0;;::::1;::::0;;:13:::1;:30:::0;;;;;;:40;;61355:39;;;::::1;::::0;-1:-1:-1;61440:6:0;;61406:30;;:40:::1;::::0;61440:6;;61406:40:::1;:::i;:::-;::::0;;;-1:-1:-1;;61499:53:0::1;::::0;;;;-1:-1:-1;;;;;61499:45:0;::::1;::::0;::::1;::::0;:53:::1;::::0;61545:6;;61499:53:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;61457:24:0;::::1;;::::0;;;:13:::1;:24;::::0;;;;:95;;:24;;;:95:::1;::::0;;;::::1;:::i;:::-;;;;;;;;61573:11;-1:-1:-1::0;;;;;61573:45:0::1;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;61672:9;-1:-1:-1::0;;;;;61646:44:0::1;61655:15;-1:-1:-1::0;;;;;61646:44:0::1;;61683:6;61646:44;;;;;;:::i;:::-;;;;;;;;61706:38;61726:9;61737:6;61706:38;;;;;;;:::i;27015:145::-:0;27097:7;27124:18;;;:12;:18;;;;;:28;;27146:5;27124:21;:28::i;11936:139::-;12014:4;12038:12;;;;;;;;;;;-1:-1:-1;;;;;12038:29:0;;;;;;;;;;;;;;;11936:139::o;55309:62::-;55347:24;55309:62;:::o;36047:104::-;36103:13;36136:7;36129:14;;;;;:::i;55599:60::-;55636:23;55599:60;:::o;59563:376::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;55489:28:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;-1:-1:-1::0;;;;;59756:22:0;::::2;59734:83;;;;-1:-1:-1::0;;;59734:83:0::2;;;;;;;:::i;:::-;59828:36;59838:6;59846:9;59857:6;59828:9;:36::i;:::-;59890:41;59905:6;59913:9;59924:6;59890:41;;;;;;;;:::i;39823:377::-:0;39916:4;39933:24;39960:11;:25;39972:12;:10;:12::i;:::-;-1:-1:-1;;;;;39960:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;39960:25:0;;;:34;;;;;;;;;;;-1:-1:-1;40013:35:0;;;;40005:85;;;;-1:-1:-1;;;40005:85:0;;;;;;;:::i;:::-;40101:67;40110:12;:10;:12::i;:::-;40124:7;40133:34;40152:15;40133:16;:34;:::i;40101:67::-;-1:-1:-1;40188:4:0;;39823:377;-1:-1:-1;;;39823:377:0:o;58317:248::-;57101:8;;58470:4;;57101:8;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;58493:42:::1;58503:12;:10;:12::i;:::-;58517:9;58528:6;58493:9;:42::i;56013:20::-:0;;;;;;:::o;63867:318::-;57101:8;;;;57100:9;57078:71;;;;-1:-1:-1;;;57078:71:0;;;;;;;:::i;:::-;55636:23:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;64010:23:::2;64048:14;55712:1;64048:39;;;;;;-1:-1:-1::0;;;64048:39:0::2;;;;;;;;;;::::0;;;::::2;::::0;;;;;::::2;::::0;-1:-1:-1;;;;;64157:19:0;;::::2;::::0;;:13:::2;:19:::0;;;;;;;;;64121:56;;;;;64048:39;::::2;::::0;-1:-1:-1;64048:39:0;;64121:27:::2;::::0;:56:::2;::::0;64149:6;;64121:56:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;64099:19:0;;::::2;;::::0;;;:13:::2;:19;::::0;;;;:78;;;;-1:-1:-1;;;63867:318:0:o;59177:374::-;57238:8;;59366:4;;57238:8;;57216:71;;;;-1:-1:-1;;;57216:71:0;;;;;;;:::i;:::-;55565:27:::1;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;-1:-1:-1::0;;;;;59411:22:0;::::2;59389:83;;;;-1:-1:-1::0;;;59389:83:0::2;;;;;;;:::i;:::-;59483:36;59493:6;59501:9;59512:6;59483:9;:36::i;58167:138::-:0;57238:8;;;;57216:71;;;;-1:-1:-1;;;57216:71:0;;;;;;;:::i;:::-;9946:4:::1;11505:30;9946:4:::0;11522:12:::1;:10;:12::i;11505:30::-;-1:-1:-1::0;58281:8:0::2;:16:::0;;-1:-1:-1;;58281:16:0::2;::::0;;58167:138::o;27334:134::-;27406:7;27433:18;;;:12;:18;;;;;:27;;:25;:27::i;9909:41::-;9946:4;9909:41;:::o;53658:771::-;53887:8;53868:15;:27;;53860:69;;;;-1:-1:-1;;;53860:69:0;;;;;;;:::i;:::-;53942:18;54016:16;54051:5;54075:7;54101:5;54125:16;54135:5;54125:9;:16::i;:::-;54160:8;53987:196;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;53963:231;;;;;;53942:252;;54207:12;54222:28;54239:10;54222:16;:28::i;:::-;54207:43;;54263:14;54280:28;54294:4;54300:1;54303;54306;54280:13;:28::i;:::-;54263:45;;54337:5;-1:-1:-1;;;;;54327:15:0;:6;-1:-1:-1;;;;;54327:15:0;;54319:58;;;;-1:-1:-1;;;54319:58:0;;;;;;;:::i;:::-;54390:31;54399:5;54406:7;54415:5;54390:8;:31::i;:::-;53658:771;;;;;;;;;;:::o;27818:170::-;27904:31;27921:4;27927:7;27904:16;:31::i;37632:151::-;-1:-1:-1;;;;;37748:18:0;;;37721:7;37748:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;37632:151::o;57319:194::-;9946:4;11505:30;9946:4;11522:12;:10;:12::i;11505:30::-;57462:14:::1;:5;57470:6:::0;;57462:14:::1;:::i;:::-;-1:-1:-1::0;57487:18:0::1;:7;57497:8:::0;;57487:18:::1;:::i;15172:112::-:0;15251:25;15262:4;15268:7;15251:10;:25::i;:::-;15172:112;;:::o;22431:152::-;22501:4;22525:50;22530:3;-1:-1:-1;;;;;22550:23:0;;22525:4;:50::i;11627:217::-;11712:4;-1:-1:-1;;;;;;11736:47:0;;11751:32;11736:47;;:100;;;11800:36;11824:11;11800:23;:36::i;3700:98::-;3780:10;3700:98;:::o;41220:346::-;-1:-1:-1;;;;;41322:19:0;;41314:68;;;;-1:-1:-1;;;41314:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;41401:21:0;;41393:68;;;;-1:-1:-1;;;41393:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;41474:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;;:36;;;41526:32;;;;;41504:6;;41526:32;:::i;:::-;;;;;;;;41220:346;;;:::o;12365:384::-;12445:22;12453:4;12459:7;12445;:22::i;:::-;12441:301;;12577:41;12605:7;-1:-1:-1;;;;;12577:41:0;12615:2;12577:19;:41::i;:::-;12675:38;12703:4;12710:2;12675:19;:38::i;:::-;12498:230;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;12498:230:0;;;;;;;;;;-1:-1:-1;;;12484:246:0;;;;;;;:::i;66306:607::-;66405:23;66443:14;55712:1;66443:39;;;;;;-1:-1:-1;;;66443:39:0;;;;;;;;;;;;;;;;;;66532:186;;-1:-1:-1;;;66532:186:0;;-1:-1:-1;;;;;66443:39:0;;;;-1:-1:-1;66443:39:0;;66532:73;;:186;;66443:39;;66655:2;;66680:19;;66532:186;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;66739:17:0;;;;;;:13;:17;;;;;:37;;66494:224;;-1:-1:-1;66494:224:0;;66739:17;;;:37;;66494:224;;66739:37;:::i;:::-;;;;;;;;66787:11;-1:-1:-1;;;;;66787:45:0;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66881:2;-1:-1:-1;;;;;66860:45:0;66877:1;-1:-1:-1;;;;;66860:45:0;;66885:19;66860:45;;;;;;:::i;:::-;;;;;;;;66306:607;;;;:::o;67469:656::-;67569:23;67607:14;55712:1;67607:39;;;;;;-1:-1:-1;;;67607:39:0;;;;;;;;;;;;;;;;;;67708:14;:39;;-1:-1:-1;;;;;67607:39:0;;;;-1:-1:-1;67708:14:0;67607:39;;67708;;-1:-1:-1;;;67708:39:0;;;;;;;;;;;;;;;;;;67696:230;;-1:-1:-1;;;67696:230:0;;-1:-1:-1;;;;;67708:39:0;;;;67696:114;;:230;;67708:39;67861:4;;67888:19;;67696:230;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;67947:19:0;;;;;;:13;:19;;;;;:39;;67658:268;;-1:-1:-1;67658:268:0;;67947:19;;;:39;;67658:268;;67947:39;:::i;:::-;;;;;;;;67997:11;-1:-1:-1;;;;;67997:45:0;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68093:1;-1:-1:-1;;;;;68070:47:0;68079:4;-1:-1:-1;;;;;68070:47:0;;68097:19;68070:47;;;;;;:::i;59951:1052::-;-1:-1:-1;;;;;60112:25:0;;60090:86;;;;-1:-1:-1;;;60090:86:0;;;;;;;:::i;:::-;60219:9;-1:-1:-1;;;;;60209:19:0;:6;-1:-1:-1;;;;;60209:19:0;;;60187:80;;;;-1:-1:-1;;;60187:80:0;;;;;;;:::i;:::-;60288:23;60326:14;55712:1;60326:39;;;;;;-1:-1:-1;;;60326:39:0;;;;;;;;;;;;;;;;;;;;;60464:191;;;;;;;;-1:-1:-1;;;;;60464:191:0;;;;;;;;;;;;;;;;;;;;;60576:21;;;:13;:21;;;;;;;60464:191;;;;60616:24;;;;;;;;;;60464:191;;;;60420:246;;;;;60326:39;;;;;-1:-1:-1;60326:39:0;;60420:29;;:246;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60711:34;;-1:-1:-1;;;;;60687:21:0;;;60711:34;60687:21;;;:13;:21;;;;;;;;:58;;;;60783:37;;;60756:24;;;;;;;;;;:64;;;;60874:36;;;;60846:65;;60377:289;;-1:-1:-1;60756:24:0;;60687:21;;60846:65;;;;60874:36;60846:65;:::i;:::-;;;;;;;;56086:3;-1:-1:-1;;;;;60927:68:0;60936:6;-1:-1:-1;;;;;60927:68:0;;60958:16;:36;;;60927:68;;;;;;:::i;:::-;;;;;;;;59951:1052;;;;;:::o;13323:147::-;13406:18;13419:4;13406:12;:18::i;:::-;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;13437:25:::1;13448:4;13454:7;13437:10;:25::i;49728:281::-:0;49781:7;49822:16;49805:13;:33;49801:201;;;-1:-1:-1;49862:24:0;49855:31;;49801:201;49926:64;49948:10;49960:12;49974:15;49926:21;:64::i;:::-;49919:71;;;;14371:218;14478:12;:10;:12::i;:::-;-1:-1:-1;;;;;14467:23:0;:7;-1:-1:-1;;;;;14467:23:0;;14459:83;;;;-1:-1:-1;;;14459:83:0;;;;;;;:::i;:::-;14555:26;14567:4;14573:7;14555:11;:26::i;22759:158::-;22832:4;22856:53;22864:3;-1:-1:-1;;;;;22884:23:0;;22856:7;:53::i;51901:114::-;51993:14;;51901:114::o;23717:158::-;23791:7;23842:22;23846:3;23858:5;23842:3;:22::i;23256:117::-;23319:7;23346:19;23354:3;23346:7;:19::i;55006:207::-;-1:-1:-1;;;;;55127:14:0;;55066:15;55127:14;;;:7;:14;;;;;55162:15;55127:14;55162:13;:15::i;:::-;55152:25;;55188:17;:5;:15;:17::i;:::-;55006:207;;;;:::o;50996:167::-;51073:7;51100:55;51122:20;:18;:20::i;:::-;51144:10;51100:21;:55::i;44231:1432::-;44316:7;45241:66;45227:80;;;45219:127;;;;-1:-1:-1;;;45219:127:0;;;;;;;:::i;:::-;45365:1;:7;;45370:2;45365:7;:18;;;;45376:1;:7;;45381:2;45376:7;45365:18;45357:65;;;;-1:-1:-1;;;45357:65:0;;;;;;;:::i;:::-;45520:14;45537:24;45547:4;45553:1;45556;45559;45537:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45537:24:0;;-1:-1:-1;;45537:24:0;;;-1:-1:-1;;;;;;;45580:20:0;;45572:57;;;;-1:-1:-1;;;45572:57:0;;;;;;;:::i;13715:149::-;13799:18;13812:4;13799:12;:18::i;:::-;11505:30;11516:4;11522:12;:10;:12::i;11505:30::-;13830:26:::1;13842:4;13848:7;13830:11;:26::i;15619:229::-:0;15694:22;15702:4;15708:7;15694;:22::i;:::-;15689:152;;15733:6;:12;;;;;;;;;;;-1:-1:-1;;;;;15733:29:0;;;;;;;;;:36;;-1:-1:-1;;15733:36:0;15765:4;15733:36;;;15816:12;:10;:12::i;:::-;-1:-1:-1;;;;;15789:40:0;15807:7;-1:-1:-1;;;;;15789:40:0;15801:4;15789:40;;;;;;;;;;15619:229;;:::o;17716:414::-;17779:4;17801:21;17811:3;17816:5;17801:9;:21::i;:::-;17796:327;;-1:-1:-1;17839:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;18022:18;;18000:19;;;:12;;;:19;;;;;;:40;;;;18055:11;;17796:327;-1:-1:-1;18106:5:0;18099:12;;7475:157;-1:-1:-1;;;;;;7584:40:0;;7599:25;7584:40;7475:157;;;:::o;5571:447::-;5646:13;5672:19;5704:10;5708:6;5704:1;:10;:::i;:::-;:14;;5717:1;5704:14;:::i;:::-;5694:25;;;;;;-1:-1:-1;;;5694:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5694:25:0;;5672:47;;5730:15;:6;5737:1;5730:9;;;;;;-1:-1:-1;;;5730:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;5730:15:0;;;;;;;;;5756;:6;5763:1;5756:9;;;;;;-1:-1:-1;;;5756:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;5756:15:0;;;;;;;;-1:-1:-1;5787:9:0;5799:10;5803:6;5799:1;:10;:::i;:::-;:14;;5812:1;5799:14;:::i;:::-;5787:26;;5782:131;5819:1;5815;:5;5782:131;;;5854:8;5863:5;5871:3;5863:11;5854:21;;;;;-1:-1:-1;;;5854:21:0;;;;;;;;;;;;5842:6;5849:1;5842:9;;;;;;-1:-1:-1;;;5842:9:0;;;;;;;;;;;;:33;-1:-1:-1;;;;;5842:33:0;;;;;;;;-1:-1:-1;5900:1:0;5890:11;;;;;5822:3;;;:::i;:::-;;;5782:131;;;-1:-1:-1;5931:10:0;;5923:55;;;;-1:-1:-1;;;5923:55:0;;;;;;;:::i;50017:337::-;50119:7;50199:8;50226:4;50249:7;50275:13;50315:4;50170:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;50146:200;;;;;;50139:207;;50017:337;;;;;:::o;15856:230::-;15931:22;15939:4;15945:7;15931;:22::i;:::-;15927:152;;;16002:5;15970:12;;;;;;;;;;;-1:-1:-1;;;;;15970:29:0;;;;;;;;;:37;;-1:-1:-1;;15970:37:0;;;16054:12;:10;:12::i;:::-;-1:-1:-1;;;;;16027:40:0;16045:7;-1:-1:-1;;;;;16027:40:0;16039:4;16027:40;;;;;;;;;;15856:230;;:::o;18306:1407::-;18372:4;18511:19;;;:12;;;:19;;;;;;18547:15;;18543:1163;;18909:21;18933:14;18946:1;18933:10;:14;:::i;:::-;18982:18;;18909:38;;-1:-1:-1;18962:17:0;;18982:22;;19003:1;;18982:22;:::i;:::-;18962:42;;19038:13;19025:9;:26;19021:405;;19072:17;19092:3;:11;;19104:9;19092:22;;;;;;-1:-1:-1;;;19092:22:0;;;;;;;;;;;;;;;;;19072:42;;19246:9;19217:3;:11;;19229:13;19217:26;;;;;;-1:-1:-1;;;19217:26:0;;;;;;;;;;;;;;;;;;;;:38;;;;19331:23;;;:12;;;:23;;;;;:36;;;19021:405;19507:17;;:3;;:17;;;-1:-1:-1;;;19507:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;19602:3;:12;;:19;19615:5;19602:19;;;;;;;;;;;19595:26;;;19645:4;19638:11;;;;;;;18543:1163;19689:5;19682:12;;;;;20467:120;20534:7;20561:3;:11;;20573:5;20561:18;;;;;;-1:-1:-1;;;20561:18:0;;;;;;;;;;;;;;;;;20554:25;;20467:120;;;;:::o;52023:127::-;52112:19;;52130:1;52112:19;;;52023:127::o;46582:196::-;46675:7;46741:15;46758:10;46712:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;46702:68;;;;;;46695:75;;46582:196;;;;:::o;19799:129::-;19872:4;19896:19;;;:12;;;;;:19;;;;;;:24;;;19799:129::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:138:1;84:20;;113:33;84:20;113:33;:::i;157:404::-;;;290:3;283:4;275:6;271:17;267:27;257:2;;315:8;305;298:26;257:2;-1:-1:-1;345:20:1;;388:18;377:30;;374:2;;;427:8;417;410:26;374:2;471:4;463:6;459:17;447:29;;534:3;527:4;519;511:6;507:17;499:6;495:30;491:41;488:50;485:2;;;551:1;548;541:12;485:2;247:314;;;;;:::o;566:162::-;633:20;;689:13;;682:21;672:32;;662:2;;718:1;715;708:12;733:378;;;851:3;844:4;836:6;832:17;828:27;818:2;;876:8;866;859:26;818:2;-1:-1:-1;906:20:1;;949:18;938:30;;935:2;;;988:8;978;971:26;935:2;1032:4;1024:6;1020:17;1008:29;;1084:3;1077:4;1068:6;1060;1056:19;1052:30;1049:39;1046:2;;;1101:1;1098;1091:12;1116:259;;1228:2;1216:9;1207:7;1203:23;1199:32;1196:2;;;1249:6;1241;1234:22;1196:2;1293:9;1280:23;1312:33;1339:5;1312:33;:::i;1380:402::-;;;1509:2;1497:9;1488:7;1484:23;1480:32;1477:2;;;1530:6;1522;1515:22;1477:2;1574:9;1561:23;1593:33;1620:5;1593:33;:::i;:::-;1645:5;-1:-1:-1;1702:2:1;1687:18;;1674:32;1715:35;1674:32;1715:35;:::i;:::-;1769:7;1759:17;;;1467:315;;;;;:::o;1787:470::-;;;;1933:2;1921:9;1912:7;1908:23;1904:32;1901:2;;;1954:6;1946;1939:22;1901:2;1998:9;1985:23;2017:33;2044:5;2017:33;:::i;:::-;2069:5;-1:-1:-1;2126:2:1;2111:18;;2098:32;2139:35;2098:32;2139:35;:::i;:::-;1891:366;;2193:7;;-1:-1:-1;;;2247:2:1;2232:18;;;;2219:32;;1891:366::o;2262:853::-;;;;;;;;2474:3;2462:9;2453:7;2449:23;2445:33;2442:2;;;2496:6;2488;2481:22;2442:2;2540:9;2527:23;2559:33;2586:5;2559:33;:::i;:::-;2611:5;-1:-1:-1;2668:2:1;2653:18;;2640:32;2681:35;2640:32;2681:35;:::i;:::-;2735:7;-1:-1:-1;2789:2:1;2774:18;;2761:32;;-1:-1:-1;2840:2:1;2825:18;;2812:32;;-1:-1:-1;2896:3:1;2881:19;;2868:33;2945:4;2932:18;;2920:31;;2910:2;;2970:6;2962;2955:22;2910:2;2432:683;;;;-1:-1:-1;2432:683:1;;;;2998:7;3052:3;3037:19;;3024:33;;-1:-1:-1;3104:3:1;3089:19;;;3076:33;;2432:683;-1:-1:-1;;2432:683:1:o;3120:600::-;;;;3284:2;3272:9;3263:7;3259:23;3255:32;3252:2;;;3305:6;3297;3290:22;3252:2;3349:9;3336:23;3368:33;3395:5;3368:33;:::i;:::-;3420:5;-1:-1:-1;3476:2:1;3461:18;;3448:32;3503:18;3492:30;;3489:2;;;3540:6;3532;3525:22;3489:2;3584:76;3652:7;3643:6;3632:9;3628:22;3584:76;:::i;:::-;3242:478;;3679:8;;-1:-1:-1;3558:102:1;;-1:-1:-1;;;;3242:478:1:o;3725:327::-;;;3854:2;3842:9;3833:7;3829:23;3825:32;3822:2;;;3875:6;3867;3860:22;3822:2;3919:9;3906:23;3938:33;3965:5;3938:33;:::i;:::-;3990:5;4042:2;4027:18;;;;4014:32;;-1:-1:-1;;;3812:240:1:o;4057:463::-;;;4204:2;4192:9;4183:7;4179:23;4175:32;4172:2;;;4225:6;4217;4210:22;4172:2;4270:9;4257:23;4303:18;4295:6;4292:30;4289:2;;;4340:6;4332;4325:22;4289:2;4384:76;4452:7;4443:6;4432:9;4428:22;4384:76;:::i;:::-;4479:8;;4358:102;;-1:-1:-1;4162:358:1;-1:-1:-1;;;;4162:358:1:o;4525:1021::-;;4651:2;4694;4682:9;4673:7;4669:23;4665:32;4662:2;;;4715:6;4707;4700:22;4662:2;4753:9;4747:16;4786:18;4778:6;4775:30;4772:2;;;4823:6;4815;4808:22;4772:2;4851:22;;4904:4;4896:13;;4892:27;-1:-1:-1;4882:2:1;;4938:6;4930;4923:22;4882:2;4972;4966:9;4995:66;5011:49;5057:2;5011:49;:::i;:::-;4995:66;:::i;:::-;5095:15;;;5126:12;;;;5158:11;;;5196;;;5188:20;;5184:29;;5181:42;-1:-1:-1;5178:2:1;;;5241:6;5233;5226:22;5178:2;5268:6;5259:15;;5283:233;5297:2;5294:1;5291:9;5283:233;;;5361:3;5355:10;5378:33;5405:5;5378:33;:::i;:::-;5424:18;;5315:1;5308:9;;;;;5462:12;;;;5494;;5283:233;;;-1:-1:-1;5535:5:1;4631:915;-1:-1:-1;;;;;;;4631:915:1:o;5551:702::-;;;5732:2;5720:9;5711:7;5707:23;5703:32;5700:2;;;5753:6;5745;5738:22;5700:2;5798:9;5785:23;5827:18;5868:2;5860:6;5857:14;5854:2;;;5889:6;5881;5874:22;5854:2;5932:6;5921:9;5917:22;5907:32;;5977:7;5970:4;5966:2;5962:13;5958:27;5948:2;;6004:6;5996;5989:22;5948:2;6049;6036:16;6075:2;6067:6;6064:14;6061:2;;;6096:6;6088;6081:22;6061:2;6157:7;6152:2;6144:4;6136:6;6132:17;6128:2;6124:26;6120:35;6117:48;6114:2;;;6183:6;6175;6168:22;6114:2;6219;6211:11;;;;;6241:6;;-1:-1:-1;5690:563:1;;-1:-1:-1;;;;5690:563:1:o;6258:1301::-;;6432:2;6475;6463:9;6454:7;6450:23;6446:32;6443:2;;;6496:6;6488;6481:22;6443:2;6534:9;6528:16;6567:18;6559:6;6556:30;6553:2;;;6604:6;6596;6589:22;6553:2;6632:22;;6685:4;6677:13;;6673:27;-1:-1:-1;6663:2:1;;6719:6;6711;6704:22;6663:2;6753;6747:9;6776:66;6792:49;6838:2;6792:49;:::i;6776:66::-;6876:15;;;6907:12;;;;6939:11;;;6969:4;7000:11;;;6992:20;;6988:29;;6985:42;-1:-1:-1;6982:2:1;;;7045:6;7037;7030:22;6982:2;7072:6;7063:15;;7087:442;7101:2;7098:1;7095:9;7087:442;;;7172:2;7166:3;7157:7;7153:17;7149:26;7146:2;;;7193:6;7185;7178:22;7146:2;7228:19;7244:2;7228:19;:::i;:::-;7281:3;7275:10;7298:35;7325:7;7298:35;:::i;:::-;7346:22;;7410:12;;;7404:19;7388:14;;;7381:43;7437:18;;7119:1;7112:9;;;;;7475:12;;;;7507;;;;7087:442;;;-1:-1:-1;7548:5:1;;6412:1147;-1:-1:-1;;;;;;;;6412:1147:1:o;7564:192::-;;7673:2;7661:9;7652:7;7648:23;7644:32;7641:2;;;7694:6;7686;7679:22;7641:2;7722:28;7740:9;7722:28;:::i;7761:190::-;;7873:2;7861:9;7852:7;7848:23;7844:32;7841:2;;;7894:6;7886;7879:22;7841:2;-1:-1:-1;7922:23:1;;7831:120;-1:-1:-1;7831:120:1:o;7956:327::-;;;8085:2;8073:9;8064:7;8060:23;8056:32;8053:2;;;8106:6;8098;8091:22;8053:2;8147:9;8134:23;8124:33;;8207:2;8196:9;8192:18;8179:32;8220:33;8247:5;8220:33;:::i;8288:258::-;;;8417:2;8405:9;8396:7;8392:23;8388:32;8385:2;;;8438:6;8430;8423:22;8385:2;-1:-1:-1;;8466:23:1;;;8536:2;8521:18;;;8508:32;;-1:-1:-1;8375:171:1:o;8551:352::-;;8662:2;8650:9;8641:7;8637:23;8633:32;8630:2;;;8683:6;8675;8668:22;8630:2;8727:9;8714:23;-1:-1:-1;;;;;;8770:5:1;8766:78;8759:5;8756:89;8746:2;;8864:6;8856;8849:22;8908:755;;;;;9077:2;9065:9;9056:7;9052:23;9048:32;9045:2;;;9098:6;9090;9083:22;9045:2;9143:9;9130:23;9172:18;9213:2;9205:6;9202:14;9199:2;;;9234:6;9226;9219:22;9199:2;9278:61;9331:7;9322:6;9311:9;9307:22;9278:61;:::i;:::-;9358:8;;-1:-1:-1;9252:87:1;-1:-1:-1;9446:2:1;9431:18;;9418:32;;-1:-1:-1;9462:16:1;;;9459:2;;;9496:6;9488;9481:22;9459:2;;9540:63;9595:7;9584:8;9573:9;9569:24;9540:63;:::i;:::-;9035:628;;;;-1:-1:-1;9622:8:1;-1:-1:-1;;;;9035:628:1:o;9668:472::-;;9823:3;9811:9;9802:7;9798:23;9794:33;9791:2;;;9845:6;9837;9830:22;9791:2;9876:20;9892:3;9876:20;:::i;:::-;9925:9;9919:16;9912:5;9905:31;9989:2;9978:9;9974:18;9968:25;9963:2;9956:5;9952:14;9945:49;10047:2;10036:9;10032:18;10026:25;10021:2;10014:5;10010:14;10003:49;10105:2;10094:9;10090:18;10084:25;10079:2;10072:5;10068:14;10061:49;10129:5;10119:15;;;9781:359;;;;:::o;10340:194::-;;10463:2;10451:9;10442:7;10438:23;10434:32;10431:2;;;10484:6;10476;10469:22;10431:2;-1:-1:-1;10512:16:1;;10421:113;-1:-1:-1;10421:113:1:o;10539:129::-;-1:-1:-1;;;;;10607:54:1;10595:67;;10585:83::o;10673:555::-;;10779:6;10774:3;10767:19;10805:4;10834:2;10829:3;10825:12;10818:19;;10860:5;10883:3;10895:308;10909:6;10906:1;10903:13;10895:308;;;10986:6;10973:20;11006:35;11033:7;11006:35;:::i;:::-;-1:-1:-1;;;;;11066:56:1;11054:69;;11143:12;;;;11178:15;;;;10931:1;10924:9;10895:308;;;-1:-1:-1;11219:3:1;;10757:471;-1:-1:-1;;;;;10757:471:1:o;11233:444::-;11503:66;11491:79;;11595:1;11586:11;;11579:27;;;;11631:2;11622:12;;11615:28;11668:2;11659:12;;11481:196::o;11682:786::-;;12093:25;12088:3;12081:38;12148:6;12142:13;12164:62;12219:6;12214:2;12209:3;12205:12;12198:4;12190:6;12186:17;12164:62;:::i;:::-;12290:19;12285:2;12245:16;;;12277:11;;;12270:40;12335:13;;12357:63;12335:13;12406:2;12398:11;;12391:4;12379:17;;12357:63;:::i;:::-;12440:17;12459:2;12436:26;;12071:397;-1:-1:-1;;;;12071:397:1:o;12473:226::-;-1:-1:-1;;;;;12637:55:1;;;;12619:74;;12607:2;12592:18;;12574:125::o;12704:327::-;-1:-1:-1;;;;;12957:15:1;;;12939:34;;13009:15;;13004:2;12989:18;;12982:43;12866:2;12851:18;;12833:198::o;13036:398::-;-1:-1:-1;;;;;13317:15:1;;;13299:34;;13369:15;;;;13364:2;13349:18;;13342:43;13416:2;13401:18;;13394:34;;;;13226:2;13211:18;;13193:241::o;13439:414::-;;-1:-1:-1;;;;;13660:6:1;13656:55;13645:9;13638:74;13748:2;13743;13732:9;13728:18;13721:30;13768:79;13843:2;13832:9;13828:18;13820:6;13812;13768:79;:::i;13858:297::-;-1:-1:-1;;;;;14050:55:1;;;;14032:74;;14137:2;14122:18;;14115:34;14020:2;14005:18;;13987:168::o;14160:294::-;;14349:2;14338:9;14331:21;14369:79;14444:2;14433:9;14429:18;14421:6;14413;14369:79;:::i;14459:684::-;14630:2;14682:21;;;14752:13;;14655:18;;;14774:22;;;14459:684;;14630:2;14853:15;;;;14827:2;14812:18;;;14459:684;14899:218;14913:6;14910:1;14907:13;14899:218;;;14978:13;;-1:-1:-1;;;;;14974:62:1;14962:75;;15092:15;;;;15057:12;;;;14935:1;14928:9;14899:218;;;-1:-1:-1;15134:3:1;;14610:533;-1:-1:-1;;;;;;14610:533:1:o;15148:1280::-;15395:2;15447:21;;;15420:18;;;15503:22;;;15148:1280;;15544:2;15562:18;;;15603:6;15148:1280;15640:762;15654:6;15651:1;15648:13;15640:762;;;15729:25;15747:6;15729:25;:::i;:::-;15722:33;15715:41;15710:3;15703:54;15805:34;15835:2;15827:6;15823:15;15805:34;:::i;:::-;15798:42;15791:50;15786:2;15781:3;15777:12;15770:72;15890:34;15920:2;15912:6;15908:15;15890:34;:::i;:::-;15883:42;15876:50;15871:2;15866:3;15862:12;15855:72;15950:4;16002:34;16032:2;16024:6;16020:15;16002:34;:::i;:::-;15995:42;15988:50;15974:12;;;15967:72;16062:4;16114:34;16132:15;;;16114:34;:::i;:::-;16107:42;16100:50;16086:12;;;16079:72;16174:4;16204:37;16225:15;;;16204:37;:::i;:::-;16254:41;16291:2;16286:3;16282:12;16275:5;16254:41;:::i;:::-;-1:-1:-1;;16318:4:1;16342:12;;;;16377:15;;;;;15676:1;15669:9;15640:762;;;-1:-1:-1;16419:3:1;;15375:1053;-1:-1:-1;;;;;;;15375:1053:1:o;16433:886::-;16700:2;16752:21;;;16822:13;;16725:18;;;16844:22;;;16433:886;;16700:2;16885;;16903:18;;;;16944:15;;;16433:886;16990:303;17004:6;17001:1;16998:13;16990:303;;;17063:13;;17105:9;;-1:-1:-1;;;;;17101:58:1;17089:71;;17200:11;;17194:18;17180:12;;;17173:40;17233:12;;;;17268:15;;;;17026:1;17019:9;16990:303;;;-1:-1:-1;17310:3:1;;16680:639;-1:-1:-1;;;;;;;16680:639:1:o;17324:187::-;17489:14;;17482:22;17464:41;;17452:2;17437:18;;17419:92::o;17516:378::-;17737:14;;17730:22;17712:41;;-1:-1:-1;;;;;17789:55:1;;;;17784:2;17769:18;;17762:83;17876:2;17861:18;;17854:34;17700:2;17685:18;;17667:227::o;17899:177::-;18045:25;;;18033:2;18018:18;;18000:76::o;18081:614::-;18368:25;;;-1:-1:-1;;;;;18490:15:1;;;18485:2;18470:18;;18463:43;18542:15;;;;18537:2;18522:18;;18515:43;18589:2;18574:18;;18567:34;18632:3;18617:19;;18610:35;;;;18676:3;18661:19;;18654:35;18355:3;18340:19;;18322:373::o;18700:512::-;18959:25;;;19015:2;19000:18;;18993:34;;;;19058:2;19043:18;;19036:34;;;;19101:2;19086:18;;19079:34;-1:-1:-1;;;;;19150:55:1;19144:3;19129:19;;19122:84;18946:3;18931:19;;18913:299::o;19217:398::-;19444:25;;;19517:4;19505:17;;;;19500:2;19485:18;;19478:45;19554:2;19539:18;;19532:34;19597:2;19582:18;;19575:34;19431:3;19416:19;;19398:217::o;19620:383::-;;19769:2;19758:9;19751:21;19801:6;19795:13;19844:6;19839:2;19828:9;19824:18;19817:34;19860:66;19919:6;19914:2;19903:9;19899:18;19894:2;19886:6;19882:15;19860:66;:::i;:::-;19987:2;19966:15;-1:-1:-1;;19962:29:1;19947:45;;;;19994:2;19943:54;;19741:262;-1:-1:-1;;19741:262:1:o;20008:348::-;20210:2;20192:21;;;20249:2;20229:18;;;20222:30;20288:26;20283:2;20268:18;;20261:54;20347:2;20332:18;;20182:174::o;20361:356::-;20563:2;20545:21;;;20582:18;;;20575:30;20641:34;20636:2;20621:18;;20614:62;20708:2;20693:18;;20535:182::o;20722:338::-;20924:2;20906:21;;;20963:2;20943:18;;;20936:30;21002:16;20997:2;20982:18;;20975:44;21051:2;21036:18;;20896:164::o;21065:398::-;21267:2;21249:21;;;21306:2;21286:18;;;21279:30;21345:34;21340:2;21325:18;;21318:62;21416:4;21411:2;21396:18;;21389:32;21453:3;21438:19;;21239:224::o;21468:337::-;21670:2;21652:21;;;21709:2;21689:18;;;21682:30;21748:15;21743:2;21728:18;;21721:43;21796:2;21781:18;;21642:163::o;21810:347::-;22012:2;21994:21;;;22051:2;22031:18;;;22024:30;22090:25;22085:2;22070:18;;22063:53;22148:2;22133:18;;21984:173::o;22162:353::-;22364:2;22346:21;;;22403:2;22383:18;;;22376:30;22442:31;22437:2;22422:18;;22415:59;22506:2;22491:18;;22336:179::o;22520:398::-;22722:2;22704:21;;;22761:2;22741:18;;;22734:30;22800:34;22795:2;22780:18;;22773:62;-1:-1:-1;;;22866:2:1;22851:18;;22844:32;22908:3;22893:19;;22694:224::o;22923:335::-;23125:2;23107:21;;;23164:2;23144:18;;;23137:30;23203:13;23198:2;23183:18;;23176:41;23249:2;23234:18;;23097:161::o;23263:398::-;23465:2;23447:21;;;23504:2;23484:18;;;23477:30;23543:34;23538:2;23523:18;;23516:62;-1:-1:-1;;;23609:2:1;23594:18;;23587:32;23651:3;23636:19;;23437:224::o;23666:354::-;23868:2;23850:21;;;23907:2;23887:18;;;23880:30;23946:32;23941:2;23926:18;;23919:60;24011:2;23996:18;;23840:180::o;24025:400::-;24227:2;24209:21;;;24266:2;24246:18;;;24239:30;24305:34;24300:2;24285:18;;24278:62;24376:6;24371:2;24356:18;;24349:34;24415:3;24400:19;;24199:226::o;24430:336::-;24632:2;24614:21;;;24671:2;24651:18;;;24644:30;24710:14;24705:2;24690:18;;24683:42;24757:2;24742:18;;24604:162::o;24771:403::-;24973:2;24955:21;;;25012:2;24992:18;;;24985:30;25051:34;25046:2;25031:18;;25024:62;25122:9;25117:2;25102:18;;25095:37;25164:3;25149:19;;24945:229::o;25179:335::-;25381:2;25363:21;;;25420:2;25400:18;;;25393:30;25459:13;25454:2;25439:18;;25432:41;25505:2;25490:18;;25353:161::o;25519:401::-;25721:2;25703:21;;;25760:2;25740:18;;;25733:30;25799:34;25794:2;25779:18;;25772:62;25870:7;25865:2;25850:18;;25843:35;25910:3;25895:19;;25693:227::o;25925:411::-;26127:2;26109:21;;;26166:2;26146:18;;;26139:30;26205:34;26200:2;26185:18;;26178:62;26276:17;26271:2;26256:18;;26249:45;26326:3;26311:19;;26099:237::o;26341:578::-;;26537:3;26526:9;26522:19;26514:27;;-1:-1:-1;;;;;26648:2:1;26639:6;26633:13;26629:22;26618:9;26611:41;26720:2;26712:4;26704:6;26700:17;26694:24;26690:33;26683:4;26672:9;26668:20;26661:63;;26780:4;26772:6;26768:17;26762:24;26755:4;26744:9;26740:20;26733:54;26843:4;26835:6;26831:17;26825:24;26818:4;26807:9;26803:20;26796:54;26906:4;26898:6;26894:17;26888:24;26881:4;26870:9;26866:20;26859:54;26504:415;;;;:::o;27106:248::-;27280:25;;;27336:2;27321:18;;27314:34;27268:2;27253:18;;27235:119::o;27359:184::-;27531:4;27519:17;;;;27501:36;;27489:2;27474:18;;27456:87::o;27548:275::-;27619:2;27613:9;27684:2;27665:13;;-1:-1:-1;;27661:27:1;27649:40;;27719:18;27704:34;;27740:22;;;27701:62;27698:2;;;27766:18;;:::i;:::-;27802:2;27795:22;27593:230;;-1:-1:-1;27593:230:1:o;27828:192::-;;27927:18;27919:6;27916:30;27913:2;;;27949:18;;:::i;:::-;-1:-1:-1;28009:4:1;27990:17;;;27986:28;;27903:117::o;28025:128::-;;28096:1;28092:6;28089:1;28086:13;28083:2;;;28102:18;;:::i;:::-;-1:-1:-1;28138:9:1;;28073:80::o;28158:168::-;;28264:1;28260;28256:6;28252:14;28249:1;28246:21;28241:1;28234:9;28227:17;28223:45;28220:2;;;28271:18;;:::i;:::-;-1:-1:-1;28311:9:1;;28210:116::o;28331:125::-;;28399:1;28396;28393:8;28390:2;;;28404:18;;:::i;:::-;-1:-1:-1;28441:9:1;;28380:76::o;28461:258::-;28533:1;28543:113;28557:6;28554:1;28551:13;28543:113;;;28633:11;;;28627:18;28614:11;;;28607:39;28579:2;28572:10;28543:113;;;28674:6;28671:1;28668:13;28665:2;;;28709:1;28700:6;28695:3;28691:16;28684:27;28665:2;;28514:205;;;:::o;28724:136::-;;28791:5;28781:2;;28800:18;;:::i;:::-;-1:-1:-1;;;28836:18:1;;28771:89::o;28865:437::-;28950:1;28940:12;;28997:1;28987:12;;;29008:2;;29062:4;29054:6;29050:17;29040:27;;29008:2;29115;29107:6;29104:14;29084:18;29081:38;29078:2;;;-1:-1:-1;;;29149:1:1;29142:88;29253:4;29250:1;29243:15;29281:4;29278:1;29271:15;29307:135;;-1:-1:-1;;29367:17:1;;29364:2;;;29387:18;;:::i;:::-;-1:-1:-1;29434:1:1;29423:13;;29354:88::o;29447:184::-;-1:-1:-1;;;29496:1:1;29489:88;29596:4;29593:1;29586:15;29620:4;29617:1;29610:15;29636:184;-1:-1:-1;;;29685:1:1;29678:88;29785:4;29782:1;29775:15;29809:4;29806:1;29799:15;29825:156;-1:-1:-1;;;;;29906:5:1;29902:54;29895:5;29892:65;29882:2;;29971:1;29968;29961:12

Swarm Source

ipfs://696d4922b0b23ae3f3f6f9c632fa2af5c4ec3041a14cdc576fb1e77a016f5cf7
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.