creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/EnumerableSetUpgradeable.sol\";\nimport \"../utils/AddressUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable {\n    function __AccessControl_init() internal initializer {\n        __Context_init_unchained();\n        __AccessControl_init_unchained();\n    }\n\n    function __AccessControl_init_unchained() internal initializer {\n    }\n    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n    using AddressUpgradeable for address;\n\n    struct RoleData {\n        EnumerableSetUpgradeable.AddressSet members;\n        bytes32 adminRole;\n    }\n\n    mapping (bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view returns (bool) {\n        return _roles[role].members.contains(account);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view returns (uint256) {\n        return _roles[role].members.length();\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {\n        return _roles[role].members.at(index);\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) public virtual {\n        require(hasRole(_roles[role].adminRole, _msgSender()), \"AccessControl: sender must be an admin to grant\");\n\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) public virtual {\n        require(hasRole(_roles[role].adminRole, _msgSender()), \"AccessControl: sender must be an admin to revoke\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) public virtual {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);\n        _roles[role].adminRole = adminRole;\n    }\n\n    function _grantRole(bytes32 role, address account) private {\n        if (_roles[role].members.add(account)) {\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    function _revokeRole(bytes32 role, address account) private {\n        if (_roles[role].members.remove(account)) {\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal initializer {\n        __Context_init_unchained();\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal initializer {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        // Check the signature length\n        if (signature.length != 65) {\n            revert(\"ECDSA: invalid signature length\");\n        }\n\n        // Divide the signature in r, s and v variables\n        bytes32 r;\n        bytes32 s;\n        uint8 v;\n\n        // ecrecover takes the signature parameters, and the only way to get them\n        // currently is to use assembly.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            r := mload(add(signature, 0x20))\n            s := mload(add(signature, 0x40))\n            v := byte(0, mload(add(signature, 0x60)))\n        }\n\n        return recover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, \"ECDSA: invalid signature 's' value\");\n        require(v == 27 || v == 28, \"ECDSA: invalid signature 'v' value\");\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        require(signer != address(0), \"ECDSA: invalid signature\");\n\n        return signer;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * replicates the behavior of the\n     * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]\n     * JSON-RPC method.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n    /*\n     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n     */\n    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n    /**\n     * @dev Mapping of interface ids to whether or not it's supported.\n     */\n    mapping(bytes4 => bool) private _supportedInterfaces;\n\n    function __ERC165_init() internal initializer {\n        __ERC165_init_unchained();\n    }\n\n    function __ERC165_init_unchained() internal initializer {\n        // Derived contracts need only register support for their own interfaces,\n        // we register support for ERC165 itself here\n        _registerInterface(_INTERFACE_ID_ERC165);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     *\n     * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return _supportedInterfaces[interfaceId];\n    }\n\n    /**\n     * @dev Registers the contract as an implementer of the interface defined by\n     * `interfaceId`. Support of the actual ERC165 interface is automatic and\n     * registering its interface id is not required.\n     *\n     * See {IERC165-supportsInterface}.\n     *\n     * Requirements:\n     *\n     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n     */\n    function _registerInterface(bytes4 interfaceId) internal virtual {\n        require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n        _supportedInterfaces[interfaceId] = true;\n    }\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        uint256 c = a + b;\n        if (c < a) return (false, 0);\n        return (true, c);\n    }\n\n    /**\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b > a) return (false, 0);\n        return (true, a - b);\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) return (true, 0);\n        uint256 c = a * b;\n        if (c / a != b) return (false, 0);\n        return (true, c);\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b == 0) return (false, 0);\n        return (true, a / b);\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b == 0) return (false, 0);\n        return (true, a % b);\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a, \"SafeMath: subtraction overflow\");\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) return 0;\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: division by zero\");\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: modulo by zero\");\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryDiv}.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        return a % b;\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <0.8.0;\n\nimport \"../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n */\nabstract contract Initializable {\n\n    /**\n     * @dev Indicates that the contract has been initialized.\n     */\n    bool private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Modifier to protect an initializer function from being invoked twice.\n     */\n    modifier initializer() {\n        require(_initializing || _isConstructor() || !_initialized, \"Initializable: contract is already initialized\");\n\n        bool isTopLevelCall = !_initializing;\n        if (isTopLevelCall) {\n            _initializing = true;\n            _initialized = true;\n        }\n\n        _;\n\n        if (isTopLevelCall) {\n            _initializing = false;\n        }\n    }\n\n    /// @dev Returns true if and only if the function is running in the constructor\n    function _isConstructor() private view returns (bool) {\n        return !AddressUpgradeable.isContract(address(this));\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155BurnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./ERC1155Upgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n    function __ERC1155Burnable_init() internal initializer {\n        __Context_init_unchained();\n        __ERC165_init_unchained();\n        __ERC1155Burnable_init_unchained();\n    }\n\n    function __ERC1155Burnable_init_unchained() internal initializer {\n    }\n    function burn(address account, uint256 id, uint256 value) public virtual {\n        require(\n            account == _msgSender() || isApprovedForAll(account, _msgSender()),\n            \"ERC1155: caller is not owner nor approved\"\n        );\n\n        _burn(account, id, value);\n    }\n\n    function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n        require(\n            account == _msgSender() || isApprovedForAll(account, _msgSender()),\n            \"ERC1155: caller is not owner nor approved\"\n        );\n\n        _burnBatch(account, ids, values);\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155HolderUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./ERC1155ReceiverUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ncontract ERC1155HolderUpgradeable is Initializable, ERC1155ReceiverUpgradeable {\n    function __ERC1155Holder_init() internal initializer {\n        __ERC165_init_unchained();\n        __ERC1155Receiver_init_unchained();\n        __ERC1155Holder_init_unchained();\n    }\n\n    function __ERC1155Holder_init_unchained() internal initializer {\n    }\n    function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155ReceiverUpgradeable is Initializable, ERC165Upgradeable, IERC1155ReceiverUpgradeable {\n    function __ERC1155Receiver_init() internal initializer {\n        __ERC165_init_unchained();\n        __ERC1155Receiver_init_unchained();\n    }\n\n    function __ERC1155Receiver_init_unchained() internal initializer {\n        _registerInterface(\n            ERC1155ReceiverUpgradeable(address(0)).onERC1155Received.selector ^\n            ERC1155ReceiverUpgradeable(address(0)).onERC1155BatchReceived.selector\n        );\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155MetadataURIUpgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n    using SafeMathUpgradeable for uint256;\n    using AddressUpgradeable for address;\n\n    // Mapping from token ID to account balances\n    mapping (uint256 => mapping(address => uint256)) private _balances;\n\n    // Mapping from account to operator approvals\n    mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n    string private _uri;\n\n    /*\n     *     bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n     *     bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n     *     bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n     *\n     *     => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n     *        0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n     */\n    bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n    /*\n     *     bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n     */\n    bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n    /**\n     * @dev See {_setURI}.\n     */\n    function __ERC1155_init(string memory uri_) internal initializer {\n        __Context_init_unchained();\n        __ERC165_init_unchained();\n        __ERC1155_init_unchained(uri_);\n    }\n\n    function __ERC1155_init_unchained(string memory uri_) internal initializer {\n        _setURI(uri_);\n\n        // register the supported interfaces to conform to ERC1155 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC1155);\n\n        // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n        _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n    }\n\n    /**\n     * @dev See {IERC1155MetadataURI-uri}.\n     *\n     * This implementation returns the same URI for *all* token types. It relies\n     * on the token type ID substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * Clients calling this function must replace the `\\{id\\}` substring with the\n     * actual token type ID.\n     */\n    function uri(uint256) external view virtual override returns (string memory) {\n        return _uri;\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n        require(account != address(0), \"ERC1155: balance query for the zero address\");\n        return _balances[id][account];\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOfBatch}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(\n        address[] memory accounts,\n        uint256[] memory ids\n    )\n        public\n        view\n        virtual\n        override\n        returns (uint256[] memory)\n    {\n        require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n        uint256[] memory batchBalances = new uint256[](accounts.length);\n\n        for (uint256 i = 0; i < accounts.length; ++i) {\n            batchBalances[i] = balanceOf(accounts[i], ids[i]);\n        }\n\n        return batchBalances;\n    }\n\n    /**\n     * @dev See {IERC1155-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n        _operatorApprovals[_msgSender()][operator] = approved;\n        emit ApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC1155-isApprovedForAll}.\n     */\n    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[account][operator];\n    }\n\n    /**\n     * @dev See {IERC1155-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    )\n        public\n        virtual\n        override\n    {\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not owner nor approved\"\n        );\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n        _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n        _balances[id][to] = _balances[id][to].add(amount);\n\n        emit TransferSingle(operator, from, to, id, amount);\n\n        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n    }\n\n    /**\n     * @dev See {IERC1155-safeBatchTransferFrom}.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        public\n        virtual\n        override\n    {\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: transfer caller is not owner nor approved\"\n        );\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; ++i) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            _balances[id][from] = _balances[id][from].sub(\n                amount,\n                \"ERC1155: insufficient balance for transfer\"\n            );\n            _balances[id][to] = _balances[id][to].add(amount);\n        }\n\n        emit TransferBatch(operator, from, to, ids, amounts);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Sets a new URI for all token types, by relying on the token type ID\n     * substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n     * URI or any of the amounts in the JSON file at said URI will be replaced by\n     * clients with the token type ID.\n     *\n     * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n     * interpreted by clients as\n     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n     * for token type ID 0x4cce0.\n     *\n     * See {uri}.\n     *\n     * Because these URIs cannot be meaningfully represented by the {URI} event,\n     * this function emits no events.\n     */\n    function _setURI(string memory newuri) internal virtual {\n        _uri = newuri;\n    }\n\n    /**\n     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n        require(account != address(0), \"ERC1155: mint to the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n        _balances[id][account] = _balances[id][account].add(amount);\n        emit TransferSingle(operator, address(0), account, id, amount);\n\n        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        for (uint i = 0; i < ids.length; i++) {\n            _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n        }\n\n        emit TransferBatch(operator, address(0), to, ids, amounts);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens of token type `id` from `account`\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens of token type `id`.\n     */\n    function _burn(address account, uint256 id, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC1155: burn from the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n        _balances[id][account] = _balances[id][account].sub(\n            amount,\n            \"ERC1155: burn amount exceeds balance\"\n        );\n\n        emit TransferSingle(operator, account, address(0), id, amount);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     */\n    function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n        require(account != address(0), \"ERC1155: burn from the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n        for (uint i = 0; i < ids.length; i++) {\n            _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n                amounts[i],\n                \"ERC1155: burn amount exceeds balance\"\n            );\n        }\n\n        emit TransferBatch(operator, account, address(0), ids, amounts);\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `id` and `amount` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        internal\n        virtual\n    { }\n\n    function _doSafeTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    )\n        private\n    {\n        if (to.isContract()) {\n            try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n                if (response != IERC1155ReceiverUpgradeable(to).onERC1155Received.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _doSafeBatchTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        private\n    {\n        if (to.isContract()) {\n            try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n                if (response != IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n        uint256[] memory array = new uint256[](1);\n        array[0] = element;\n\n        return array;\n    }\n    uint256[47] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155MetadataURIUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC1155Upgradeable.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\n    /**\n     * @dev Returns the URI for token type `id`.\n     *\n     * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n     * clients with the actual token type ID.\n     */\n    function uri(uint256 id) external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\n    /**\n        @dev Handles the receipt of a single ERC1155 token type. This function is\n        called at the end of a `safeTransferFrom` after the balance has been updated.\n        To accept the transfer, this must return\n        `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n        (i.e. 0xf23a6e61, or its own function selector).\n        @param operator The address which initiated the transfer (i.e. msg.sender)\n        @param from The address which previously owned the token\n        @param id The ID of the token being transferred\n        @param value The amount of tokens being transferred\n        @param data Additional data with no specified format\n        @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n    */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    )\n        external\n        returns(bytes4);\n\n    /**\n        @dev Handles the receipt of a multiple ERC1155 token types. This function\n        is called at the end of a `safeBatchTransferFrom` after the balances have\n        been updated. To accept the transfer(s), this must return\n        `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n        (i.e. 0xbc197c81, or its own function selector).\n        @param operator The address which initiated the batch transfer (i.e. msg.sender)\n        @param from The address which previously owned the token\n        @param ids An array containing ids of each token being transferred (order and length must match values array)\n        @param values An array containing amounts of each token being transferred (order and length must match ids array)\n        @param data Additional data with no specified format\n        @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n    */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    )\n        external\n        returns(bytes4);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n     */\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n    /**\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n     * transfers.\n     */\n    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n    /**\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n     * `approved`.\n     */\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n    /**\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n     *\n     * If an {URI} event was emitted for `id`, the standard\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n     * returned by {IERC1155MetadataURI-uri}.\n     */\n    event URI(string value, uint256 indexed id);\n\n    /**\n     * @dev Returns the amount of tokens of token type `id` owned by `account`.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n    /**\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n     *\n     * Emits an {ApprovalForAll} event.\n     *\n     * Requirements:\n     *\n     * - `operator` cannot be the caller.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n     *\n     * See {setApprovalForAll}.\n     */\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721BurnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./ERC721Upgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Burnable Token\n * @dev ERC721 Token that can be irreversibly burned (destroyed).\n */\nabstract contract ERC721BurnableUpgradeable is Initializable, ContextUpgradeable, ERC721Upgradeable {\n    function __ERC721Burnable_init() internal initializer {\n        __Context_init_unchained();\n        __ERC165_init_unchained();\n        __ERC721Burnable_init_unchained();\n    }\n\n    function __ERC721Burnable_init_unchained() internal initializer {\n    }\n    /**\n     * @dev Burns `tokenId`. See {ERC721-_burn}.\n     *\n     * Requirements:\n     *\n     * - The caller must own `tokenId` or be an approved operator.\n     */\n    function burn(uint256 tokenId) public virtual {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n        _burn(tokenId);\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721HolderUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n  /**\n   * @dev Implementation of the {IERC721Receiver} interface.\n   *\n   * Accepts all token transfers. \n   * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n   */\ncontract ERC721HolderUpgradeable is Initializable, IERC721ReceiverUpgradeable {\n    function __ERC721Holder_init() internal initializer {\n        __ERC721Holder_init_unchained();\n    }\n\n    function __ERC721Holder_init_unchained() internal initializer {\n    }\n\n    /**\n     * @dev See {IERC721Receiver-onERC721Received}.\n     *\n     * Always returns `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n    using SafeMathUpgradeable for uint256;\n    using AddressUpgradeable for address;\n    using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n    using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n    using StringsUpgradeable for uint256;\n\n    // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n    // Mapping from holder address to their (enumerable) set of owned tokens\n    mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n    // Enumerable mapping from token ids to their owners\n    EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\n\n    // Mapping from token ID to approved address\n    mapping (uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Optional mapping for token URIs\n    mapping (uint256 => string) private _tokenURIs;\n\n    // Base URI\n    string private _baseURI;\n\n    /*\n     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n     *\n     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n    /*\n     *     bytes4(keccak256('name()')) == 0x06fdde03\n     *     bytes4(keccak256('symbol()')) == 0x95d89b41\n     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n     *\n     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n    /*\n     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd\n     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n     *\n     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    function __ERC721_init(string memory name_, string memory symbol_) internal initializer {\n        __Context_init_unchained();\n        __ERC165_init_unchained();\n        __ERC721_init_unchained(name_, symbol_);\n    }\n\n    function __ERC721_init_unchained(string memory name_, string memory symbol_) internal initializer {\n        _name = name_;\n        _symbol = symbol_;\n\n        // register the supported interfaces to conform to ERC721 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC721);\n        _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), \"ERC721: balance query for the zero address\");\n        return _holderTokens[owner].length();\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n        string memory _tokenURI = _tokenURIs[tokenId];\n        string memory base = baseURI();\n\n        // If there is no base URI, return the token URI.\n        if (bytes(base).length == 0) {\n            return _tokenURI;\n        }\n        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n        if (bytes(_tokenURI).length > 0) {\n            return string(abi.encodePacked(base, _tokenURI));\n        }\n        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n        return string(abi.encodePacked(base, tokenId.toString()));\n    }\n\n    /**\n    * @dev Returns the base URI set via {_setBaseURI}. This will be\n    * automatically added as a prefix in {tokenURI} to each token's URI, or\n    * to the token ID if no specific URI is set for that token ID.\n    */\n    function baseURI() public view virtual returns (string memory) {\n        return _baseURI;\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n        return _holderTokens[owner].at(index);\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n        return _tokenOwners.length();\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenByIndex}.\n     */\n    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n        (uint256 tokenId, ) = _tokenOwners.at(index);\n        return tokenId;\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(_msgSender() == owner || ERC721Upgradeable.isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not owner nor approved for all\"\n        );\n\n        _approve(to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n        _operatorApprovals[_msgSender()][operator] = approved;\n        emit ApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n        _safeTransfer(from, to, tokenId, _data);\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n        _transfer(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _tokenOwners.contains(tokenId);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n        address owner = ERC721Upgradeable.ownerOf(tokenId);\n        return (spender == owner || getApproved(tokenId) == spender || ERC721Upgradeable.isApprovedForAll(owner, spender));\n    }\n\n    /**\n     * @dev Safely mints `tokenId` and transfers it to `to`.\n     *\n     * Requirements:\n     d*\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n        _mint(to, tokenId);\n        require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal virtual {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _beforeTokenTransfer(address(0), to, tokenId);\n\n        _holderTokens[to].add(tokenId);\n\n        _tokenOwners.set(tokenId, to);\n\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721Upgradeable.ownerOf(tokenId); // internal owner\n\n        _beforeTokenTransfer(owner, address(0), tokenId);\n\n        // Clear approvals\n        _approve(address(0), tokenId);\n\n        // Clear metadata (if any)\n        if (bytes(_tokenURIs[tokenId]).length != 0) {\n            delete _tokenURIs[tokenId];\n        }\n\n        _holderTokens[owner].remove(tokenId);\n\n        _tokenOwners.remove(tokenId);\n\n        emit Transfer(owner, address(0), tokenId);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\n        require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId);\n\n        // Clear approvals from the previous owner\n        _approve(address(0), tokenId);\n\n        _holderTokens[from].remove(tokenId);\n        _holderTokens[to].add(tokenId);\n\n        _tokenOwners.set(tokenId, to);\n\n        emit Transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n        require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n        _tokenURIs[tokenId] = _tokenURI;\n    }\n\n    /**\n     * @dev Internal function to set the base URI for all token IDs. It is\n     * automatically added as a prefix to the value returned in {tokenURI},\n     * or to the token ID if {tokenURI} is empty.\n     */\n    function _setBaseURI(string memory baseURI_) internal virtual {\n        _baseURI = baseURI_;\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n        private returns (bool)\n    {\n        if (!to.isContract()) {\n            return true;\n        }\n        bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n            IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n            _msgSender(),\n            from,\n            tokenId,\n            _data\n        ), \"ERC721: transfer to non ERC721Receiver implementer\");\n        bytes4 retval = abi.decode(returndata, (bytes4));\n        return (retval == _ERC721_RECEIVED);\n    }\n\n    /**\n     * @dev Approve `to` to operate on `tokenId`\n     *\n     * Emits an {Approval} event.\n     */\n    function _approve(address to, uint256 tokenId) internal virtual {\n        _tokenApprovals[tokenId] = to;\n        emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n     * transferred to `to`.\n     * - When `from` is zero, `tokenId` will be minted for `to`.\n     * - When `to` is zero, ``from``'s `tokenId` will be burned.\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n    uint256[41] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721EnumerableUpgradeable is IERC721Upgradeable {\n\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721MetadataUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n     */\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n      * @dev Safely transfers `tokenId` token from `from` to `to`.\n      *\n      * Requirements:\n      *\n      * - `from` cannot be the zero address.\n      * - `to` cannot be the zero address.\n      * - `tokenId` token must exist and be owned by `from`.\n      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n      *\n      * Emits a {Transfer} event.\n      */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { size := extcodesize(account) }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: value }(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/Initializable.sol\";\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal initializer {\n        __Context_init_unchained();\n    }\n\n    function __Context_init_unchained() internal initializer {\n    }\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n    uint256[50] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Map type with\n    // bytes32 keys and values.\n    // The Map implementation uses private functions, and user-facing\n    // implementations (such as Uint256ToAddressMap) are just wrappers around\n    // the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit\n    // in bytes32.\n\n    struct MapEntry {\n        bytes32 _key;\n        bytes32 _value;\n    }\n\n    struct Map {\n        // Storage of map keys and values\n        MapEntry[] _entries;\n\n        // Position of the entry defined by a key in the `entries` array, plus 1\n        // because index 0 means a key is not in the map.\n        mapping (bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n        // We read and store the key's index to prevent multiple reads from the same storage slot\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex == 0) { // Equivalent to !contains(map, key)\n            map._entries.push(MapEntry({ _key: key, _value: value }));\n            // The entry is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            map._indexes[key] = map._entries.length;\n            return true;\n        } else {\n            map._entries[keyIndex - 1]._value = value;\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function _remove(Map storage map, bytes32 key) private returns (bool) {\n        // We read and store the key's index to prevent multiple reads from the same storage slot\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex != 0) { // Equivalent to contains(map, key)\n            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n            // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = keyIndex - 1;\n            uint256 lastIndex = map._entries.length - 1;\n\n            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n            MapEntry storage lastEntry = map._entries[lastIndex];\n\n            // Move the last entry to the index where the entry to delete is\n            map._entries[toDeleteIndex] = lastEntry;\n            // Update the index for the moved entry\n            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n            // Delete the slot where the moved entry was stored\n            map._entries.pop();\n\n            // Delete the index for the deleted slot\n            delete map._indexes[key];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function _contains(Map storage map, bytes32 key) private view returns (bool) {\n        return map._indexes[key] != 0;\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function _length(Map storage map) private view returns (uint256) {\n        return map._entries.length;\n    }\n\n   /**\n    * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n    *\n    * Note that there are no guarantees on the ordering of entries inside the\n    * array, and it may change when more entries are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n        require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n        MapEntry storage entry = map._entries[index];\n        return (entry._key, entry._value);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`.  O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n    }\n\n    /**\n     * @dev Returns the value associated with `key`.  O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n        return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n    }\n\n    /**\n     * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {_tryGet}.\n     */\n    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n        return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return _remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return _contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return _length(map._inner);\n    }\n\n   /**\n    * @dev Returns the element stored at position `index` in the set. O(1).\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n        (bytes32 key, bytes32 value) = _at(map._inner, index);\n        return (uint256(key), address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`.  O(1).\n     * Does not revert if `key` is not in the map.\n     *\n     * _Available since v3.4._\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`.  O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSetUpgradeable {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping (bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) { // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n            bytes32 lastvalue = set._values[lastIndex];\n\n            // Move the last value to the index where the value to delete is\n            set._values[toDeleteIndex] = lastvalue;\n            // Update the index for the moved value\n            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n        return set._values[index];\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal initializer {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal initializer {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and make it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        uint256 index = digits - 1;\n        temp = value;\n        while (temp != 0) {\n            buffer[index--] = bytes1(uint8(48 + temp % 10));\n            temp /= 10;\n        }\n        return string(buffer);\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/EnumerableSet.sol\";\nimport \"../utils/Address.sol\";\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context {\n    using EnumerableSet for EnumerableSet.AddressSet;\n    using Address for address;\n\n    struct RoleData {\n        EnumerableSet.AddressSet members;\n        bytes32 adminRole;\n    }\n\n    mapping (bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view returns (bool) {\n        return _roles[role].members.contains(account);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view returns (uint256) {\n        return _roles[role].members.length();\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {\n        return _roles[role].members.at(index);\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) public virtual {\n        require(hasRole(_roles[role].adminRole, _msgSender()), \"AccessControl: sender must be an admin to grant\");\n\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) public virtual {\n        require(hasRole(_roles[role].adminRole, _msgSender()), \"AccessControl: sender must be an admin to revoke\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) public virtual {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);\n        _roles[role].adminRole = adminRole;\n    }\n\n    function _grantRole(bytes32 role, address account) private {\n        if (_roles[role].members.add(account)) {\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    function _revokeRole(bytes32 role, address account) private {\n        if (_roles[role].members.remove(account)) {\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () internal {\n        address msgSender = _msgSender();\n        _owner = msgSender;\n        emit OwnershipTransferred(address(0), msgSender);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}\n"
      },
      "@openzeppelin/contracts/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165 is IERC165 {\n    /*\n     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n     */\n    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n    /**\n     * @dev Mapping of interface ids to whether or not it's supported.\n     */\n    mapping(bytes4 => bool) private _supportedInterfaces;\n\n    constructor () internal {\n        // Derived contracts need only register support for their own interfaces,\n        // we register support for ERC165 itself here\n        _registerInterface(_INTERFACE_ID_ERC165);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     *\n     * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return _supportedInterfaces[interfaceId];\n    }\n\n    /**\n     * @dev Registers the contract as an implementer of the interface defined by\n     * `interfaceId`. Support of the actual ERC165 interface is automatic and\n     * registering its interface id is not required.\n     *\n     * See {IERC165-supportsInterface}.\n     *\n     * Requirements:\n     *\n     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n     */\n    function _registerInterface(bytes4 interfaceId) internal virtual {\n        require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n        _supportedInterfaces[interfaceId] = true;\n    }\n}\n"
      },
      "@openzeppelin/contracts/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/math/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        uint256 c = a + b;\n        if (c < a) return (false, 0);\n        return (true, c);\n    }\n\n    /**\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b > a) return (false, 0);\n        return (true, a - b);\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) return (true, 0);\n        uint256 c = a * b;\n        if (c / a != b) return (false, 0);\n        return (true, c);\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b == 0) return (false, 0);\n        return (true, a / b);\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        if (b == 0) return (false, 0);\n        return (true, a % b);\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a, \"SafeMath: subtraction overflow\");\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0) return 0;\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: division by zero\");\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b > 0, \"SafeMath: modulo by zero\");\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryDiv}.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        return a % b;\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/IBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
      },
      "@openzeppelin/contracts/proxy/Proxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internall call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 { revert(0, returndatasize()) }\n            default { return(0, returndatasize()) }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internall call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback () external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive () external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overriden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/ProxyAdmin.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../access/Ownable.sol\";\nimport \"./TransparentUpgradeableProxy.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/TransparentUpgradeableProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./UpgradeableProxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\n     */\n    constructor(address _logic, address admin_, bytes memory _data) public payable UpgradeableProxy(_logic, _data) {\n        assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n        _setAdmin(admin_);\n    }\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _admin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function admin() external ifAdmin returns (address admin_) {\n        admin_ = _admin();\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function implementation() external ifAdmin returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n     */\n    function changeAdmin(address newAdmin) external virtual ifAdmin {\n        require(newAdmin != address(0), \"TransparentUpgradeableProxy: new admin is the zero address\");\n        emit AdminChanged(_admin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n     */\n    function upgradeTo(address newImplementation) external virtual ifAdmin {\n        _upgradeTo(newImplementation);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n     */\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {\n        _upgradeTo(newImplementation);\n        Address.functionDelegateCall(newImplementation, data);\n    }\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _admin() internal view virtual returns (address adm) {\n        bytes32 slot = _ADMIN_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            adm := sload(slot)\n        }\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        bytes32 slot = _ADMIN_SLOT;\n\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, newAdmin)\n        }\n    }\n\n    /**\n     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n     */\n    function _beforeFallback() internal virtual override {\n        require(msg.sender != _admin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n        super._beforeFallback();\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/UpgradeableBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../access/Ownable.sol\";\nimport \"../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n    address private _implementation;\n\n    /**\n     * @dev Emitted when the implementation returned by the beacon is changed.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n     * beacon.\n     */\n    constructor(address implementation_) public {\n        _setImplementation(implementation_);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function implementation() public view virtual override returns (address) {\n        return _implementation;\n    }\n\n    /**\n     * @dev Upgrades the beacon to a new implementation.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * Requirements:\n     *\n     * - msg.sender must be the owner of the contract.\n     * - `newImplementation` must be a contract.\n     */\n    function upgradeTo(address newImplementation) public virtual onlyOwner {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Sets the implementation contract address for this beacon\n     *\n     * Requirements:\n     *\n     * - `newImplementation` must be a contract.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n        _implementation = newImplementation;\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/UpgradeableProxy.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./Proxy.sol\";\nimport \"../utils/Address.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n *\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\n * {TransparentUpgradeableProxy}.\n */\ncontract UpgradeableProxy is Proxy {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) public payable {\n        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n        _setImplementation(_logic);\n        if(_data.length > 0) {\n            Address.functionDelegateCall(_logic, _data);\n        }\n    }\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        bytes32 slot = _IMPLEMENTATION_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            impl := sload(slot)\n        }\n    }\n\n    /**\n     * @dev Upgrades the proxy to a new implementation.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal virtual {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"UpgradeableProxy: new implementation is not a contract\");\n\n        bytes32 slot = _IMPLEMENTATION_SLOT;\n\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, newImplementation)\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n *\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n    using SafeMath for uint256;\n    using Address for address;\n\n    // Mapping from token ID to account balances\n    mapping (uint256 => mapping(address => uint256)) private _balances;\n\n    // Mapping from account to operator approvals\n    mapping (address => mapping(address => bool)) private _operatorApprovals;\n\n    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n    string private _uri;\n\n    /*\n     *     bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n     *     bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n     *     bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n     *\n     *     => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n     *        0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n     */\n    bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n    /*\n     *     bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n     */\n    bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n    /**\n     * @dev See {_setURI}.\n     */\n    constructor (string memory uri_) public {\n        _setURI(uri_);\n\n        // register the supported interfaces to conform to ERC1155 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC1155);\n\n        // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n        _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\n    }\n\n    /**\n     * @dev See {IERC1155MetadataURI-uri}.\n     *\n     * This implementation returns the same URI for *all* token types. It relies\n     * on the token type ID substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * Clients calling this function must replace the `\\{id\\}` substring with the\n     * actual token type ID.\n     */\n    function uri(uint256) external view virtual override returns (string memory) {\n        return _uri;\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n        require(account != address(0), \"ERC1155: balance query for the zero address\");\n        return _balances[id][account];\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOfBatch}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(\n        address[] memory accounts,\n        uint256[] memory ids\n    )\n        public\n        view\n        virtual\n        override\n        returns (uint256[] memory)\n    {\n        require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n        uint256[] memory batchBalances = new uint256[](accounts.length);\n\n        for (uint256 i = 0; i < accounts.length; ++i) {\n            batchBalances[i] = balanceOf(accounts[i], ids[i]);\n        }\n\n        return batchBalances;\n    }\n\n    /**\n     * @dev See {IERC1155-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n        _operatorApprovals[_msgSender()][operator] = approved;\n        emit ApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC1155-isApprovedForAll}.\n     */\n    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[account][operator];\n    }\n\n    /**\n     * @dev See {IERC1155-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    )\n        public\n        virtual\n        override\n    {\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not owner nor approved\"\n        );\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n        _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n        _balances[id][to] = _balances[id][to].add(amount);\n\n        emit TransferSingle(operator, from, to, id, amount);\n\n        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n    }\n\n    /**\n     * @dev See {IERC1155-safeBatchTransferFrom}.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        public\n        virtual\n        override\n    {\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: transfer caller is not owner nor approved\"\n        );\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; ++i) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            _balances[id][from] = _balances[id][from].sub(\n                amount,\n                \"ERC1155: insufficient balance for transfer\"\n            );\n            _balances[id][to] = _balances[id][to].add(amount);\n        }\n\n        emit TransferBatch(operator, from, to, ids, amounts);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Sets a new URI for all token types, by relying on the token type ID\n     * substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n     * URI or any of the amounts in the JSON file at said URI will be replaced by\n     * clients with the token type ID.\n     *\n     * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n     * interpreted by clients as\n     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n     * for token type ID 0x4cce0.\n     *\n     * See {uri}.\n     *\n     * Because these URIs cannot be meaningfully represented by the {URI} event,\n     * this function emits no events.\n     */\n    function _setURI(string memory newuri) internal virtual {\n        _uri = newuri;\n    }\n\n    /**\n     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n        require(account != address(0), \"ERC1155: mint to the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n        _balances[id][account] = _balances[id][account].add(amount);\n        emit TransferSingle(operator, address(0), account, id, amount);\n\n        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        for (uint i = 0; i < ids.length; i++) {\n            _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\n        }\n\n        emit TransferBatch(operator, address(0), to, ids, amounts);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens of token type `id` from `account`\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens of token type `id`.\n     */\n    function _burn(address account, uint256 id, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC1155: burn from the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n        _balances[id][account] = _balances[id][account].sub(\n            amount,\n            \"ERC1155: burn amount exceeds balance\"\n        );\n\n        emit TransferSingle(operator, account, address(0), id, amount);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     */\n    function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n        require(account != address(0), \"ERC1155: burn from the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, account, address(0), ids, amounts, \"\");\n\n        for (uint i = 0; i < ids.length; i++) {\n            _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n                amounts[i],\n                \"ERC1155: burn amount exceeds balance\"\n            );\n        }\n\n        emit TransferBatch(operator, account, address(0), ids, amounts);\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `id` and `amount` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        internal\n        virtual\n    { }\n\n    function _doSafeTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    )\n        private\n    {\n        if (to.isContract()) {\n            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n                if (response != IERC1155Receiver(to).onERC1155Received.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _doSafeBatchTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    )\n        private\n    {\n        if (to.isContract()) {\n            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n                if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n        uint256[] memory array = new uint256[](1);\n        array[0] = element;\n\n        return array;\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n    /**\n     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n     */\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n    /**\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n     * transfers.\n     */\n    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\n\n    /**\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n     * `approved`.\n     */\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n    /**\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n     *\n     * If an {URI} event was emitted for `id`, the standard\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n     * returned by {IERC1155MetadataURI-uri}.\n     */\n    event URI(string value, uint256 indexed id);\n\n    /**\n     * @dev Returns the amount of tokens of token type `id` owned by `account`.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);\n\n    /**\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n     *\n     * Emits an {ApprovalForAll} event.\n     *\n     * Requirements:\n     *\n     * - `operator` cannot be the caller.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n     *\n     * See {setApprovalForAll}.\n     */\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n"
      },
      "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n    /**\n     * @dev Returns the URI for token type `id`.\n     *\n     * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n     * clients with the actual token type ID.\n     */\n    function uri(uint256 id) external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\n    /**\n        @dev Handles the receipt of a single ERC1155 token type. This function is\n        called at the end of a `safeTransferFrom` after the balance has been updated.\n        To accept the transfer, this must return\n        `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n        (i.e. 0xf23a6e61, or its own function selector).\n        @param operator The address which initiated the transfer (i.e. msg.sender)\n        @param from The address which previously owned the token\n        @param id The ID of the token being transferred\n        @param value The amount of tokens being transferred\n        @param data Additional data with no specified format\n        @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n    */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    )\n        external\n        returns(bytes4);\n\n    /**\n        @dev Handles the receipt of a multiple ERC1155 token types. This function\n        is called at the end of a `safeBatchTransferFrom` after the balances have\n        been updated. To accept the transfer(s), this must return\n        `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n        (i.e. 0xbc197c81, or its own function selector).\n        @param operator The address which initiated the batch transfer (i.e. msg.sender)\n        @param from The address which previously owned the token\n        @param ids An array containing ids of each token being transferred (order and length must match values array)\n        @param values An array containing amounts of each token being transferred (order and length must match ids array)\n        @param data Additional data with no specified format\n        @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n    */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    )\n        external\n        returns(bytes4);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n    using SafeMath for uint256;\n\n    mapping (address => uint256) private _balances;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor (string memory name_, string memory symbol_) public {\n        _name = name_;\n        _symbol = symbol_;\n        _decimals = 18;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * Requirements:\n     *\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal virtual {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/ERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n    using SafeMath for uint256;\n    using Address for address;\n    using EnumerableSet for EnumerableSet.UintSet;\n    using EnumerableMap for EnumerableMap.UintToAddressMap;\n    using Strings for uint256;\n\n    // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n    // Mapping from holder address to their (enumerable) set of owned tokens\n    mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n    // Enumerable mapping from token ids to their owners\n    EnumerableMap.UintToAddressMap private _tokenOwners;\n\n    // Mapping from token ID to approved address\n    mapping (uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to operator approvals\n    mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Optional mapping for token URIs\n    mapping (uint256 => string) private _tokenURIs;\n\n    // Base URI\n    string private _baseURI;\n\n    /*\n     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n     *\n     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n    /*\n     *     bytes4(keccak256('name()')) == 0x06fdde03\n     *     bytes4(keccak256('symbol()')) == 0x95d89b41\n     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n     *\n     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n    /*\n     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd\n     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n     *\n     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n    /**\n     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n     */\n    constructor (string memory name_, string memory symbol_) public {\n        _name = name_;\n        _symbol = symbol_;\n\n        // register the supported interfaces to conform to ERC721 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC721);\n        _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n    }\n\n    /**\n     * @dev See {IERC721-balanceOf}.\n     */\n    function balanceOf(address owner) public view virtual override returns (uint256) {\n        require(owner != address(0), \"ERC721: balance query for the zero address\");\n        return _holderTokens[owner].length();\n    }\n\n    /**\n     * @dev See {IERC721-ownerOf}.\n     */\n    function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n        return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n    }\n\n    /**\n     * @dev See {IERC721Metadata-name}.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-symbol}.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC721Metadata-tokenURI}.\n     */\n    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n        require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n        string memory _tokenURI = _tokenURIs[tokenId];\n        string memory base = baseURI();\n\n        // If there is no base URI, return the token URI.\n        if (bytes(base).length == 0) {\n            return _tokenURI;\n        }\n        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n        if (bytes(_tokenURI).length > 0) {\n            return string(abi.encodePacked(base, _tokenURI));\n        }\n        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n        return string(abi.encodePacked(base, tokenId.toString()));\n    }\n\n    /**\n    * @dev Returns the base URI set via {_setBaseURI}. This will be\n    * automatically added as a prefix in {tokenURI} to each token's URI, or\n    * to the token ID if no specific URI is set for that token ID.\n    */\n    function baseURI() public view virtual returns (string memory) {\n        return _baseURI;\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n        return _holderTokens[owner].at(index);\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n        return _tokenOwners.length();\n    }\n\n    /**\n     * @dev See {IERC721Enumerable-tokenByIndex}.\n     */\n    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n        (uint256 tokenId, ) = _tokenOwners.at(index);\n        return tokenId;\n    }\n\n    /**\n     * @dev See {IERC721-approve}.\n     */\n    function approve(address to, uint256 tokenId) public virtual override {\n        address owner = ERC721.ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not owner nor approved for all\"\n        );\n\n        _approve(to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-getApproved}.\n     */\n    function getApproved(uint256 tokenId) public view virtual override returns (address) {\n        require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev See {IERC721-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n        _operatorApprovals[_msgSender()][operator] = approved;\n        emit ApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC721-isApprovedForAll}.\n     */\n    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev See {IERC721-transferFrom}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n        _transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev See {IERC721-safeTransferFrom}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n        _safeTransfer(from, to, tokenId, _data);\n    }\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * `_data` is additional data, it has no specified format and it is sent in call to `to`.\n     *\n     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n     * implement alternative mechanisms to perform token transfer, such as signature-based.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n        _transfer(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns whether `tokenId` exists.\n     *\n     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n     *\n     * Tokens start existing when they are minted (`_mint`),\n     * and stop existing when they are burned (`_burn`).\n     */\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _tokenOwners.contains(tokenId);\n    }\n\n    /**\n     * @dev Returns whether `spender` is allowed to manage `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n        require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n        address owner = ERC721.ownerOf(tokenId);\n        return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));\n    }\n\n    /**\n     * @dev Safely mints `tokenId` and transfers it to `to`.\n     *\n     * Requirements:\n     d*\n     * - `tokenId` must not exist.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _safeMint(address to, uint256 tokenId) internal virtual {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {\n        _mint(to, tokenId);\n        require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Mints `tokenId` and transfers it to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n     *\n     * Requirements:\n     *\n     * - `tokenId` must not exist.\n     * - `to` cannot be the zero address.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _mint(address to, uint256 tokenId) internal virtual {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _beforeTokenTransfer(address(0), to, tokenId);\n\n        _holderTokens[to].add(tokenId);\n\n        _tokenOwners.set(tokenId, to);\n\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    /**\n     * @dev Destroys `tokenId`.\n     * The approval is cleared when the token is burned.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _burn(uint256 tokenId) internal virtual {\n        address owner = ERC721.ownerOf(tokenId); // internal owner\n\n        _beforeTokenTransfer(owner, address(0), tokenId);\n\n        // Clear approvals\n        _approve(address(0), tokenId);\n\n        // Clear metadata (if any)\n        if (bytes(_tokenURIs[tokenId]).length != 0) {\n            delete _tokenURIs[tokenId];\n        }\n\n        _holderTokens[owner].remove(tokenId);\n\n        _tokenOwners.remove(tokenId);\n\n        emit Transfer(owner, address(0), tokenId);\n    }\n\n    /**\n     * @dev Transfers `tokenId` from `from` to `to`.\n     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _transfer(address from, address to, uint256 tokenId) internal virtual {\n        require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, tokenId);\n\n        // Clear approvals from the previous owner\n        _approve(address(0), tokenId);\n\n        _holderTokens[from].remove(tokenId);\n        _holderTokens[to].add(tokenId);\n\n        _tokenOwners.set(tokenId, to);\n\n        emit Transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n        require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n        _tokenURIs[tokenId] = _tokenURI;\n    }\n\n    /**\n     * @dev Internal function to set the base URI for all token IDs. It is\n     * automatically added as a prefix to the value returned in {tokenURI},\n     * or to the token ID if {tokenURI} is empty.\n     */\n    function _setBaseURI(string memory baseURI_) internal virtual {\n        _baseURI = baseURI_;\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n        private returns (bool)\n    {\n        if (!to.isContract()) {\n            return true;\n        }\n        bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n            IERC721Receiver(to).onERC721Received.selector,\n            _msgSender(),\n            from,\n            tokenId,\n            _data\n        ), \"ERC721: transfer to non ERC721Receiver implementer\");\n        bytes4 retval = abi.decode(returndata, (bytes4));\n        return (retval == _ERC721_RECEIVED);\n    }\n\n    function _approve(address to, uint256 tokenId) private {\n        _tokenApprovals[tokenId] = to;\n        emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning.\n     *\n     * Calling conditions:\n     *\n     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n     * transferred to `to`.\n     * - When `from` is zero, `tokenId` will be minted for `to`.\n     * - When `to` is zero, ``from``'s `tokenId` will be burned.\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n      * @dev Safely transfers `tokenId` token from `from` to `to`.\n      *\n      * Requirements:\n      *\n      * - `from` cannot be the zero address.\n      * - `to` cannot be the zero address.\n      * - `tokenId` token must exist and be owned by `from`.\n      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n      *\n      * Emits a {Transfer} event.\n      */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Enumerable is IERC721 {\n\n    /**\n     * @dev Returns the total amount of tokens stored by the contract.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\n     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);\n\n    /**\n     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\n     * Use along with {totalSupply} to enumerate all tokens.\n     */\n    function tokenByIndex(uint256 index) external view returns (uint256);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"./IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n\n    /**\n     * @dev Returns the token collection name.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the token collection symbol.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n     */\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { size := extcodesize(account) }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: value }(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/EnumerableMap.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Map type with\n    // bytes32 keys and values.\n    // The Map implementation uses private functions, and user-facing\n    // implementations (such as Uint256ToAddressMap) are just wrappers around\n    // the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit\n    // in bytes32.\n\n    struct MapEntry {\n        bytes32 _key;\n        bytes32 _value;\n    }\n\n    struct Map {\n        // Storage of map keys and values\n        MapEntry[] _entries;\n\n        // Position of the entry defined by a key in the `entries` array, plus 1\n        // because index 0 means a key is not in the map.\n        mapping (bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n        // We read and store the key's index to prevent multiple reads from the same storage slot\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex == 0) { // Equivalent to !contains(map, key)\n            map._entries.push(MapEntry({ _key: key, _value: value }));\n            // The entry is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            map._indexes[key] = map._entries.length;\n            return true;\n        } else {\n            map._entries[keyIndex - 1]._value = value;\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function _remove(Map storage map, bytes32 key) private returns (bool) {\n        // We read and store the key's index to prevent multiple reads from the same storage slot\n        uint256 keyIndex = map._indexes[key];\n\n        if (keyIndex != 0) { // Equivalent to contains(map, key)\n            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n            // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = keyIndex - 1;\n            uint256 lastIndex = map._entries.length - 1;\n\n            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n            MapEntry storage lastEntry = map._entries[lastIndex];\n\n            // Move the last entry to the index where the entry to delete is\n            map._entries[toDeleteIndex] = lastEntry;\n            // Update the index for the moved entry\n            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n            // Delete the slot where the moved entry was stored\n            map._entries.pop();\n\n            // Delete the index for the deleted slot\n            delete map._indexes[key];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function _contains(Map storage map, bytes32 key) private view returns (bool) {\n        return map._indexes[key] != 0;\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function _length(Map storage map) private view returns (uint256) {\n        return map._entries.length;\n    }\n\n   /**\n    * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n    *\n    * Note that there are no guarantees on the ordering of entries inside the\n    * array, and it may change when more entries are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n        require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n        MapEntry storage entry = map._entries[index];\n        return (entry._key, entry._value);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`.  O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n    }\n\n    /**\n     * @dev Returns the value associated with `key`.  O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n        return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n    }\n\n    /**\n     * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {_tryGet}.\n     */\n    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n        uint256 keyIndex = map._indexes[key];\n        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n        return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return _remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return _contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return _length(map._inner);\n    }\n\n   /**\n    * @dev Returns the element stored at position `index` in the set. O(1).\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n        (bytes32 key, bytes32 value) = _at(map._inner, index);\n        return (uint256(key), address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`.  O(1).\n     * Does not revert if `key` is not in the map.\n     *\n     * _Available since v3.4._\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`.  O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping (bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) { // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n            bytes32 lastvalue = set._values[lastIndex];\n\n            // Move the last value to the index where the value to delete is\n            set._values[toDeleteIndex] = lastvalue;\n            // Update the index for the moved value\n            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n        return set._values[index];\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n   /**\n    * @dev Returns the value stored at position `index` in the set. O(1).\n    *\n    * Note that there are no guarantees on the ordering of values inside the\n    * array, and it may change when more values are added or removed.\n    *\n    * Requirements:\n    *\n    * - `index` must be strictly less than {length}.\n    */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        uint256 index = digits - 1;\n        temp = value;\n        while (temp != 0) {\n            buffer[index--] = bytes1(uint8(48 + temp % 10));\n            temp /= 10;\n        }\n        return string(buffer);\n    }\n}\n"
      },
      "contracts/ERC1155/BaseEnigmaNFT1155.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\";\nimport \"@openzeppelin/contracts/proxy/IBeacon.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"../interfaces/ITransferGatekeeper.sol\";\nimport \"../interfaces/IRoyaltyAwareNFT.sol\";\nimport \"../interfaces/IExternalVerifiedMinting.sol\";\nimport \"../utils/MintNFTEvent.sol\";\n\n/// @title BaseEnigmaNFT1155\n///\n/// @dev This contract is a ERC1155 burnable and upgradable based in openZeppelin v3.4.0.\n///         Be careful when upgrade, you must respect the same storage.\n\nabstract contract BaseEnigmaNFT1155 is\n    IRoyaltyAwareNFT,\n    ERC1155BurnableUpgradeable,\n    OwnableUpgradeable,\n    MintNFTEvent,\n    IExternalVerifiedMinting\n{\n    using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n    using StringsUpgradeable for uint256;\n    using SafeMathUpgradeable for uint256;\n\n    /* Storage */\n    // mapping from token ID to account balances.\n    // FIXME: It doesn make much sense for the user one. Check if it can be removed without breaking storage layout\n    mapping(uint256 => address) internal creators;\n    //mapping for token royaltyFee\n    mapping(uint256 => uint256) private _royaltyFee;\n    //mapping for token URIs\n    mapping(uint256 => string) private _tokenURIs;\n    //mapping for token owners\n    EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\n\n    //tokens base uri\n    string public tokenURIPrefix;\n\n    string private _name;\n\n    string private _symbol;\n\n    //token id counter, increase by 1 for each new mint\n    uint256 public newItemId;\n\n    // Transfer Gatekeeper with logic to allow token transfers\n    IBeacon public transferGatekeeperBeacon;\n\n    //mapping for token rights holder, the ones that will receive royalties\n    mapping(uint256 => address) private rightsHolders_;\n\n    mapping(address => bool) private externalVerifiers_;\n\n    bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;\n\n    /* events */\n    event TokenBaseURI(string value);\n    event SetExternalAuthorized(address externalVerifiers_, bool isAuthorized_);\n\n    /* functions */\n\n    modifier onlyExternalVerifier() {\n        require(isExternalVerifier(msg.sender), \"BaseEnigmaNFT1155: Not external verifier\");\n        _;\n    }\n\n    /**\n     * @notice Initialize NFT1155 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the toke base uri\n     */\n    function _initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_\n    ) internal initializer {\n        __ERC1155_init(tokenURIPrefix_);\n        __ERC1155Burnable_init();\n        __Ownable_init();\n\n        _name = name_;\n        _symbol = symbol_;\n        newItemId = 1;\n        _setTokenURIPrefix(tokenURIPrefix_);\n        _registerInterface(_INTERFACE_ID_ERC2981);\n    }\n\n    /// oz-upgrades-unsafe-allow constructor\n    // solhint-disable-next-line\n    constructor() initializer {}\n\n    function name() external view virtual returns (string memory) {\n        return _name;\n    }\n\n    function symbol() external view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @notice Internal function to set the token URI for a given token.\n     * Reverts if the token ID does not exist.\n     * @param tokenId_ uint256 ID of the token to set its URI\n     * @param tokenURI_ string URI to assign\n     */\n    function _setTokenURI(uint256 tokenId_, string memory tokenURI_) internal {\n        _tokenURIs[tokenId_] = tokenURI_;\n    }\n\n    /// @notice Called with the sale price to determine how much royalty\n    //          is owed and to whom.\n    /// @param _tokenId - the NFT asset queried for royalty information\n    /// @param _salePrice - the sale price of the NFT asset specified by _tokenId\n    /// @return receiver - address of who should be sent the royalty payment\n    /// @return royaltyAmount - the royalty payment amount for _salePrice\n    function royaltyInfo(uint256 _tokenId, uint256 _salePrice)\n        external\n        view\n        virtual\n        override\n        returns (address receiver, uint256 royaltyAmount)\n    {\n        return (rightsHolder(_tokenId), _salePrice.mul(_royaltyFee[_tokenId]).div(1000));\n    }\n\n    /**\n     * @notice Get the rights holder (the one to receive royalties) of given tokenID.\n     * @param tokenId ID of the Token.\n     * @return right holder of given ID.\n     */\n    function rightsHolder(uint256 tokenId) public view virtual override returns (address) {\n        address _rightsHolder = rightsHolders_[tokenId];\n        return _rightsHolder == address(0x0) ? this.getCreator(tokenId) : _rightsHolder;\n    }\n\n    /**\n     * @notice Updates the rights holder for a specific tokenId\n     * @param tokenId ID of the Token.\n     * @param newRightsHolder new rights holder of given ID.\n     * @dev Rights holder should only be set by the token creator\n     */\n    function setRightsHolder(uint256 tokenId, address newRightsHolder) external override {\n        require(msg.sender == this.getCreator(tokenId), \"Only creator\");\n        rightsHolders_[tokenId] = newRightsHolder;\n    }\n\n    /**\n     * @dev Internal function to set the token URI for all the tokens.\n     * @param _tokenURIPrefix string memory _tokenURIPrefix of the tokens.\n     */\n    function _setTokenURIPrefix(string memory _tokenURIPrefix) internal {\n        tokenURIPrefix = _tokenURIPrefix;\n        emit TokenBaseURI(_tokenURIPrefix);\n    }\n\n    /**\n     * @dev Returns an URI for a given token ID.\n     * Throws if the token ID does not exist. May return an empty string.\n     * @param tokenId uint256 ID of the token to query\n     */\n    function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\n        require(_exists(tokenId), \"ERC1155Metadata: URI query for nonexistent token\");\n        string memory _tokenURI = _tokenURIs[tokenId];\n        string memory base = tokenURIPrefix;\n\n        if (bytes(base).length == 0) {\n            return _tokenURI;\n        }\n        if (bytes(_tokenURI).length > 0) {\n            return string(abi.encodePacked(base, _tokenURI));\n        }\n        return string(abi.encodePacked(base, tokenId.toString()));\n    }\n\n    /**\n     * @dev Returns the URI for token type `id`.\n     *\n     * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n     * clients with the actual token type ID.\n     */\n    function uri(uint256 id) external view override returns (string memory) {\n        return tokenURI(id);\n    }\n\n    function _exists(uint256 tokenId) internal view virtual returns (bool) {\n        return _tokenOwners.contains(tokenId);\n    }\n\n    /**\n     * @notice Get the balance of an account's Tokens.\n     * @param account The address of the token holder\n     * @param tokenId ID of the Token\n     * @return The owner's balance of the Token type requested\n     */\n\n    function balanceOf(address account, uint256 tokenId) public view override returns (uint256) {\n        require(_exists(tokenId), \"ERC1155Metadata: balance query for nonexistent token\");\n        return super.balanceOf(account, tokenId);\n    }\n\n    /**\n     * @notice call transfer fucntion after check transfer gatekeeper allowance\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 amount,\n        bytes memory data\n    ) public virtual override {\n        bytes memory allData = abi.encode(\"1155\", tokenId, amount, data);\n        ITransferGatekeeper transferGatekeeper = ITransferGatekeeper(transferGatekeeperBeacon.implementation());\n        require(transferGatekeeper.canTransfer(from, to, _msgSender(), allData), \"Transfer not approved\");\n        super.safeTransferFrom(from, to, tokenId, amount, data);\n    }\n\n    /**\n     * @notice call transfer fucntion after check transfer gatekeeper allowance\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) public virtual override {\n        bytes memory allData = abi.encode(\"1155_batch\", ids, amounts, data);\n        ITransferGatekeeper transferGatekeeper = ITransferGatekeeper(transferGatekeeperBeacon.implementation());\n        require(transferGatekeeper.canTransfer(from, to, _msgSender(), allData), \"Batch transfer not approved\");\n        super.safeBatchTransferFrom(from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Internal function to mint a new token.\n     * Reverts if the given token ID already exists.\n     * @param tokenURI_ string memory URI of the token to be minted\n     * @param fee_ uint256 royalty of the token to be minted\n     * @param rightsHolder_ account that will be marked as the creator\n     * @param recipient account that will receive the tokens\n     * @param nonce ID that identifies the action of creation\n     * @param creator_ account that will receive the royalties\n     * @param tokenId_ id of the token to be created, it should be 0 if autoId is true\n     * @param supply_ uint256 supply of the token to be minted\n     */\n    function _mintNew(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address recipient,\n        uint256 nonce,\n        address creator_,\n        uint256 tokenId_,\n        uint256 supply_\n    ) internal virtual returns (uint256) {\n        require(!_exists(tokenId_), \"ERC1155: token already minted\");\n\n        require(_tokenOwners.set(tokenId_, recipient), \"ERC1155: token already minted\");\n        require(supply_ != 0, \"Supply should be positive\");\n        require(bytes(tokenURI_).length > 0, \"uri should be set\");\n\n        _mint(recipient, tokenId_, supply_, \"\");\n        _setTokenURI(tokenId_, tokenURI_);\n        emit URI(tokenURI_, tokenId_);\n        emit MintNewNFT(tokenId_, creator_, recipient, tokenURI_, supply_, fee_, rightsHolder_, nonce);\n\n        _royaltyFee[tokenId_] = fee_;\n        rightsHolders_[tokenId_] = rightsHolder_;\n\n        return tokenId_;\n    }\n\n    /**\n     * @dev Internal function to mint more of an existing token.\n     * Reverts if the given token does NOT exist.\n     * @param to account that will receive the tokens\n     * @param tokenId id of the token to be created, it should be 0 if autoId is true\n     * @param amount amount of tokens to be minted\n     * @param nonce number that identifies the order of creation\n     */\n    function _mintExistingNFT(\n        uint256 tokenId,\n        address to,\n        uint256 amount,\n        uint256 nonce\n    ) internal {\n        require(_exists(tokenId), \"BaseEnigmaNFT1155: TokenId does not exist\");\n        super._mint(to, tokenId, amount, \"\");\n        emit MintExistingNFT(tokenId, to, amount, nonce);\n    }\n\n    function _increaseNextId() internal returns (uint256) {\n        uint256 tokenCounter = newItemId;\n        newItemId = newItemId + 1;\n        return tokenCounter;\n    }\n\n    /**\n     * @notice call burn function after check that token exists\n     */\n    function _burn(\n        address account,\n        uint256 tokenId,\n        uint256 amount\n    ) internal virtual override {\n        require(_exists(tokenId), \"ERC1155Metadata: burn query for nonexistent token\");\n        super._burn(account, tokenId, amount);\n    }\n\n    /**\n     * @notice burn tokens to msg.sender\n     */\n    function burn(uint256 tokenId, uint256 amount) external {\n        _burn(msg.sender, tokenId, amount);\n    }\n\n    /**\n     * @dev external function to set the token URI for all the tokens.\n     * @param baseURI_ string memory _tokenURIPrefix of the tokens.\n     */\n    function setBaseURI(string memory baseURI_) external onlyOwner {\n        _setTokenURIPrefix(baseURI_);\n    }\n\n    /**\n     * @notice Set a transferGatekeeperBeacon that points to the gatekeeper implementation\n     * @param transferGatekeeperBeacon_ The IBeacon instance\n     */\n    function setTransferGatekeeperBeacon(IBeacon transferGatekeeperBeacon_) external onlyOwner {\n        transferGatekeeperBeacon = transferGatekeeperBeacon_;\n    }\n\n    /**\n     * @notice Allows to batchUpdate the royalty fees for several tokens\n     * @dev This function doesn't perform any checks to make it cheaper, be careful when invoking it\n     * @param tokenIds Tokens to update royalty from\n     * @param newRoyaltyFees New royalty fees. They must match with the tokenIds\n     */\n    function batchUpdateRoyaltyFees(uint256[] calldata tokenIds, uint256[] calldata newRoyaltyFees) external onlyOwner {\n        uint256 length = tokenIds.length;\n\n        for (uint256 index; index < length; ) {\n            _royaltyFee[tokenIds[index]] = newRoyaltyFees[index];\n            ++index;\n        }\n    }\n\n    /**\n     * @notice Kind of like an initializer for the upgrade where we support ERC2981\n     * @dev This is left unprotected as it is idempotent and it has no parameters\n     */\n    function declareERC2981Interface() external override {\n        _registerInterface(_INTERFACE_ID_ERC2981);\n    }\n\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function setExternalVerifier(address externalVerifier_, bool isAuthorized_) external override onlyOwner {\n        externalVerifiers_[externalVerifier_] = isAuthorized_;\n        emit SetExternalAuthorized(externalVerifier_, isAuthorized_);\n    }\n\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function isExternalVerifier(address externalVerifier_) public view override returns (bool) {\n        return externalVerifiers_[externalVerifier_];\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a verifies in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param verifiedCreator_ address of the authorizer of the token creation\n     * @param tokenId_ This is expected to be 0. As the tokenIds are autogenerated\n     * @param supply_ tokens amount to be minted, not used if 721\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        address verifiedCreator_,\n        uint256 tokenId_,\n        uint256 supply_\n    ) public virtual returns (uint256);\n\n    /**\n     * @notice mint function that should be used by a well known contract that verifies a minter in a different way\n     * @param tokenId_ id of the tokens to be minted, must be an existing token\n     * @param supply_ tokens amount to be minted\n     * @param to_ address of the first receiver\n     * will fail if it's not authorized to min\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintExistingExternalVerifier(\n        uint256 tokenId_,\n        uint256 supply_,\n        address to_,\n        address,\n        uint256 nonce\n    ) external virtual returns (uint256);\n\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/ERC1155/EnigmaNFT1155.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./BaseEnigmaNFT1155.sol\";\nimport \"../utils/AuthorizedMintingNFT.sol\";\nimport \"../utils/AuthorizationBitmap.sol\";\n\n/// @title EnigmaNFT1155\n///\n/// @dev This contract extends from BaseEnigmaNFT1155\n\ncontract EnigmaNFT1155 is BaseEnigmaNFT1155, AuthorizedMintingNFT {\n    using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n\n    AuthorizationBitmap.Bitmap internal processedNonces; // Struct to check that an authorization was not used yet\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) AuthorizedMintingNFT(name, version) {}\n\n    /**\n     * @notice Initialize NFT1155 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the toke base uri\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_\n    ) external initializer {\n        super._initialize(name_, symbol_, tokenURIPrefix_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param nonce nonce of signature\n     * @param sign_ bytes that authorize the minting of this token\n     */\n    function mintNew(\n        string memory tokenURI_,\n        uint256 supply_,\n        uint256 fee_,\n        uint256 nonce,\n        bytes memory sign_\n    ) external {\n        mintNewCustomized(tokenURI_, supply_, fee_, msg.sender, msg.sender, nonce, sign_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ address that will receive the royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param sign_ bytes that authorize the minting of this token\n     */\n    function mintNewCustomized(\n        string memory tokenURI_,\n        uint256 supply_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        bytes memory sign_\n    ) public returns (uint256) {\n        require(\n            !AuthorizationBitmap.isAuthProcessed(processedNonces, nonce),\n            \"EnigmaNFT1155: Nonce for NFTMintingVoucher already used\"\n        );\n        verifySign(tokenURI_, msg.sender, supply_, nonce, sign_, owner());\n        AuthorizationBitmap.setAuthProcessed(processedNonces, nonce);\n        uint256 tokenId = _mintNew(tokenURI_, fee_, rightsHolder_, to_, nonce, msg.sender, _increaseNextId(), supply_);\n        creators[tokenId] = msg.sender;\n        return tokenId;\n    }\n\n    function getCreator(uint256 tokenId) external view virtual override returns (address) {\n        return creators[tokenId];\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a verifies in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param verifiedCreator_ address of the authorizer of the token creation\n     * @param tokenId_ This is expected to be 0. As the tokenIds are autogenerated\n     * @param supply_ tokens amount to be minted, not used if 721\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        address verifiedCreator_,\n        uint256 tokenId_,\n        uint256 supply_\n    ) public virtual override onlyExternalVerifier returns (uint256) {\n        require(tokenId_ == 0, \"EnigmaNFT1155: TokenId is not zero\");\n        uint256 tokenId = _increaseNextId();\n        _mintNew(tokenURI_, fee_, rightsHolder_, to_, nonce, verifiedCreator_, tokenId, supply_);\n        creators[tokenId] = verifiedCreator_;\n        return tokenId;\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that verifies a minter in a different way\n     * @param tokenId_ id of the tokens to be minted, must be an existing token\n     * @param supply_ tokens amount to be minted\n     * @param to_ address of the first receiver\n     * will fail if it's not authorized to min\n     * @param verifiedCreator_ verified address of the original operation to mint\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintExistingExternalVerifier(\n        uint256 tokenId_,\n        uint256 supply_,\n        address to_,\n        address verifiedCreator_,\n        uint256 nonce\n    ) external virtual override onlyExternalVerifier returns (uint256) {\n        _mintExistingNFT(tokenId_, to_, supply_, nonce);\n        require(creators[tokenId_] == verifiedCreator_, \"EnigmaNFT1155: verifiedCreator is not Token Creator\");\n        return tokenId_;\n    }\n}\n"
      },
      "contracts/ERC1155/EnigmaUserToken1155.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./BaseEnigmaNFT1155.sol\";\nimport \"../vault/Vault.sol\";\n\n/// @title EnigmaUserToken1155\n///\n/// @dev This contract extends from BaseEnigmaNFT1155\ncontract EnigmaUserToken1155 is BaseEnigmaNFT1155 {\n    address public operator;\n    bool public autoId;\n    address public bundledItemsRecipient;\n\n    event OperatorChanged(address indexed newOperator);\n    event BundledItemsRecipientChanged(address indexed newBundledItemsrecipient);\n    event ItemsBundled(uint256 amountOfTokensCreated, uint256[] ids, uint256[] amounts);\n\n    struct MintItem {\n        uint256 tokenId;\n        bool mintNew;\n        address recipient;\n        uint256 amount;\n        uint256 fee;\n        string uri;\n    }\n\n    struct MintItemWithRightsHolder {\n        MintItem basicMintItem;\n        address rightsHolder;\n    }\n\n    modifier onlyOwnerOrOperator() {\n        require(msg.sender == owner() || msg.sender == operator, \"Not owner nor operator\");\n        _;\n    }\n\n    /// oz-upgrades-unsafe-allow constructor\n    // solhint-disable-next-line\n    constructor() initializer {}\n\n    /**\n     * @notice Initialize NFT1155 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the token base uri\n     * @param operator_ that will be able to mint tokens on behalf the owner\n     * @param transferGatekeeperBeacon_ TransferGatekeeper beacon\n     * @param autoId_ True if token id will be automatically assigned when minting\n     * @param bundledItemsRecipient_ Adress that will receive the tokens to be bundled. This ideally should lock them.\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_,\n        address operator_,\n        address transferGatekeeperBeacon_,\n        bool autoId_,\n        address bundledItemsRecipient_\n    ) external initializer {\n        super._initialize(name_, symbol_, tokenURIPrefix_);\n        operator = operator_;\n        transferGatekeeperBeacon = IBeacon(transferGatekeeperBeacon_);\n        autoId = autoId_;\n        bundledItemsRecipient = bundledItemsRecipient_;\n    }\n\n    function batchMint(MintItem[] calldata toMint) public onlyOwnerOrOperator {\n        uint256 length = toMint.length;\n        address rightsHolder_ = owner();\n\n        for (uint256 index = 0; index < length; index++) {\n            _mintItem(toMint[index], rightsHolder_);\n        }\n    }\n\n    function batchMintWithRightsHolder(MintItemWithRightsHolder[] calldata toMint) public onlyOwnerOrOperator {\n        uint256 length = toMint.length;\n\n        for (uint256 index = 0; index < length; index++) {\n            _mintItem(toMint[index].basicMintItem, toMint[index].rightsHolder);\n        }\n    }\n\n    /**\n     * @notice This function bundles (exchanges) some tokens in exchange for a new one. All the tokens\n     *         must belong to the same collection (this one)\n     * @dev This operation can only be performed by the owner or the operator.\n     *\n     * @param tokensOwner The one the tokens are going to be taken from\n     * @param ids TokenIds to be locked in exchange for the new one\n     * @param amounts For each token to be exchanged\n     * @param toMint new tokens to be generated and minted with the owner set as right holder\n     */\n    function bundle(\n        address tokensOwner,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        MintItem[] calldata toMint\n    ) external onlyOwnerOrOperator {\n        super.safeBatchTransferFrom(tokensOwner, bundledItemsRecipient, ids, amounts, \"\");\n        batchMint(toMint);\n        emit ItemsBundled(toMint.length, ids, amounts);\n    }\n\n    /**\n     * @notice This function bundles (exchanges) some tokens in exchange for a new one. All the tokens\n     *         must belong to the same collection (this one)\n     * @dev This operation can only be performed by the owner or the operator.\n     *\n     * @param tokensOwner The one the tokens are going to be taken from\n     * @param ids TokenIds to be locked in exchange for the new one\n     * @param amounts For each token to be exchanged\n     * @param toMint new token to be generated and minted to the owner\n     */\n    function bundleWithRightsHolder(\n        address tokensOwner,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        MintItemWithRightsHolder[] calldata toMint\n    ) external onlyOwnerOrOperator {\n        super.safeBatchTransferFrom(tokensOwner, bundledItemsRecipient, ids, amounts, \"\");\n        batchMintWithRightsHolder(toMint);\n        emit ItemsBundled(toMint.length, ids, amounts);\n    }\n\n    /**\n     * @dev Mints a new NFT if it doesn't exist otherwise uses the existing one\n     */\n    function _mintItem(MintItem calldata item, address rightsHolder_) internal {\n        if (item.mintNew) {\n            _mintNew(item.uri, item.fee, rightsHolder_, item.recipient, 0, owner(), item.tokenId, item.amount);\n        } else {\n            _mintExistingNFT(item.tokenId, item.recipient, item.amount, 0);\n        }\n    }\n\n    /**\n     * @notice Checks if operator contract has registered the passed signer address as a valid signer\n     * @dev If Vault were to get refactored to avoid using an ACL then we wouldn't need to\n     * get the SIGNER_ROLE hash, because we would assume that is the only possible role\n     * @param signer address of the sellOrder signer.\n     * @return Boolean representing if signer is registered as valid or not\n     */\n    function _hasOperatorPermission(address signer) internal view returns (bool) {\n        if (operator == address(0)) return false;\n        Vault operator_ = Vault(operator);\n        bytes32 signerRole = operator_.SIGNER_ROLE();\n        return operator_.hasRole(signerRole, signer);\n    }\n\n    /**\n     * @notice For compatibility reasons this method is kept although it always returns the contract owner\n     */\n    function getCreator(uint256) external view virtual override returns (address) {\n        return owner();\n    }\n\n    /**\n     * @notice Let's the owner to update the operator\n     * @param newOperator to set\n     */\n    function setOperator(address newOperator) external onlyOwner {\n        operator = newOperator;\n        emit OperatorChanged(newOperator);\n    }\n\n    /**\n     * @notice Allows changing the bundled NFTs recipient to another address\n     * @param bundledItemsRecipient_ New recipient. Cannot be 0x0 address otherwise will fail when transfering\n     */\n    function setBundledItemsRecipient(address bundledItemsRecipient_) external onlyOwnerOrOperator {\n        require(bundledItemsRecipient_ != address(0x0), \"Cannot be 0x0 address\");\n        bundledItemsRecipient = bundledItemsRecipient_;\n        emit BundledItemsRecipientChanged(bundledItemsRecipient);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param tokenId_ id of the token to be created, it should be 0 if autoId is true\n     */\n    function mintNew(\n        string memory tokenURI_,\n        uint256 supply_,\n        uint256 fee_,\n        uint256 tokenId_\n    ) external onlyOwnerOrOperator {\n        _mintNew(tokenURI_, fee_, msg.sender, msg.sender, 0, owner(), tokenId_, supply_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ address that will receive the royalties\n     * @param to_ address of the first receiver\n     * @param tokenId_ id of the token to be created, it should be 0 if autoId is true\n     */\n    function mintNewCustomized(\n        string memory tokenURI_,\n        uint256 supply_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 tokenId_\n    ) external onlyOwnerOrOperator returns (uint256) {\n        return _mintNew(tokenURI_, fee_, rightsHolder_, to_, 0, owner(), tokenId_, supply_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ address that will receive the royalties\n     * @param recipient address of the first receiver\n     * @param tokenId_ id of the token to be created, it should be 0 if autoId is true\n     */\n    function _mintNew(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address recipient,\n        uint256 nonce,\n        address creator_,\n        uint256 tokenId_,\n        uint256 supply_\n    ) internal virtual override returns (uint256) {\n        autoId\n            ? require(tokenId_ == 0, \"EnigmaUserToken1155: New token id specified but autoId is active\")\n            : require(!super._exists(tokenId_), \"EnigmaUserToken1155: TokenId exists already\");\n        uint256 tokenId = autoId ? _increaseNextId() : tokenId_;\n        super._mintNew(tokenURI_, fee_, rightsHolder_, recipient, nonce, creator_, tokenId, supply_);\n        return tokenId;\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a verifies in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param verifiedCreator_ address of the authorizer of the token creation\n     * @param tokenId_ This is expected to be 0. As the tokenIds are autogenerated\n     * @param supply_ tokens amount to be minted, not used if 721\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        address verifiedCreator_,\n        uint256 tokenId_,\n        uint256 supply_\n    ) public virtual override onlyExternalVerifier returns (uint256) {\n        // If verifiedCreator (order signer) is the owner address, operator address, or has permission by Vault\n        // then they can mint\n        require(\n            verifiedCreator_ == owner() || verifiedCreator_ == operator || _hasOperatorPermission(verifiedCreator_),\n            \"EnigmaUserToken1155: Not authorized to mint\"\n        );\n        return _mintNew(tokenURI_, fee_, rightsHolder_, to_, nonce, verifiedCreator_, tokenId_, supply_);\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that verifies a minter in a different way\n     * @param tokenId_ id of the tokens to be minted, must be an existing token\n     * @param supply_ tokens amount to be minted\n     * @param to_ address of the first receiver\n     * will fail if it's not authorized to min\n     * @param verifiedCreator_ verified address of the original operation to mint\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintExistingExternalVerifier(\n        uint256 tokenId_,\n        uint256 supply_,\n        address to_,\n        address verifiedCreator_,\n        uint256 nonce\n    ) external virtual override onlyExternalVerifier returns (uint256) {\n        // If verifiedCreator (order signer) is the owner address, operator address, or has permission by Vault\n        // then they can mint\n        require(\n            verifiedCreator_ == owner() || verifiedCreator_ == operator || _hasOperatorPermission(verifiedCreator_),\n            \"EnigmaUserToken1155: Not authorized to mint\"\n        );\n        _mintExistingNFT(tokenId_, to_, supply_, nonce);\n        return tokenId_;\n    }\n}\n"
      },
      "contracts/ERC721/BaseEnigmaNFT721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721BurnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/proxy/IBeacon.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"../interfaces/ITransferGatekeeper.sol\";\nimport \"../interfaces/IRoyaltyAwareNFT.sol\";\nimport \"../interfaces/IExternalVerifiedMinting.sol\";\nimport \"../utils/MintNFTEvent.sol\";\n\n/// @title BaseEnigmaNFT721\n///\n/// @dev This contract is a ERC721 burnable and upgradable based in openZeppelin v3.4.0.\n///         Be careful when upgrade, you must respect the same storage.\n\nabstract contract BaseEnigmaNFT721 is\n    IRoyaltyAwareNFT,\n    ERC721BurnableUpgradeable,\n    OwnableUpgradeable,\n    MintNFTEvent,\n    IExternalVerifiedMinting\n{\n    using SafeMathUpgradeable for uint256;\n\n    /* Storage */\n    //mapping for token royaltyFee\n    mapping(uint256 => uint256) private _royaltyFee;\n\n    //mapping for token creator\n    mapping(uint256 => address) internal _creator;\n\n    //token id counter, increase by 1 for each new mint\n    uint256 public tokenCounter;\n\n    // Transfer Gatekeeper with logic to allow token transfers\n    IBeacon public transferGatekeeperBeacon;\n\n    //mapping for token rights holder, the ones that will receive royalties\n    mapping(uint256 => address) private _rightsHolders;\n\n    mapping(address => bool) private externalVerifiers_;\n\n    bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;\n\n    /* events */\n    event URI(string value, uint256 indexed id);\n    event TokenBaseURI(string value);\n\n    event SetExternalAuthorized(address externalVerifiers_, bool isAuthorized_);\n\n    /* functions */\n\n    modifier onlyExternalVerifier() {\n        require(isExternalVerifier(msg.sender), \"BaseEnigmaNFT721: Not external verifier\");\n        _;\n    }\n\n    /**\n     * @notice Initialize NFT721 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the toke base uri\n     */\n    function _initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_\n    ) internal initializer {\n        __ERC721_init(name_, symbol_);\n        __ERC721Burnable_init();\n        __Ownable_init();\n\n        tokenCounter = 1;\n        _setBaseURI(tokenURIPrefix_);\n        _registerInterface(_INTERFACE_ID_ERC2981);\n    }\n\n    /// oz-upgrades-unsafe-allow constructor\n    // solhint-disable-next-line\n    constructor() initializer {}\n\n    /// @notice Called with the sale price to determine how much royalty\n    //          is owed and to whom.\n    /// @param _tokenId - the NFT asset queried for royalty information\n    /// @param _salePrice - the sale price of the NFT asset specified by _tokenId\n    /// @return receiver - address of who should be sent the royalty payment\n    /// @return royaltyAmount - the royalty payment amount for _salePrice\n    function royaltyInfo(uint256 _tokenId, uint256 _salePrice)\n        external\n        view\n        virtual\n        override\n        returns (address receiver, uint256 royaltyAmount)\n    {\n        return (rightsHolder(_tokenId), _salePrice.mul(_royaltyFee[_tokenId]).div(1000));\n    }\n\n    /**\n     * @notice Get the creator of given tokenID.\n     * @param tokenId ID of the Token.\n     * @return creator of given ID.\n     */\n    function getCreator(uint256 tokenId) public view virtual override returns (address) {\n        return _creator[tokenId];\n    }\n\n    /**\n     * @notice Get the rights holder (the one to receive royalties) of given tokenID.\n     * @param tokenId ID of the Token.\n     * @return creator of given ID.\n     */\n    function rightsHolder(uint256 tokenId) public view virtual override returns (address) {\n        address rightsHolder_ = _rightsHolders[tokenId];\n        return rightsHolder_ == address(0x0) ? getCreator(tokenId) : rightsHolder_;\n    }\n\n    /**\n     * @notice Updates the rights holder for a specific tokenId\n     * @param tokenId ID of the Token.\n     * @param newRightsHolder new rights holderof given ID.\n     * @dev Rights holder should only be set by the token creator\n     */\n    function setRightsHolder(uint256 tokenId, address newRightsHolder) external override {\n        require(msg.sender == this.getCreator(tokenId), \"Only creator\");\n        _rightsHolders[tokenId] = newRightsHolder;\n    }\n\n    /**\n     * @notice Internal function to set the base URI for all token IDs. It is\n     * automatically added as a prefix to the value returned in {tokenURI},\n     * or to the token ID if {tokenURI} is empty.\n     * @param baseURI_ the new base uri\n     */\n    function _setBaseURI(string memory baseURI_) internal virtual override {\n        super._setBaseURI(baseURI_);\n        emit TokenBaseURI(baseURI_);\n    }\n\n    /**\n     * @notice Internal function to set the token URI for a given token.\n     * Reverts if the token ID does not exist.\n     * @param tokenId uint256 ID of the token to set its URI\n     * @param _tokenURI string URI to assign\n     */\n    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual override {\n        super._setTokenURI(tokenId, _tokenURI);\n        emit URI(_tokenURI, tokenId);\n    }\n\n    /**\n     * @notice call safe mint function and set token creator and royalty fee\n     */\n    function _safeMint(\n        address to_,\n        uint256 tokenId_,\n        uint256 fee_,\n        address rightsHolder_\n    ) internal virtual {\n        _royaltyFee[tokenId_] = fee_;\n        _rightsHolders[tokenId_] = rightsHolder_;\n        super._safeMint(to_, tokenId_, \"\");\n    }\n\n    /**\n     * @notice call transfer fucntion after check transferGatekeeper allowance\n     */\n    function _transfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual override {\n        bytes memory allData = abi.encode(\"721\", tokenId);\n\n        ITransferGatekeeper transferGatekeeper = ITransferGatekeeper(transferGatekeeperBeacon.implementation());\n        require(transferGatekeeper.canTransfer(from, to, _msgSender(), allData), \"Transfer not approved\");\n        super._transfer(from, to, tokenId);\n    }\n\n    /**\n     * @notice external function to set the base URI for all token IDs\n     * @param baseURI_ the new base uri\n     */\n    function setBaseURI(string memory baseURI_) external onlyOwner {\n        _setBaseURI(baseURI_);\n    }\n\n    /**\n     * @notice Set a transferGatekeeperBeacon that points to the gatekeeper implementation\n     * @param transferGatekeeperBeacon_ The IBeacon instance\n     */\n    function setTransferGatekeeperBeacon(IBeacon transferGatekeeperBeacon_) external onlyOwner {\n        transferGatekeeperBeacon = transferGatekeeperBeacon_;\n    }\n\n    /**\n     * @notice Allows to batchUpdate the royalty fees for several tokens\n     * @dev This function doesn't perform any checks to make it cheaper, be careful when invoking it\n     * @param tokenIds Tokens to update royalty from\n     * @param newRoyaltyFees New royalty fees. They must match with the tokenIds\n     */\n    function batchUpdateRoyaltyFees(uint256[] calldata tokenIds, uint256[] calldata newRoyaltyFees) external onlyOwner {\n        uint256 length = tokenIds.length;\n\n        for (uint256 index; index < length; ) {\n            _royaltyFee[tokenIds[index]] = newRoyaltyFees[index];\n            ++index;\n        }\n    }\n\n    /**\n     * @notice Kind of like an initializer for the upgrade where we support ERC2981\n     * @dev This is left unprotected as it is idempotent and it has no parameters\n     */\n    function declareERC2981Interface() external override {\n        _registerInterface(_INTERFACE_ID_ERC2981);\n    }\n\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function setExternalVerifier(address externalVerifier_, bool isAuthorized_) external override onlyOwner {\n        externalVerifiers_[externalVerifier_] = isAuthorized_;\n        emit SetExternalAuthorized(externalVerifier_, isAuthorized_);\n    }\n\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function isExternalVerifier(address externalVerifier_) public view override returns (bool) {\n        return externalVerifiers_[externalVerifier_];\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param to_ address of the creator of the token\n     * @return id of the token\n     */\n    function _mintNew(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        address creator_\n    ) internal returns (uint256) {\n        uint256 newItemId = tokenCounter;\n        tokenCounter = tokenCounter + 1;\n        _safeMint(to_, newItemId, fee_, rightsHolder_);\n        _setTokenURI(newItemId, tokenURI_);\n        emit MintNewNFT(newItemId, creator_, to_, tokenURI_, 1, fee_, rightsHolder_, nonce);\n        return newItemId;\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a minter in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param verifiedCreator_ actual sender of the mint operation(creator), verified by the external verifier\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        address verifiedCreator_,\n        uint256 nonce\n    ) public virtual onlyExternalVerifier returns (uint256) {\n        return _mintNew(tokenURI_, fee_, rightsHolder_, to_, nonce, verifiedCreator_);\n    }\n\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/ERC721/EnigmaNFT721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./BaseEnigmaNFT721.sol\";\nimport \"../utils/AuthorizedMintingNFT.sol\";\nimport \"../utils/AuthorizationBitmap.sol\";\n\n/// @title EnigmaNFT721\n///\n/// @dev This contract extends from BaseEnigmaNFT721\n\ncontract EnigmaNFT721 is BaseEnigmaNFT721, AuthorizedMintingNFT {\n    AuthorizationBitmap.Bitmap internal processedNonces; // Struct to check that an authorization was not used yet\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) AuthorizedMintingNFT(name, version) {}\n\n    /**\n     * @notice Initialize NFT1155 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the toke base uri\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_\n    ) external initializer {\n        super._initialize(name_, symbol_, tokenURIPrefix_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param nonce nonce of signature\n     * @param sign_ bytes that authorize the minting of this token\n     */\n    function mintNew(\n        string memory tokenURI_,\n        uint256 fee_,\n        uint256 nonce,\n        bytes memory sign_\n    ) external returns (uint256) {\n        return mintNewCustomized(tokenURI_, fee_, msg.sender, msg.sender, nonce, sign_);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param nonce nonce of signature\n     * @param sign_ bytes that authorize the minting of this token\n     */\n    function mintNewCustomized(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        uint256 nonce,\n        bytes memory sign_\n    ) public returns (uint256) {\n        require(\n            !AuthorizationBitmap.isAuthProcessed(processedNonces, nonce),\n            \"EnigmaNFT721: Nonce for NFTMintingVoucher already used\"\n        );\n        verifySign(tokenURI_, msg.sender, 1, nonce, sign_, owner());\n        AuthorizationBitmap.setAuthProcessed(processedNonces, nonce);\n        uint256 tokenId = _mintNew(tokenURI_, fee_, rightsHolder_, to_, nonce, msg.sender);\n        _creator[tokenId] = msg.sender;\n        return tokenId;\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a minter in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param verifiedAccount_ actual sender of the mint operation, verified by the external verifier\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        address verifiedAccount_,\n        uint256 nonce\n    ) public virtual override returns (uint256) {\n        uint256 tokenId = super.mintNewExternalVerifier(tokenURI_, fee_, rightsHolder_, to_, verifiedAccount_, nonce);\n        _creator[tokenId] = verifiedAccount_;\n        return tokenId;\n    }\n}\n"
      },
      "contracts/ERC721/EnigmaTicketCollection721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./EnigmaUserToken721.sol\";\n\ncontract EnigmaTicketCollection721 is EnigmaUserToken721 {\n    uint256 private _disableTransfersStartDate;\n    uint256 private _disableTransfersEndDate;\n    mapping(uint256 => bool) public isTokenDisabled;\n\n    /**\n     * @notice Initialize TicketCollection NFT721 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the token base uri\n     * @param operator_ that will be able to mint tokens on behalf the owner\n     * @param transferGatekeeperBeacon_ TransferGatekeeper beacon\n     * @param disableTransfersStartDate_ the date transfers are no longer allowed\n     * @param disableTransfersEndDate_ the date transfers are resumed\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_,\n        address operator_,\n        address transferGatekeeperBeacon_,\n        uint256 disableTransfersStartDate_,\n        uint256 disableTransfersEndDate_\n    ) public initializer {\n        super.initialize(name_, symbol_, tokenURIPrefix_, operator_, transferGatekeeperBeacon_);\n        _disableTransfersStartDate = disableTransfersStartDate_;\n        _disableTransfersEndDate = disableTransfersEndDate_;\n    }\n\n    function setDisableTransfersStartDate(uint256 newStartDate) external onlyOwnerOrOperator {\n        _disableTransfersStartDate = newStartDate;\n    }\n\n    function setDisableTransfersEndDate(uint256 newStartDate) external onlyOwnerOrOperator {\n        _disableTransfersEndDate = newStartDate;\n    }\n\n    function setTokenDisabled(uint256 tokenId, bool disabled) external onlyOwnerOrOperator {\n        isTokenDisabled[tokenId] = disabled;\n    }\n\n    /**\n     * @notice overriden hook to allow disabling transfers.\n     *\n     * @param from the issuer address\n     * @param to the receiver address\n     * @param tokenId of token to transfer\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId\n    ) internal virtual override {\n        require(!isTokenDisabled[tokenId], \"EnigmaTicketCollection721: Token has been disabled\");\n        if (_disableTransfersStartDate != 0) {\n            require(\n                block.timestamp < _disableTransfersStartDate ||\n                    (_disableTransfersEndDate != 0 && block.timestamp > _disableTransfersEndDate),\n                \"EnigmaTicketCollection721: Transfers have been disabled\"\n            );\n        }\n        super._beforeTokenTransfer(from, to, tokenId);\n    }\n\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/ERC721/EnigmaUserToken721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./BaseEnigmaNFT721.sol\";\nimport \"../vault/Vault.sol\";\n\n/// @title EnigmaUserToken721\n///\n/// @dev This contract extends from BaseEnigmaNFT721\n\ncontract EnigmaUserToken721 is BaseEnigmaNFT721 {\n    address public operator;\n\n    event OperatorChanged(address indexed newOperator);\n\n    modifier onlyOwnerOrOperator() {\n        require(msg.sender == owner() || msg.sender == operator, \"Not owner nor operator\");\n        _;\n    }\n\n    /// oz-upgrades-unsafe-allow constructor\n    // solhint-disable-next-line\n    constructor() initializer {}\n\n    /**\n     * @notice Initialize NFT721 contract.\n     *\n     * @param name_ the token name\n     * @param symbol_ the token symbol\n     * @param tokenURIPrefix_ the token base uri\n     * @param operator_ that will be able to mint tokens on behalf the owner\n     * @param transferGatekeeperBeacon_ TransferGatekeeper beacon\n     */\n    function initialize(\n        string memory name_,\n        string memory symbol_,\n        string memory tokenURIPrefix_,\n        address operator_,\n        address transferGatekeeperBeacon_\n    ) public initializer {\n        super._initialize(name_, symbol_, tokenURIPrefix_);\n        operator = operator_;\n        transferGatekeeperBeacon = IBeacon(transferGatekeeperBeacon_);\n    }\n\n    /**\n     * @notice For compatibility reasons this method is kept although it always returns the contract owner\n     */\n    function getCreator(uint256) public view virtual override returns (address) {\n        return owner();\n    }\n\n    /**\n     * @notice Let's the owner to update the operator\n     * @param newOperator to set\n     */\n    function setOperator(address newOperator) external onlyOwner {\n        operator = newOperator;\n        emit OperatorChanged(newOperator);\n    }\n\n    /**\n     * @notice Checks if operator contract has registered the passed signer address as a valid signer\n     * @dev If Vault were to get refactored to avoid using an ACL then we wouldn't need to\n     * get the SIGNER_ROLE hash, because we would assume that is the only possible role\n     * @param signer address of the sellOrder signer.\n     * @return Boolean representing if signer is registered as valid or not\n     */\n    function _hasOperatorPermission(address signer) internal view returns (bool) {\n        if (operator == address(0)) return false;\n        Vault operator_ = Vault(operator);\n        bytes32 signerRole = operator_.SIGNER_ROLE();\n        return operator_.hasRole(signerRole, signer);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     */\n    function mintNew(string memory tokenURI_, uint256 fee_) external onlyOwnerOrOperator returns (uint256) {\n        _mintNew(tokenURI_, fee_, msg.sender, msg.sender, 0, msg.sender);\n    }\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     */\n    function mintNewCustomized(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_\n    ) public onlyOwnerOrOperator returns (uint256) {\n        _mintNew(tokenURI_, fee_, rightsHolder_, to_, 0, msg.sender);\n    }\n\n    /**\n     * @notice mint function that should be used by a well known contract that authorizes a minter in a different way\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     * @param rightsHolder_ account that will receive royalties\n     * @param to_ address of the first receiver\n     * @param verifiedAccount_ actual sender of the mint operation, verified by the external verifier\n     * @param nonce nonce of signature\n     * @return Id of the newly created token\n     */\n    function mintNewExternalVerifier(\n        string memory tokenURI_,\n        uint256 fee_,\n        address rightsHolder_,\n        address to_,\n        address verifiedAccount_,\n        uint256 nonce\n    ) public virtual override onlyExternalVerifier returns (uint256) {\n        // If verifiedAccount (order signer) is the owner address, operator address, or has permission by Vault\n        // then they can mint\n        require(\n            owner() == verifiedAccount_ || verifiedAccount_ == operator || _hasOperatorPermission(verifiedAccount_),\n            \"EnigmaUserToken721: Not authorized to mint\"\n        );\n        return super.mintNewExternalVerifier(tokenURI_, fee_, rightsHolder_, to_, verifiedAccount_, nonce);\n    }\n\n    uint256[49] private __gap;\n}\n"
      },
      "contracts/interfaces/IERC2981.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\n///\n/// @dev Interface for the NFT Royalty Standard\n///\ninterface IERC2981 is IERC165Upgradeable {\n    /// @notice Called with the sale price to determine how much royalty\n    //          is owed and to whom.\n    /// @param _tokenId - the NFT asset queried for royalty information\n    /// @param _salePrice - the sale price of the NFT asset specified by _tokenId\n    /// @return receiver - address of who should be sent the royalty payment\n    /// @return royaltyAmount - the royalty payment amount for _salePrice\n    function royaltyInfo(uint256 _tokenId, uint256 _salePrice)\n        external\n        view\n        virtual\n        returns (address receiver, uint256 royaltyAmount);\n}\n"
      },
      "contracts/interfaces/IExternalVerifiedMinting.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nabstract contract IExternalVerifiedMinting {\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function setExternalVerifier(address externalVerifier_, bool isAuthorized_) external virtual;\n\n    /**\n     * @notice Add or remove an external authorizer\n     * @dev This function is idempotent and unprotected.\n     */\n    function isExternalVerifier(address externalVerifier_) public view virtual returns (bool);\n}\n"
      },
      "contracts/interfaces/IRoyaltyAwareNFT.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"./IERC2981.sol\";\n\ninterface IRoyaltyAwareNFT is IERC2981 {\n    /**\n     * @notice Get the creator of given tokenID.\n     * @param tokenId ID of the Token.\n     * @return creator of given ID.\n     */\n    function getCreator(uint256 tokenId) external view virtual returns (address);\n\n    /**\n     * @notice Get the rights holder (the one to receive royalties) of given tokenID.\n     * @param tokenId ID of the Token.\n     * @return rights holder of given ID.\n     */\n    function rightsHolder(uint256 tokenId) external view virtual returns (address);\n\n    /**\n     * @notice Updates the rights holder for a specific tokenId\n     * @param tokenId ID of the Token.\n     * @param newRightsHolder new rights holderof given ID.\n     * @dev Rights holder should only be set by the token creator\n     */\n    function setRightsHolder(uint256 tokenId, address newRightsHolder) external virtual;\n\n    /**\n     * @notice Kind of like an initializer for the upgrade where we support ERC2981\n     */\n    function declareERC2981Interface() external virtual;\n}\n"
      },
      "contracts/interfaces/ITransferGatekeeper.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/// @title ITransferGatekeeper\n/// @notice an interface that allows an asset transfer to be guard.\n\ninterface ITransferGatekeeper {\n    /**\n     * @param _from the address that owns what's being transfered\n     * @param _to the address that would receive what's being transfered\n     * @param _proxy the address that wants to transfer\n     * @param _data any other aditional data that might be relevant to allow/block the transfer\n     * @dev Returns true if this transfer is allowed under current context\n     */\n    function canTransfer(\n        address _from,\n        address _to,\n        address _proxy,\n        bytes memory _data\n    ) external view returns (bool);\n}\n"
      },
      "contracts/interfaces/ITransferProxy.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\ninterface ITransferProxy {\n    function erc721safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    function erc1155safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external;\n\n    function erc20safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    ) external;\n}\n"
      },
      "contracts/interfaces/IWhitelist.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/// All the whitelists logics that want to be used in the NFTs contracts must implement this interface.\n///\n/// By implementing this interface, can be transfered.\n///\n\ninterface IWhitelist {\n    /**\n     * @param _who the address that wants to transfer a NFT\n     * @dev Returns true if address has permission to transfer a NFT\n     */\n    function canTransfer(address _who) external view returns (bool);\n}\n"
      },
      "contracts/interfaces/IWhitelistHandler.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\nimport \"./IWhitelist.sol\";\n\n/// @title IWhitelistHandler\n\ninterface IWhitelistHandler {\n    /**\n     * @param _whitelist the contract that implements IWhitelist\n     */\n    function setWhitelist(IWhitelist _whitelist) external;\n}\n"
      },
      "contracts/interfaces/IWyvernProxyRegistry.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/**\n * @title IWyvernProxyRegistry\n * @author Wyvern Protocol Developers\n */\ninterface IWyvernProxyRegistry {\n    /**\n     * Returns The Wyvern Proxy for the given owner\n     * @param owner the owner of the Proxy\n     * @dev based on Apr '22 https://github.com/wyvernprotocol/wyvern-v3\n     */\n    function proxies(address owner) external view returns (address);\n}\n"
      },
      "contracts/market/EnigmaMarket.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721HolderUpgradeable.sol\";\nimport \"../interfaces/ITransferProxy.sol\";\nimport \"./NFTMarketReserveAuction.sol\";\nimport \"./TradeV4.sol\";\n\n/// @title EnigmaMarket\n///\n/// @dev This contract is a Transparent Upgradable based in openZeppelin v3.4.0.\n///         Be careful when upgrade, you must respect the same storage.\n\ncontract EnigmaMarket is\n    TradeV4, // Direct sales\n    ERC721HolderUpgradeable, // Make sure the contract is able to use its\n    NFTMarketReserveAuction\n{\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) TradeV4(name, version) {}\n\n    /**\n     * @notice Called once to configure the contract after the initial proxy deployment.\n     * @dev This farms the initialize call out to inherited contracts as needed to initialize mutable variables.\n     * @param _transferProxy the proxy from wich all NFT transfers are gonna be processed from.\n     * @param _enigmaNFT721Address Enigma ERC721 NFT proxy.\n     * @param _enigmaNFT1155Address Enigma ERC1155 NFT proxy.\n     * @param _custodialAddress The address on wich NFTs are gonna be kept during Fiat Trades.\n     * @param _minDuration The min duration for auctions, in seconds.\n     * @param _maxDuration The max duration for auctions, in seconds.\n     * @param _minIncrementPermille The minimum required when making an offer or placing a bid. Ej: 100 => 0.1 => 10%\n     */\n    function fullInitialize(\n        ITransferProxy _transferProxy,\n        address _enigmaNFT721Address,\n        address _enigmaNFT1155Address,\n        address _custodialAddress,\n        uint256 _minDuration,\n        uint256 _maxDuration,\n        uint16 _minIncrementPermille\n    ) external initializer {\n        initializeTradeV4(_transferProxy, _enigmaNFT721Address, _enigmaNFT1155Address, _custodialAddress);\n        __Ownable_init();\n        __ReentrancyGuard_init();\n        _initializeNFTMarketAuction();\n        _initializeNFTMarketReserveAuction(_minDuration, _maxDuration);\n        _initializeNFTMarketCore(_minIncrementPermille);\n    }\n\n    /**\n     * @notice Called once to configure the contract after the initial proxy deployment.\n     * @dev as we are updating an already deployed contracts, legacy vars don't need init.\n     * @param _minDuration The min duration for auctions, in seconds.\n     * @param _maxDuration The max duration for auctions, in seconds.\n     */\n    function upgradeInitialize(uint256 _minDuration, uint256 _maxDuration) external onlyOwner {\n        _initializeNFTMarketAuction();\n        _initializeNFTMarketReserveAuction(_minDuration, _maxDuration);\n    }\n\n    function getPlatformTreasury() public view returns (address payable) {\n        // TODO: review if we don't need a new field for collecting fees\n        return payable(owner());\n    }\n\n    /**\n     * @inheritdoc NFTMarketCore\n     */\n    function _transferFromEscrow(\n        address nftContract,\n        uint256 tokenId,\n        address recipient\n    ) internal virtual override {\n        // As we are transfering through our own market, there's no need to go by transferProxy\n        IERC721(nftContract).transferFrom(address(this), recipient, tokenId);\n    }\n\n    /**\n     * @inheritdoc NFTMarketCore\n     */\n    function _transferToEscrow(address nftContract, uint256 tokenId) internal virtual override {\n        safeTransferFrom(AssetType.ERC721, msg.sender, address(this), nftContract, tokenId, 1);\n    }\n\n    /**\n     * @dev Be careful when invoking this function as reentrancy guard should be put in place\n     */\n    // slither-disable-next-line reentrancy-eth\n    function _distFunds(\n        address nftContract,\n        uint256 tokenId,\n        uint256 amount,\n        address payable seller,\n        uint256 sellerFeesPerMille,\n        uint256 buyerFeesPerMille\n    )\n        internal\n        override\n        returns (\n            uint256 platformFee,\n            uint256 royaltyFee,\n            uint256 assetFee\n        )\n    {\n        // Disable slither warning because it's only invoked from functions with nonReentrant checks\n        FeeDistributionData memory feeDistributionData =\n            getFees(amount, nftContract, tokenId, sellerFeesPerMille, buyerFeesPerMille, seller);\n        _sendValueWithFallbackWithdraw(\n            getPlatformTreasury(),\n            feeDistributionData.fees.platformFee,\n            SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT\n        );\n\n        if (feeDistributionData.toRightsHolder > 0) {\n            _sendValueWithFallbackWithdraw(\n                payable(feeDistributionData.rightsHolder),\n                feeDistributionData.toRightsHolder,\n                SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT\n            );\n        }\n\n        if (feeDistributionData.toSeller > 0) {\n            _sendValueWithFallbackWithdraw(seller, feeDistributionData.toSeller, SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT);\n        }\n\n        return (\n            feeDistributionData.fees.platformFee,\n            feeDistributionData.fees.royaltyFee,\n            feeDistributionData.fees.assetFee\n        );\n    }\n\n    /**\n     * @notice Creates an auction for the given NFT.\n     * The NFT is held in escrow until the auction is finalized or canceled.\n     * buyer and seller fees are locked at creation time\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @param duration seconds for how long an auction lasts for once the first bid has been received.\n     * @param reservePrice The initial reserve price for the auction.\n     */\n    function createReserveAuctionFor(\n        address nftContract,\n        uint256 tokenId,\n        uint256 duration,\n        uint256 reservePrice,\n        uint256 amount,\n        PlatformFees calldata platformFees\n    ) internal override {\n        verifyPlatformFeesSignature(platformFees, owner());\n        NFTMarketReserveAuction.createReserveAuctionFor(\n            nftContract,\n            tokenId,\n            duration,\n            reservePrice,\n            amount,\n            platformFees\n        );\n    }\n\n    /*********************\n     ** PUBLIC FUNCTIONS *\n     *********************/\n\n    /**\n     * @notice Creates an auction for the given NFT.\n     * The NFT is held in escrow until the auction is finalized or canceled.\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @param duration seconds for how long an auction lasts for once the first bid has been received.\n     * @param reservePrice The initial reserve price for the auction.\n     */\n    function createReserveAuction(\n        address nftContract,\n        uint256 tokenId,\n        uint256 duration,\n        uint256 reservePrice,\n        PlatformFees calldata platformFees\n    ) external nonReentrant onlyValidAuctionConfig(reservePrice) {\n        // get the amount, including buyer fees for this reserve price\n        uint256 amount = applyBuyerFee(reservePrice, platformFees.buyerFeePermille);\n        createReserveAuctionFor(nftContract, tokenId, duration, reservePrice, amount, platformFees);\n    }\n}\n"
      },
      "contracts/market/NFTMarketAuction.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.7.6;\n\n/// @dev Taken from https://github.com/f8n/fnd-protocol/tree/v2.0.3\n\n/**\n * @title An abstraction layer for auctions.\n * @dev This contract can be expanded with reusable calls and data as more auction types are added.\n */\nabstract contract NFTMarketAuction {\n    /**\n     * @dev A global id for auctions of any type.\n     */\n    uint256 private nextAuctionId;\n\n    /**\n     * @notice Called once to configure the contract after the initial proxy deployment.\n     * @dev This sets the initial auction id to 1, making the first auction cheaper\n     * and id 0 represents no auction found.\n     */\n    function _initializeNFTMarketAuction() internal {\n        nextAuctionId = 1;\n    }\n\n    /**\n     * @notice Returns id to assign to the next auction.\n     */\n    function _getNextAndIncrementAuctionId() internal returns (uint256) {\n        // AuctionId cannot overflow 256 bits.\n        return nextAuctionId++;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[1000] private __gap;\n}\n"
      },
      "contracts/market/NFTMarketCore.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.7.6;\n\n/// @dev Taken from https://github.com/f8n/fnd-protocol/tree/v2.0.3\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"./TradeV4.sol\";\n\n/**\n * @title A place for common modifiers and functions used by various NFTMarket mixins, if any.\n * @dev This also leaves a gap which can be used to add a new mixin to the top of the inheritance tree.\n */\nabstract contract NFTMarketCore is OwnableUpgradeable {\n    using SafeMathUpgradeable for uint256;\n\n    /// @notice Emitted when owner has updated the minIncrementPermille\n    event MinIncrementPermilleUpdated(uint16 prevValue, uint16 newValue);\n\n    /// @dev The minimum required when making an offer or placing a bid. Ej: 100 => 0.1 => 10%\n    uint16 public minIncrementPermille;\n\n    /**\n     * @param _minIncrementPermille The increment to outbid. Ej: 100 => 0.1 => 10%\n     */\n    function _initializeNFTMarketCore(uint16 _minIncrementPermille) internal {\n        minIncrementPermille = _minIncrementPermille;\n    }\n\n    function setMinIncrementPermille(uint16 _minIncrementPermille) external onlyOwner {\n        emit MinIncrementPermilleUpdated(minIncrementPermille, _minIncrementPermille);\n        minIncrementPermille = _minIncrementPermille;\n    }\n\n    /**\n     * @notice Transfers the NFT from escrow and clears any state tracking this escrowed NFT.\n     */\n    function _transferFromEscrow(\n        address nftContract,\n        uint256 tokenId,\n        address recipient\n    ) internal virtual;\n\n    /**\n     * @notice Transfers an NFT into escrow\n     */\n    function _transferToEscrow(address nftContract, uint256 tokenId) internal virtual;\n\n    /**\n     * @notice Applies fees and distributes funds for a finalized market operation.\n     * For all creator, platforma and seller.\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @param amount Reserve price, plus buyerFee.\n     * @param seller The address of the seller.\n     * @return platformFee Platform share total from the sale, both taken from the buyer and seller\n     * @return royaltyFee Rayalty fee distributed to owner/s\n     * @return assetFee Total received bu the saller\n     */\n    function _distFunds(\n        address nftContract,\n        uint256 tokenId,\n        uint256 amount,\n        address payable seller,\n        uint256 sellerFeesPerMille,\n        uint256 buyerFeesPerMille\n    )\n        internal\n        virtual\n        returns (\n            uint256 platformFee,\n            uint256 royaltyFee,\n            uint256 assetFee\n        );\n\n    /**\n     * @notice For a given price and fee, it returns the total amount a buyer must provide to cover for both\n     * @param _price the target price\n     * @param _buyerFeePermille the fee taken from the buyer, expressed in *1000 (ej: 10% = 0.1 => 100)\n     * @return amount the buyer must sent to comply to this price and fees\n     */\n    function applyBuyerFee(uint256 _price, uint8 _buyerFeePermille) internal pure returns (uint256 amount) {\n        if (_buyerFeePermille == 0) {\n            amount = _price;\n        } else {\n            amount = _price.add(_price.mul(_buyerFeePermille).div(1000));\n        }\n    }\n\n    /**\n     * @dev Determines the minimum amount when increasing an existing offer or bid.\n     */\n    function _getMinIncrement(uint256 currentAmount) internal view returns (uint256) {\n        uint256 minIncrement = currentAmount.mul(minIncrementPermille).div(1000);\n        if (minIncrement == 0) {\n            // Since minIncrement reduces from the currentAmount, this cannot overflow.\n            // The next amount must be at least 1 wei greater than the current.\n            return currentAmount + 1;\n        }\n\n        return minIncrement + currentAmount;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[1000] private __gap;\n}\n"
      },
      "contracts/market/NFTMarketReserveAuction.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/// @dev Taken from https://github.com/f8n/fnd-protocol/tree/v2.0.3\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\n\nimport \"./NFTMarketAuction.sol\";\nimport \"./NFTMarketCore.sol\";\nimport \"./SendValueWithFallbackWithdraw.sol\";\n\n// The gas limit to send ETH to a single recipient, enough for a contract with a simple receiver.\nuint256 constant SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT = 20000;\n\n// solhint-disable max-line-length\nstring constant ReserveAuction_Already_Listed = \"ReserveAuction_Already_Listed\";\nstring constant ReserveAuction_Bid_Must_Be_At_Least_Min_Amount = \"ReserveAuction_Bid_Must_Be_At_Least_Min_Amount\";\nstring constant ReserveAuction_Cannot_Admin_Cancel_Without_Reason = \"ReserveAuction_Cannot_Admin_Cancel_Without_Reason\";\nstring constant ReserveAuction_Cannot_Bid_Lower_Than_Reserve_Price = \"ReserveAuction_Cannot_Bid_Lower_Than_Reserve_Price\";\nstring constant ReserveAuction_Cannot_Bid_On_Ended_Auction = \"ReserveAuction_Cannot_Bid_On_Ended_Auction\";\nstring constant ReserveAuction_Cannot_Bid_On_Nonexistent_Auction = \"ReserveAuction_Cannot_Bid_On_Nonexistent_Auction\";\nstring constant ReserveAuction_Cannot_Cancel_Nonexistent_Auction = \"ReserveAuction_Cannot_Cancel_Nonexistent_Auction\";\nstring constant ReserveAuction_Cannot_Finalize_Already_Settled_Auction = \"ReserveAuction_Cannot_Finalize_Already_Settled_Auction\";\nstring constant ReserveAuction_Cannot_Finalize_Auction_In_Progress = \"ReserveAuction_Cannot_Finalize_Auction_In_Progress\";\nstring constant ReserveAuction_Cannot_Rebid_Over_Outstanding_Bid = \"ReserveAuction_Cannot_Rebid_Over_Outstanding_Bid\";\nstring constant ReserveAuction_Cannot_Update_Auction_In_Progress = \"ReserveAuction_Cannot_Update_Auction_In_Progress\";\nstring constant ReserveAuction_Subceeds_Min_Duration = \"ReserveAuction_Subceeds_Min_Duration\";\nstring constant ReserveAuction_Exceeds_Max_Duration = \"ReserveAuction_Exceeds_Max_Duration\";\nstring constant ReserveAuction_Less_Than_Extension_Duration = \"ReserveAuction_Less_Than_Extension_Duration\";\nstring constant ReserveAuction_Must_Set_Non_Zero_Reserve_Price = \"ReserveAuction_Must_Set_Non_Zero_Reserve_Price\";\nstring constant ReserveAuction_Not_Matching_Bidder = \"ReserveAuction_Not_Matching_Bidder\";\nstring constant ReserveAuction_Only_Owner_Can_Update_Auction = \"ReserveAuction_Only_Owner_Can_Update_Auction\";\nstring constant ReserveAuction_Price_Already_Set = \"ReserveAuction_Price_Already_Set\";\n\n// solhint-enable max-line-length\n\n/**\n * @title Allows the owner of an NFT to list it in auction.\n * @notice NFTs in auction are escrowed in the market contract.\n */\nabstract contract NFTMarketReserveAuction is\n    ReentrancyGuardUpgradeable,\n    NFTMarketCore,\n    NFTMarketAuction,\n    SendValueWithFallbackWithdraw\n{\n    // Stores the auction configuration for a specific NFT.\n    struct ReserveAuction {\n        // The address of the NFT contract.\n        address nftContract;\n        // The id of the NFT.\n        uint256 tokenId;\n        // The owner of the NFT which listed it in auction.\n        address payable seller;\n        // The duration for this auction.\n        uint256 duration;\n        // The extension window for this auction.\n        uint256 extensionDuration;\n        // The time at which this auction will not accept any new bids.\n        // @dev This is `0` until the first bid is placed.\n        uint256 endTime;\n        // The current highest bidder in this auction.\n        // @dev This is `address(0)` until the first bid is placed.\n        address payable bidder;\n        // The latest amount locked in for this auction. Includes buyerFee.\n        // @dev This is set to the reserve price + buyerFee, and then to the highest bid once the auction has started.\n        uint256 amount;\n        // The buyerFee at the moment the auction was created. Expressed as x1000 (ej: 100 => 10% = 0.1)\n        uint8 buyerFeePermille;\n        // The sellerFee at the moment the auction was created. Expressed as x1000 (ej: 100 => 10% = 0.1)\n        uint8 sellerFeePermille;\n    }\n\n    /// @dev The auction configuration for a specific auction id.\n    mapping(address => mapping(uint256 => uint256)) internal nftContractToTokenIdToAuctionId;\n\n    /// @dev The auction id for a specific NFT.\n    /// @dev This is deleted when an auction is finalized or canceled.\n    mapping(uint256 => ReserveAuction) internal auctionIdToAuction;\n\n    /// @dev Minimal value for how long an auction can lasts for once the first bid has been received.\n    uint256 internal minDuration;\n\n    /// @dev Maximal value for how long an auction can lasts for once the first bid has been received.\n    uint256 internal maxDuration;\n\n    /// @dev The window for auction extensions, any bid placed in the final 15 minutes\n    /// of an auction will reset the time remaining to 15 minutes.\n    uint256 internal constant EXTENSION_DURATION = 15 minutes;\n\n    /// @dev Caps the max duration that may be configured so that overflows will not occur.\n    uint256 internal constant MAX_MAX_DURATION = 1000 days;\n\n    /**\n     * @notice Emitted when a bid is placed.\n     * @param auctionId The id of the auction this bid was for.\n     * @param bidder The address of the bidder.\n     * @param amount The amount of the bid.\n     * @param endTime The new end time of the auction (which may have been set or extended by this bid).\n     */\n    event ReserveAuctionBidPlaced(uint256 indexed auctionId, address indexed bidder, uint256 amount, uint256 endTime);\n    /**\n     * @notice Emitted when an auction is cancelled.\n     * @dev This is only possible if the auction has not received any bids.\n     * @param auctionId The id of the auction that was cancelled.\n     */\n    event ReserveAuctionCanceled(uint256 indexed auctionId);\n    /**\n     * @notice Emitted when an auction is canceled by a Enigma admin.\n     * @dev When this occurs, the highest bidder (if there was a bid) is automatically refunded.\n     * @param auctionId The id of the auction that was cancelled.\n     * @param reason The reason for the cancellation.\n     */\n    event ReserveAuctionCanceledByAdmin(uint256 indexed auctionId, string reason);\n    /**\n     * @notice Emitted when an NFT is listed for auction.\n     * @param seller The address of the seller.\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @param duration The duration of the auction (always 24-hours).\n     * @param extensionDuration The duration of the auction extension window (always 15-minutes).\n     * @param reservePrice The reserve price to kick off the auction.\n     * @param bidAmount Reserve price, plus buyerFee. Min amount required to win this auction.\n     * @param auctionId The id of the auction that was created.\n     */\n    event ReserveAuctionCreated(\n        address indexed seller,\n        address indexed nftContract,\n        uint256 indexed tokenId,\n        uint256 duration,\n        uint256 extensionDuration,\n        uint256 reservePrice,\n        uint256 bidAmount,\n        uint256 auctionId\n    );\n    /**\n     * @notice Emitted when an auction that has already ended is finalized,\n     * indicating that the NFT has been transferred and revenue from the sale distributed.\n     * @dev The amount of the highest bid / final sale price for this auction is `f8nFee` + `creatorFee` + `ownerRev`.\n     * @param auctionId The id of the auction that was finalized.\n     * @param seller The address of the seller.\n     * @param bidder The address of the highest bidder that won the NFT.\n     * @param platformFee The amount of ETH that was sent to Enigma for this sale.\n     * @param royaltyFee The amount of ETH that was sent to the creator for this sale.\n     * @param sellerRev The amount of ETH that was sent to the sellet for this NFT.\n     */\n    event ReserveAuctionFinalized(\n        uint256 indexed auctionId,\n        address indexed seller,\n        address indexed bidder,\n        uint256 platformFee,\n        uint256 royaltyFee,\n        uint256 sellerRev\n    );\n    /**\n     * @notice Emitted when the auction's reserve price is changed.\n     * @dev This is only possible if the auction has not received any bids.\n     * @param auctionId The id of the auction that was updated.\n     * @param reservePrice The new reserve price for the auction.\n     */\n    event ReserveAuctionUpdated(uint256 indexed auctionId, uint256 reservePrice);\n\n    /// @notice Confirms that the reserve price is not zero.\n    modifier onlyValidAuctionConfig(uint256 reservePrice) {\n        if (reservePrice == 0) {\n            revert(ReserveAuction_Must_Set_Non_Zero_Reserve_Price);\n        }\n        _;\n    }\n\n    /// oz-upgrades-unsafe-allow constructor\n    // solhint-disable-next-line\n    constructor() {}\n\n    /**\n     * @notice Configures the duration for auctions.\n     * @param _minDuration The min duration for auctions, in seconds.\n     * @param _maxDuration The max duration for auctions, in seconds.\n     */\n    function _initializeNFTMarketReserveAuction(uint256 _minDuration, uint256 _maxDuration) internal {\n        if (_maxDuration > MAX_MAX_DURATION) {\n            // This ensures that math in this file will not overflow due to a huge duration.\n            revert(ReserveAuction_Exceeds_Max_Duration);\n        }\n        if (_minDuration < EXTENSION_DURATION) {\n            // The auction duration configuration must be greater than the extension window of 15 minutes\n            revert(ReserveAuction_Less_Than_Extension_Duration);\n        }\n        minDuration = _minDuration;\n        maxDuration = _maxDuration;\n    }\n\n    /**\n     * @notice Creates an auction for the given NFT.\n     * The NFT is held in escrow until the auction is finalized or canceled.\n     * buyer and seller fees are locked at creation time\n     * @dev IMPORTANT! The platform fees are assumed to be authenticated, otherwise this may cause security issues\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @param duration seconds for how long an auction lasts for once the first bid has been received.\n     * @param reservePrice The initial reserve price for the auction.\n     */\n    function createReserveAuctionFor(\n        address nftContract,\n        uint256 tokenId,\n        uint256 duration,\n        uint256 reservePrice,\n        uint256 amount,\n        PlatformFees calldata platformFees\n    ) internal virtual {\n        uint256 auctionId = nftContractToTokenIdToAuctionId[nftContract][tokenId];\n        if (auctionId == 0) {\n            // NFT is not in auction\n            // If the `msg.sender` is not the owner of the NFT, transferring into escrow should fail.\n            _transferToEscrow(nftContract, tokenId);\n        } else {\n            // Using storage saves gas since most of the data is not needed\n            ReserveAuction storage auction = auctionIdToAuction[auctionId];\n            if (auction.endTime == 0) {\n                revert(ReserveAuction_Already_Listed);\n            } else {\n                // Auction in progress, confirm the highest bidder is a match\n                if (auction.bidder != msg.sender) {\n                    revert(ReserveAuction_Not_Matching_Bidder);\n                }\n\n                // Finalize auction but leave NFT in escrow, reverts if the auction has not ended\n                _finalizeReserveAuction({ auctionId: auctionId, keepInEscrow: true });\n            }\n        }\n        // Get the new Id\n        auctionId = _getNextAndIncrementAuctionId();\n\n        // This checks if duration is between acceptable\n        if (minDuration > duration) {\n            revert(ReserveAuction_Subceeds_Min_Duration);\n        }\n        if (duration > maxDuration) {\n            revert(ReserveAuction_Exceeds_Max_Duration);\n        }\n\n        // Store the auction details\n        nftContractToTokenIdToAuctionId[nftContract][tokenId] = auctionId;\n        auctionIdToAuction[auctionId] = ReserveAuction(\n            nftContract,\n            tokenId,\n            payable(msg.sender),\n            duration,\n            EXTENSION_DURATION,\n            0, // endTime is only known once the reserve price is met\n            payable(0), // bidder is only known once a bid has been placed\n            amount,\n            platformFees.buyerFeePermille, // fees are locked-in at create time\n            platformFees.sellerFeePermille\n        );\n\n        emit ReserveAuctionCreated(\n            msg.sender,\n            nftContract,\n            tokenId,\n            duration,\n            EXTENSION_DURATION,\n            reservePrice,\n            amount,\n            auctionId\n        );\n    }\n\n    /**\n     * @notice Once the countdown has expired for an auction, anyone can settle the auction.\n     * This will send the NFT to the highest bidder and distribute revenue for this sale.\n     * @param auctionId The id of the auction to settle.\n     */\n    function finalizeReserveAuction(uint256 auctionId) external nonReentrant {\n        if (auctionIdToAuction[auctionId].endTime == 0) {\n            revert(ReserveAuction_Cannot_Finalize_Already_Settled_Auction);\n        }\n        _finalizeReserveAuction({ auctionId: auctionId, keepInEscrow: false });\n    }\n\n    /**\n     * @notice Settle an auction that has already ended.\n     * This will send the NFT to the highest bidder and distribute revenue for this sale.\n     * @param keepInEscrow If true, the NFT will be kept in escrow to save gas by avoiding\n     * redundant transfers if the NFT should remain in escrow, such as when the new owner\n     * sets a buy price or lists it in a new auction.\n     */\n    function _finalizeReserveAuction(uint256 auctionId, bool keepInEscrow) internal {\n        ReserveAuction memory auction = auctionIdToAuction[auctionId];\n\n        if (auction.endTime >= block.timestamp) {\n            revert(ReserveAuction_Cannot_Finalize_Auction_In_Progress);\n        }\n\n        // Remove the auction.\n        delete nftContractToTokenIdToAuctionId[auction.nftContract][auction.tokenId];\n        delete auctionIdToAuction[auctionId];\n\n        if (!keepInEscrow) {\n            // The seller was authorized when the auction was originally created\n            _transferFromEscrow(auction.nftContract, auction.tokenId, auction.bidder);\n        }\n\n        // Distribute revenue for this sale.\n        (uint256 platformFee, uint256 royaltyFee, uint256 assetFee) = _distAuctionFunds(auction);\n\n        emit ReserveAuctionFinalized(auctionId, auction.seller, auction.bidder, platformFee, royaltyFee, assetFee);\n    }\n\n    function _distAuctionFunds(ReserveAuction memory auction)\n        internal\n        returns (\n            uint256 platformFee,\n            uint256 royaltyFee,\n            uint256 assetFee\n        )\n    {\n        return\n            _distFunds(\n                auction.nftContract,\n                auction.tokenId,\n                auction.amount,\n                auction.seller,\n                auction.sellerFeePermille,\n                auction.buyerFeePermille\n            );\n    }\n\n    /**\n     * @notice Allows Enigma to cancel an auction, refunding the bidder and returning the NFT to\n     * the seller (if not active buy price set).\n     * This should only be used for extreme cases such as DMCA takedown requests.\n     * @param auctionId The id of the auction to cancel.\n     * @param reason The reason for the cancellation (a required field).\n     */\n    function adminCancelReserveAuction(uint256 auctionId, string calldata reason) external onlyOwner nonReentrant {\n        if (bytes(reason).length == 0) {\n            revert(ReserveAuction_Cannot_Admin_Cancel_Without_Reason);\n        }\n        ReserveAuction memory auction = auctionIdToAuction[auctionId];\n        if (auction.amount == 0) {\n            revert(ReserveAuction_Cannot_Cancel_Nonexistent_Auction);\n        }\n\n        delete nftContractToTokenIdToAuctionId[auction.nftContract][auction.tokenId];\n        delete auctionIdToAuction[auctionId];\n\n        // Return the NFT to the owner.\n        _transferFromEscrow(auction.nftContract, auction.tokenId, auction.seller);\n\n        if (auction.bidder != address(0)) {\n            // Refund the highest bidder if any bids were placed in this auction.\n            _sendValueWithFallbackWithdraw(auction.bidder, auction.amount, SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT);\n        }\n\n        emit ReserveAuctionCanceledByAdmin(auctionId, reason);\n    }\n\n    /**\n     * @notice If an auction has been created but has not yet received bids, it may be canceled by the seller.\n     * @dev The NFT is transferred back to the owner unless there is still a buy price set.\n     * @param auctionId The id of the auction to cancel.\n     */\n    function cancelReserveAuction(uint256 auctionId) external nonReentrant {\n        ReserveAuction memory auction = auctionIdToAuction[auctionId];\n        if (auction.amount == 0) {\n            revert(ReserveAuction_Cannot_Cancel_Nonexistent_Auction);\n        }\n        if (auction.seller != msg.sender) {\n            revert(ReserveAuction_Only_Owner_Can_Update_Auction);\n        }\n        if (auction.endTime != 0) {\n            revert(ReserveAuction_Cannot_Update_Auction_In_Progress);\n        }\n\n        // Remove the auction.\n        delete nftContractToTokenIdToAuctionId[auction.nftContract][auction.tokenId];\n        delete auctionIdToAuction[auctionId];\n\n        // Transfer the NFT.\n        _transferFromEscrow(auction.nftContract, auction.tokenId, auction.seller);\n\n        emit ReserveAuctionCanceled(auctionId);\n    }\n\n    /**\n     * @notice Place a bid in an auction.\n     * A bidder may place a bid which is at least the value defined by `getMinBidAmount`.\n     * If this is the first bid on the auction, the countdown will begin.\n     * If there is already an outstanding bid, the previous bidder will be refunded at this time\n     * and if the bid is placed in the final moments of the auction, the countdown may be extended.\n     * @param auctionId The id of the auction to bid on.\n     */\n    /* solhint-disable-next-line code-complexity */\n    function placeBid(uint256 auctionId) external payable nonReentrant {\n        ReserveAuction storage auction = auctionIdToAuction[auctionId];\n\n        if (auction.amount == 0) {\n            // No auction found\n            revert(ReserveAuction_Cannot_Bid_On_Nonexistent_Auction);\n        }\n\n        uint256 endTime = auction.endTime;\n        if (endTime == 0) {\n            // This is the first bid, kicking off the auction.\n\n            if (msg.value < auction.amount) {\n                // The bid must be >= the reserve price.\n                revert(ReserveAuction_Cannot_Bid_Lower_Than_Reserve_Price);\n            }\n\n            // Store the bid details.\n            auction.amount = msg.value;\n            auction.bidder = payable(msg.sender);\n\n            // On the first bid, set the endTime to now + duration.\n            // Duration is always less than MAX MAX, so the below can't overflow.\n            endTime = block.timestamp + auction.duration;\n\n            auction.endTime = endTime;\n        } else {\n            if (endTime < block.timestamp) {\n                // The auction has already ended.\n                revert(ReserveAuction_Cannot_Bid_On_Ended_Auction);\n            } else if (auction.bidder == msg.sender) {\n                // We currently do not allow a bidder to increase their bid unless another user has outbid them first.\n                revert(ReserveAuction_Cannot_Rebid_Over_Outstanding_Bid);\n            } else {\n                uint256 minIncrement = _getMinIncrement(auction.amount);\n                if (msg.value < minIncrement) {\n                    // If this bid outbids another, it must be at least 10% greater than the last bid.\n                    revert(ReserveAuction_Bid_Must_Be_At_Least_Min_Amount);\n                }\n            }\n\n            // Cache and update bidder state\n            uint256 originalAmount = auction.amount;\n            address payable originalBidder = auction.bidder;\n            auction.amount = msg.value;\n            auction.bidder = payable(msg.sender);\n\n            // When a bid outbids another, check to see if a time extension should apply.\n            // We confirmed that the auction has not ended, so endTime is always >= the current timestamp.\n            // Current time plus extension duration (always 15 mins) cannot overflow.\n            uint256 endTimeWithExtension = block.timestamp + EXTENSION_DURATION;\n            if (endTime < endTimeWithExtension) {\n                endTime = endTimeWithExtension;\n                auction.endTime = endTime;\n            }\n            // Refund the previous bidder\n            _sendValueWithFallbackWithdraw(originalBidder, originalAmount, SEND_VALUE_GAS_LIMIT_SINGLE_RECIPIENT);\n        }\n        emit ReserveAuctionBidPlaced(auctionId, msg.sender, msg.value, endTime);\n    }\n\n    /**\n     * @notice If an auction has been created but has not yet received bids, the reservePrice may be\n     * changed by the seller.\n     * @param auctionId The id of the auction to change.\n     * @param reservePrice The new reserve price for this auction.\n     */\n    function updateReserveAuction(uint256 auctionId, uint256 reservePrice)\n        external\n        onlyValidAuctionConfig(reservePrice)\n    {\n        ReserveAuction storage auction = auctionIdToAuction[auctionId];\n        if (auction.seller != msg.sender) {\n            revert(ReserveAuction_Only_Owner_Can_Update_Auction);\n        } else if (auction.endTime != 0) {\n            revert(ReserveAuction_Cannot_Update_Auction_In_Progress);\n        }\n\n        // get the amount, including buyer fee for this reserve price\n        uint256 amount = applyBuyerFee(reservePrice, auction.buyerFeePermille);\n        if (auction.amount == amount) revert(ReserveAuction_Price_Already_Set);\n\n        // Update the current reserve price.\n        auction.amount = amount;\n\n        emit ReserveAuctionUpdated(auctionId, reservePrice);\n    }\n\n    /**\n     * @notice Returns the minimum amount a bidder must spend to participate in an auction.\n     * Bids must be greater than or equal to this value or they will revert.\n     * @param auctionId The id of the auction to check.\n     * @return minimum The minimum amount for a bid to be accepted.\n     */\n    function getMinBidAmount(uint256 auctionId) external view returns (uint256 minimum) {\n        ReserveAuction storage auction = auctionIdToAuction[auctionId];\n        if (auction.endTime == 0) {\n            return auction.amount;\n        }\n        return _getMinIncrement(auction.amount);\n    }\n\n    /**\n     * @notice Returns auction details for a given auctionId.\n     * @param auctionId The id of the auction to lookup.\n     * @return auction The auction details.\n     */\n    function getReserveAuction(uint256 auctionId) external view returns (ReserveAuction memory auction) {\n        return auctionIdToAuction[auctionId];\n    }\n\n    /**\n     * @notice Returns the auctionId for a given NFT, or 0 if no auction is found.\n     * @dev If an auction is canceled, it will not be returned. However the auction may be over\n     *  and pending finalization.\n     * @param nftContract The address of the NFT contract.\n     * @param tokenId The id of the NFT.\n     * @return auctionId The id of the auction, or 0 if no auction is found.\n     */\n    function getReserveAuctionIdFor(address nftContract, uint256 tokenId) external view returns (uint256 auctionId) {\n        auctionId = nftContractToTokenIdToAuctionId[nftContract][tokenId];\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[1000] private __gap;\n}\n"
      },
      "contracts/market/SendValueWithFallbackWithdraw.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\n/// @dev Taken from https://github.com/f8n/fnd-protocol/tree/v2.0.3\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\npragma solidity ^0.7.6;\n\n/**\n * @title A mixin for sending ETH with a fallback withdraw mechanism.\n * @notice Attempt to send ETH and if the transfer fails or runs out of gas, store the balance\n * in the pendingWithdrawals for future withdrawal instead.\n */\nabstract contract SendValueWithFallbackWithdraw is OwnableUpgradeable {\n    /// @dev Tracks the amount of ETH that is stored in escrow for future withdrawal.\n    mapping(address => uint256) internal pendingWithdrawals;\n\n    /**\n     * @notice Emitted when escrowed funds are withdrawn.\n     * @param executor The account which has withdrawn ETH, either the owner or an Admin.\n     * @param owner The owner whose ETH has been withdrawn from.\n     * @param recipient The address where the funds were transfered to.\n     * @param amount The amount of ETH which has been withdrawn.\n     */\n    event PendingWithdrawalCompleted(\n        address indexed executor,\n        address indexed owner,\n        address recipient,\n        uint256 amount\n    );\n\n    /**\n     * @notice Emitted when escrowed funds are deposite into pending Withdrawals.\n     * @param owner The owner whose ETH has been deposit.\n     * @param amount The amount of ETH which has been deposit.\n     */\n    event PendingWithdrawalDeposit(address indexed owner, uint256 amount);\n\n    /**\n     * @dev Attempt to send a user or contract ETH and\n     * if it fails store the amount owned for later withdrawal .\n     *  @dev This function doesn't check for reentrancy issues so be careful when invoking\n     */\n    function _sendValueWithFallbackWithdraw(\n        address payable user,\n        uint256 amount,\n        uint256 gasLimit\n    ) internal {\n        if (amount == 0) {\n            return;\n        }\n        // Cap the gas to prevent consuming all available gas to block a tx from completing successfully\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, ) = user.call{ value: amount, gas: gasLimit }(\"\");\n        if (!success) {\n            // Store the funds that failed to send for the user pendingWithdrawals list\n            pendingWithdrawals[user] += amount;\n            emit PendingWithdrawalDeposit(user, amount);\n        }\n    }\n\n    function _withdrawTo(address from, address payable recipient) internal {\n        uint256 pendingAmount = pendingWithdrawals[from];\n        if (pendingAmount != 0) {\n            // No reentrancy is possible\n            pendingWithdrawals[from] = 0;\n            (bool success, ) = recipient.call{ value: pendingAmount }(\"\");\n            require(success, \"withdrawal failed\");\n            emit PendingWithdrawalCompleted(msg.sender, from, recipient, pendingAmount);\n        }\n    }\n\n    /**\n     * @notice Allows owner to widthawl pending funds (on failed sale send).\n     * @param recipient The address to sent the locked funds to.\n     */\n    function withdrawTo(address payable recipient) public {\n        _withdrawTo(msg.sender, recipient);\n    }\n\n    /**\n     * @notice Allows Enigma to widthawl pending funds (on failed sale send) on behalf of a user.\n     * This should only be used for extreme cases when the user has prove unintended funds locked up.\n     * @param fundsOwner The user address holding the pending funds.\n     * @param recipient The address to sent the locked funds to.\n     */\n    function adminWithdrawTo(address fundsOwner, address payable recipient) external onlyOwner {\n        _withdrawTo(fundsOwner, recipient);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[500] private __gap;\n}\n"
      },
      "contracts/market/TradeV4.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol\";\nimport \"./utils/TradeSignaturesVerifier.sol\";\nimport \"../utils/AuthorizationBitmap.sol\";\nimport \"../utils/Types.sol\";\nimport \"../interfaces/ITransferProxy.sol\";\nimport \"../interfaces/IRoyaltyAwareNFT.sol\";\nimport \"../ERC721/BaseEnigmaNFT721.sol\";\nimport \"../ERC1155/BaseEnigmaNFT1155.sol\";\n\n/// @title TradeV4\n///\n/// @dev This contract is a Transparent Upgradable based in openZeppelin v3.4.0.\n///         Be careful when upgrade, you must respect the same storage.\n\nabstract contract TradeV4 is ReentrancyGuardUpgradeable, OwnableUpgradeable, TradeSignaturesVerifier {\n    using SafeMathUpgradeable for uint256;\n    using ECDSAUpgradeable for bytes32;\n\n    event SellerFee(uint8 sellerFee);\n    event BuyerFee(uint8 buyerFee);\n    event CustodialAddressChanged(address prevAddress, address newAddress);\n    event BuyAsset(\n        address indexed assetOwner,\n        address paymentReceiver,\n        address indexed tokenReceiver,\n        address paymentSender,\n        address assetAddress,\n        AssetType assetType,\n        uint256 indexed tokenId,\n        uint256 quantity,\n        uint256 nonce,\n        bool mintTokens\n    );\n    event ExecuteBid(address indexed assetOwner, uint256 indexed tokenId, uint256 quantity, address indexed buyer);\n    event TokenWithdraw(address indexed assetOwner, uint256 indexed nonce, uint256 indexed tokenId, uint256 quantity);\n\n    /// @dev deprecated\n    uint8 internal _buyerFeePermille;\n    /// @dev deprecated\n    uint8 internal _sellerFeePermille;\n    ITransferProxy public transferProxy;\n    address public enigmaNFT721Address;\n    address public enigmaNFT1155Address;\n    // Address that acts as custodial for platform hold NFTs,\n    address public custodialAddress;\n\n    bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;\n\n    // This is a packed array of booleans, to track processed authorizations\n    mapping(uint256 => uint256) internal processedAuthorizationsBitMap;\n\n    // This mapping uses as input the address of the seller and the nonce\n    // to avoid an order being oversold in multiple sells.\n    // It is assumed that the user will for every order use a different order\n    // If it does not, it will create an undefined behaviour over its own tokens\n    // meaning that even in the worst case scenario, it will only sell its own tokens\n    mapping(address => mapping(uint256 => uint256)) internal amountSold;\n\n    // This tracks the id of an order to mintAndSell(lazy mint).\n    // It uses the seller and the nonce as input to avoid overlapping multiple sales\n    mapping(address => mapping(uint256 => uint256)) internal mintOrderTokenId;\n\n    struct FeeDistributionData {\n        uint256 toRightsHolder; // Amount of tokens/ethers that will be sent to the rights holder(royalty receiver)\n        uint256 toSeller; // Amount of tokens/ethers that will be sent to the seller\n        address rightsHolder; // Rights holder address(tipically the creator, or a smart contract that splits the fees)\n        Fees fees;\n    }\n\n    /// @notice Struct that contains all the fees of a given sale\n    struct Fees {\n        uint256 platformFee; // Sum of buyerFee + sellerFee, this is what the platform charges for a sale\n        // Amount sent - royalty - platformFee, this is what is left after fees are\n        // taken(usually goes to the seller unless this is a primary sale)\n        uint256 assetFee;\n        uint256 royaltyFee; // Royalty fee (could be split or not), it is intended to go to the artist/creator\n        uint256 price; // Amount sent - buyerFee, it should be the price that the seller set on the asset\n    }\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) TradeSignaturesVerifier(name, version) {}\n\n    function initializeTradeV4(\n        ITransferProxy _transferProxy,\n        address _enigmaNFT721Address,\n        address _enigmaNFT1155Address,\n        address _custodialAddress\n    ) internal initializer {\n        transferProxy = _transferProxy;\n        enigmaNFT721Address = _enigmaNFT721Address;\n        enigmaNFT1155Address = _enigmaNFT1155Address;\n        custodialAddress = _custodialAddress;\n        __Ownable_init();\n        __ReentrancyGuard_init();\n    }\n\n    function setCustodialAddress(address _custodialAddress) external onlyOwner returns (bool) {\n        emit CustodialAddressChanged(custodialAddress, _custodialAddress);\n        custodialAddress = _custodialAddress;\n        return true;\n    }\n\n    /**\n     * @notice Calculates fees of an operation from the paymentAmount as well as ask for the royalty fees receiver\n     * because it is part of the ERC2981 standard\n     * @param paymentAmt Amount that the user sent(NOT the price, it is the price + buyer fee)\n     * @param buyingAssetAddress the token symbol\n     * @param tokenId Token id of the token being sold\n     * @param sellerFeePermille Seller fee in Permille(unit per thousand of the total)\n     * @param buyerFeePermille Buyer fee in Permille(unit per thousand of the total)\n     */\n    function calculateFees(\n        uint256 paymentAmt,\n        address buyingAssetAddress,\n        uint256 tokenId,\n        uint256 sellerFeePermille,\n        uint256 buyerFeePermille\n    ) internal view virtual returns (address, Fees memory) {\n        Fees memory fees;\n        address royaltyFeeReceiver;\n        // TODO maybe this could be improved if the price is sent instead of being calculated\n        uint256 price = paymentAmt.mul(1000).div((1000 + buyerFeePermille));\n        uint256 buyerFee = paymentAmt.sub(price);\n        uint256 sellerFee = price.mul(sellerFeePermille).div((1000));\n        fees.platformFee = buyerFee.add(sellerFee);\n\n        bool success = IERC165Upgradeable(buyingAssetAddress).supportsInterface(_INTERFACE_ID_ERC2981);\n        if (success) {\n            (royaltyFeeReceiver, fees.royaltyFee) = IERC2981(buyingAssetAddress).royaltyInfo(tokenId, price);\n        } else {\n            fees.royaltyFee = 0;\n        }\n        fees.assetFee = price.sub(sellerFee).sub(fees.royaltyFee);\n        fees.price = price;\n        return (royaltyFeeReceiver, fees);\n    }\n\n    /**\n     * @notice Calculates fees of an operation from the paymentAmount and to whom we should distribute it too\n     *\n     * @param paymentAmt Amount that the user sent(NOT the price, it is the price + buyer fee)\n     * @param buyingAssetAddress the token symbol\n     * @param tokenId Token id of the token being sold\n     * @param sellerFeePermille Seller fee in Permille(unit per thousand of the total)\n     * @param buyerFeePermille Buyer fee in Permille(unit per thousand of the total)\n     * @param seller Address of the seller\n     */\n    function getFees(\n        uint256 paymentAmt,\n        address buyingAssetAddress,\n        uint256 tokenId,\n        uint256 sellerFeePermille,\n        uint256 buyerFeePermille,\n        address seller\n    ) internal view virtual returns (FeeDistributionData memory) {\n        (address royaltyFeesReceiver, Fees memory fees) =\n            calculateFees(paymentAmt, buyingAssetAddress, tokenId, sellerFeePermille, buyerFeePermille);\n        uint256 toRightsHolder = 0;\n        uint256 toSeller = 0;\n        bool isPrimarySale;\n\n        try IRoyaltyAwareNFT(buyingAssetAddress).getCreator(tokenId) returns (address creator) {\n            isPrimarySale = creator == seller;\n        } catch {\n            // We are not sure as this is probably an external token. We will take the safe path here\n            isPrimarySale = false;\n        }\n\n        if (isPrimarySale) {\n            toRightsHolder = fees.royaltyFee.add(fees.assetFee);\n            // seller receives 0 in this case as all of it is split using the rightsHolder\n        } else {\n            toSeller = fees.assetFee;\n            toRightsHolder = fees.royaltyFee; // This might be 0\n        }\n\n        return\n            FeeDistributionData({\n                toRightsHolder: toRightsHolder,\n                toSeller: toSeller,\n                rightsHolder: royaltyFeesReceiver,\n                fees: fees\n            });\n    }\n\n    function tradeNFT(Order memory order) internal virtual {\n        safeTransferFrom(\n            order.nftType,\n            order.seller,\n            order.tokenReceiver,\n            order.nftAddress,\n            order.tokenId,\n            order.quantity\n        );\n    }\n\n    function _mintExistingNFT(Order memory order, uint256 tokenId) internal returns (uint256) {\n        BaseEnigmaNFT1155(order.nftAddress).mintExistingExternalVerifier(\n            tokenId,\n            order.quantity,\n            order.tokenReceiver,\n            order.seller,\n            order.nonce\n        );\n        return tokenId;\n    }\n\n    function _mintNFT(Order memory order, TokenData memory tokenData) internal virtual returns (uint256) {\n        uint256 tokenId;\n        if (order.nftType == AssetType.ERC721) {\n            tokenId = BaseEnigmaNFT721(order.nftAddress).mintNewExternalVerifier(\n                tokenData.tokenURI,\n                tokenData.royaltyFee,\n                tokenData.rightsHolder,\n                order.tokenReceiver,\n                order.seller,\n                order.nonce\n            );\n        } else {\n            tokenId = mintOrderTokenId[order.seller][order.nonce];\n            if (tokenId == 0) {\n                tokenId = BaseEnigmaNFT1155(order.nftAddress).mintNewExternalVerifier(\n                    tokenData.tokenURI,\n                    tokenData.royaltyFee,\n                    tokenData.rightsHolder,\n                    order.tokenReceiver,\n                    order.nonce,\n                    order.seller,\n                    order.tokenId,\n                    order.quantity\n                );\n                mintOrderTokenId[order.seller][order.nonce] = tokenId;\n            } else {\n                _mintExistingNFT(order, tokenId);\n            }\n        }\n        return tokenId;\n    }\n\n    function safeTransferFrom(\n        AssetType nftType,\n        address from,\n        address to,\n        address nftAddress,\n        uint256 tokenId,\n        uint256 quantity\n    ) internal virtual {\n        nftType == AssetType.ERC721\n            ? transferProxy.erc721safeTransferFrom(nftAddress, from, to, tokenId)\n            : transferProxy.erc1155safeTransferFrom(nftAddress, from, to, tokenId, quantity, \"\");\n    }\n\n    /**\n     * @dev Disable slither warning because there is a nonReentrant check and the address are known\n     * https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations\n     */\n    function tradeETH(\n        Order memory order,\n        address royaltyReceiver,\n        Fees memory fees\n    ) internal virtual {\n        bool singleReceiver = royaltyReceiver == order.paymentReceiver;\n        if (fees.platformFee > 0) {\n            // slither-disable-next-line arbitrary-send\n            (bool platformSuccess, ) = owner().call{ value: fees.platformFee }(\"\");\n            require(platformSuccess, \"sending ETH to owner failed\");\n        }\n\n        if (!singleReceiver && fees.royaltyFee > 0) {\n            // slither-disable-next-line arbitrary-send\n            (bool royaltySuccess, ) = royaltyReceiver.call{ value: fees.royaltyFee }(\"\");\n            require(royaltySuccess, \"sending ETH to creator failed\");\n        }\n\n        if (singleReceiver || fees.assetFee > 0) {\n            uint256 amountToTransfer = singleReceiver ? fees.assetFee.add(fees.royaltyFee) : fees.assetFee;\n            // slither-disable-next-line arbitrary-send\n            (bool sellerSuccess, ) = order.paymentReceiver.call{ value: amountToTransfer }(\"\");\n            require(sellerSuccess, \"sending ETH to seller failed\");\n        }\n    }\n\n    function _buyAssetWithETH(\n        Order memory order,\n        PlatformFeesBase calldata platformFees,\n        // this might be differen from the tokenId of the order\n        // (if we are creating a new token, the order's tokenId should be 0 in most cases)\n        uint256 tokenId,\n        bool mintTokens\n    ) internal {\n        require(order.timeLimit >= block.timestamp, \"TradeV4: Order expired\");\n        require(platformFees.timeLimit >= block.timestamp, \"TradeV4: Platform fees expired\");\n        // This is repeating code for the moment being but it is an ongoing effort to refactor\n        // the distribution of fees to remove primary sale from the logic of the contract\n        (address royaltyReceiver, Fees memory fees) =\n            calculateFees(\n                msg.value,\n                order.nftAddress,\n                tokenId,\n                platformFees.sellerFeePermille,\n                platformFees.buyerFeePermille\n            );\n        require((fees.price >= order.unitPrice * order.quantity), \"Paid invalid amount\");\n        // Instead of an explicit check for equality, we check that the signature\n        // was created using those values\n        verifyDirectSalePlatformFeesSignature(platformFees, order, mintTokens, owner());\n        // Using the one sent here saves some checks as we need to make sure the same seller fees\n        // where included in both singatures, no need for an extra param or assertion\n        require(\n            order.nftType == AssetType.ERC1155 || order.limitAmountToSell == 1,\n            \"TradeV4: Limit amount to sell has to be 1 for ERC721\"\n        );\n\n        // Seller could be overselling its balance by signing an order too large, we allow that\n        // In that scenario the seller could be allowing users to buy tokens bought into the future at the current price\n        // This is not recommended but as it could only harm the seller, this is not enforced\n        uint256 totalAmountSold = amountSold[order.seller][order.nonce].add(order.quantity);\n        require(totalAmountSold <= order.limitAmountToSell, \"TradeV4: Order oversold\");\n        amountSold[order.seller][order.nonce] = totalAmountSold;\n\n        tradeETH(order, royaltyReceiver, fees);\n    }\n\n    /*********************\n     ** PUBLIC FUNCTIONS *\n     *********************/\n\n    function buyAssetWithETH(\n        Order memory order,\n        bytes memory signature, // seller signature\n        PlatformFeesBase calldata platformFees\n    ) external payable nonReentrant returns (bool) {\n        // Using the one sent here saves some checks as we need to make sure the same seller fees\n        // where included in both singatures, no need for an extra param or assertion\n        verifySellerSignature(order, platformFees.sellerFeePermille, signature);\n        _buyAssetWithETH(order, platformFees, order.tokenId, false);\n        if (order.tokenReceiver != order.seller) tradeNFT(order);\n        emit BuyAsset(\n            order.seller,\n            order.paymentReceiver,\n            order.tokenReceiver,\n            msg.sender,\n            order.nftAddress,\n            order.nftType,\n            order.tokenId,\n            order.quantity,\n            order.nonce,\n            false\n        );\n        return true;\n    }\n\n    function mintNewAndBuyAssetWithETH(\n        Order memory order,\n        TokenData memory tokenData,\n        bytes memory signature, // seller signature\n        PlatformFeesBase calldata platformFees\n    ) external payable nonReentrant returns (bool) {\n        // Using the one sent here saves some checks as we need to make sure the same seller fees\n        // where included in both singatures, no need for an extra param or assertion\n        verifyMintNewSignature(order, tokenData, platformFees.sellerFeePermille, signature);\n        uint256 tokenId = _mintNFT(order, tokenData);\n        _buyAssetWithETH(order, platformFees, tokenId, true);\n        emit BuyAsset(\n            order.seller,\n            order.paymentReceiver,\n            order.tokenReceiver,\n            msg.sender,\n            order.nftAddress,\n            order.nftType,\n            tokenId,\n            order.quantity,\n            order.nonce,\n            true\n        );\n        return true;\n    }\n\n    function mintExistingAndBuyAssetWithETH(\n        Order memory order,\n        bytes memory signature, // seller signature\n        PlatformFeesBase calldata platformFees\n    ) external payable nonReentrant returns (bool) {\n        require(order.nftType == AssetType.ERC1155, \"TradeV4: Cannot mint an existing 721\");\n\n        // Using the one sent here saves some checks as we need to make sure the same seller fees\n        // where included in both singatures, no need for an extra param or assertion\n        verifyMintExistingSignature(order, platformFees.sellerFeePermille, signature);\n        uint256 tokenId = _mintExistingNFT(order, order.tokenId);\n        _buyAssetWithETH(order, platformFees, tokenId, true);\n        emit BuyAsset(\n            order.seller,\n            order.paymentReceiver,\n            order.tokenReceiver,\n            msg.sender,\n            order.nftAddress,\n            order.nftType,\n            tokenId,\n            order.quantity,\n            order.nonce,\n            true\n        );\n        return true;\n    }\n\n    /**\n     * @notice Verifies and executes a safe Token withdraw for this sender, if authorized by the custodial\n     * @param wr struct with the withdraw information. What asset and how much of it\n     * @param signature asset custodial authorization signature\n     */\n    function withdrawToken(WithdrawRequest memory wr, bytes memory signature) external returns (bool) {\n        require(wr.timeLimit >= block.timestamp, \"TradeV4: Withdraw voucher expired\");\n        require(\n            !AuthorizationBitmap.isAuthProcessed(processedAuthorizationsBitMap, wr.nonce),\n            \"Authorization signature already processed\"\n        );\n        address assetOwner = msg.sender;\n        // Verifies that this asset custodial, is actually authorizing this user withdraw\n        verifyWithdrawSignature(custodialAddress, assetOwner, wr, signature);\n        AuthorizationBitmap.setAuthProcessed(processedAuthorizationsBitMap, wr.nonce);\n        safeTransferFrom(wr.assetType, custodialAddress, assetOwner, wr.assetAddress, wr.tokenId, wr.quantity);\n        emit TokenWithdraw(assetOwner, wr.nonce, wr.tokenId, wr.quantity);\n        return true;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n\n     */\n    uint256[998] private __gap;\n}\n"
      },
      "contracts/market/utils/TradeSignaturesVerifier.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../utils/EIP712.sol\";\n\nenum AssetType { ERC1155, ERC721 }\n\nstruct PlatformFees {\n    address assetAddress;\n    uint256 tokenId;\n    uint8 buyerFeePermille;\n    uint8 sellerFeePermille;\n    bytes signature;\n}\n\nstruct PlatformFeesBase {\n    uint8 buyerFeePermille;\n    uint8 sellerFeePermille;\n    bytes signature;\n    uint256 timeLimit;\n}\n\nstruct WithdrawRequest {\n    uint256 nonce; // Unique id for this withdraw authorization\n    address assetAddress;\n    AssetType assetType;\n    uint256 tokenId;\n    uint256 quantity;\n    uint256 timeLimit;\n}\n\nstruct Order {\n    address seller; // defined by seller - current owner of the tokens - signer of the sell order\n    address tokenReceiver; // defined by buyer - new owner of the tokens\n    address erc20Address; // defined by seller\n    address nftAddress; // defined by seller\n    AssetType nftType; // defined by seller\n    uint256 unitPrice; // defined by seller\n    uint256 tokenId; // defined by seller\n    uint256 quantity; // defined by buyer\n    uint256 limitAmountToSell; // defined by seller\n    uint256 nonce; // defined by seller\n    address paymentReceiver; // defined by seller\n    uint256 timeLimit; // defined by seller\n}\n\nstruct TokenData {\n    string tokenURI;\n    uint256 royaltyFee;\n    address rightsHolder;\n}\n\ncontract TradeSignaturesVerifier is EIP712 {\n    bytes32 private constant PLATFORM_FEES_TYPE_HASH =\n        keccak256(\"PlatformFees(address assetAddress,uint256 tokenId,uint8 buyerFeePermille,uint8 sellerFeePermille)\");\n\n    bytes32 private constant DIRECT_SALE_PLATFORM_FEES_TYPE_HASH =\n        // solhint-disable max-line-length\n        keccak256(\n            \"DirectSalePlatformFees(address assetAddress,address seller,uint256 tokenId,uint256 limitAmountToSell,uint256 sellOrderNonce,uint8 buyerFeePermille,uint8 sellerFeePermille,bool mintTokens,uint256 timeLimit)\"\n        );\n\n    bytes32 private constant SELL_ORDER_TYPE_HASH =\n        keccak256(\n            // solhint-disable max-line-length\n            \"SellOrder(address assetAddress,uint256 tokenId,address paymentAssetAddress,uint256 unitPrice,uint256 limitAmountToSell,uint8 sellerFeePermille,uint256 nonce,uint256 timeLimit,address paymentReceiver)\"\n        );\n\n    bytes32 private constant TOKEN_DATA_TYPE_HASH =\n        keccak256(\"TokenData(string tokenURI,uint256 royaltyFee,address rightsHolder)\");\n\n    bytes32 private constant MINT_NEW_AND_SELL_ORDER_TYPE_HASH =\n        keccak256(\n            // solhint-disable max-line-length\n            \"MintNewAndSellOrder(SellOrder sellOrder,TokenData tokenData)SellOrder(address assetAddress,uint256 tokenId,address paymentAssetAddress,uint256 unitPrice,uint256 limitAmountToSell,uint8 sellerFeePermille,uint256 nonce,uint256 timeLimit,address paymentReceiver)TokenData(string tokenURI,uint256 royaltyFee,address rightsHolder)\"\n        );\n\n    bytes32 private constant MINT_EXISTING_AND_SELL_ORDER_TYPE_HASH =\n        keccak256(\n            // solhint-disable max-line-length\n            \"MintExistingAndSellOrder(SellOrder sellOrder)SellOrder(address assetAddress,uint256 tokenId,address paymentAssetAddress,uint256 unitPrice,uint256 limitAmountToSell,uint8 sellerFeePermille,uint256 nonce,uint256 timeLimit,address paymentReceiver)\"\n        );\n\n    bytes32 private constant WITHDRAW_VOUCHER_TYPE_HASH =\n        keccak256(\n            // solhint-disable max-line-length\n            \"WithdrawVoucher(address assetOwner,uint256 nonce,address assetAddress,uint8 assetType,uint256 tokenId,uint256 quantity,uint256 timeLimit)\"\n        );\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) EIP712(name, version) {}\n\n    /**\n     * @notice Internal function to verify a sign to mint tokens\n     * Reverts if the sign verification fails.\n     * @param platformFees Struct that has information about platform fees\n     * @param authorizer address of the wallet that authorizes minters\n     */\n    function verifyPlatformFeesSignature(PlatformFees calldata platformFees, address authorizer) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        PLATFORM_FEES_TYPE_HASH,\n                        platformFees.assetAddress,\n                        platformFees.tokenId,\n                        platformFees.buyerFeePermille,\n                        platformFees.sellerFeePermille\n                    )\n                )\n            );\n\n        address signer = ECDSAUpgradeable.recover(digest, platformFees.signature);\n        require(authorizer == signer, \"fees sign verification failed\");\n    }\n\n    /**\n     * @notice Internal function to verify a sign to mint tokens\n     * Reverts if the sign verification fails.\n     * @param platformFees Struct that has information about platform fees\n     * @param buyOrder struct with buy order data\n     * @param authorizer address of the wallet that authorizes minters\n     */\n    function verifyDirectSalePlatformFeesSignature(\n        PlatformFeesBase calldata platformFees,\n        Order memory buyOrder,\n        bool mintTokens,\n        address authorizer\n    ) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        DIRECT_SALE_PLATFORM_FEES_TYPE_HASH,\n                        buyOrder.nftAddress,\n                        buyOrder.seller,\n                        buyOrder.tokenId,\n                        buyOrder.limitAmountToSell,\n                        buyOrder.nonce,\n                        platformFees.buyerFeePermille,\n                        platformFees.sellerFeePermille,\n                        mintTokens,\n                        platformFees.timeLimit\n                    )\n                )\n            );\n\n        address signer = ECDSAUpgradeable.recover(digest, platformFees.signature);\n        require(authorizer == signer, \"TradeSignatureVerifier: direct sale fees sign corrupted\");\n    }\n\n    /**\n     * @notice Verifies the seller authorization to sell a token\n     * @param buyOrder struct with buy order data\n     * @param sellerFeePermille sellerFee that is authorized by the seller(this is used in order to\n     */\n    function _hashSellOrder(Order memory buyOrder, uint8 sellerFeePermille) private pure returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    SELL_ORDER_TYPE_HASH,\n                    buyOrder.nftAddress,\n                    buyOrder.tokenId,\n                    address(0), // For the moment being we do not support ERC20 payments\n                    buyOrder.unitPrice,\n                    buyOrder.limitAmountToSell,\n                    sellerFeePermille,\n                    buyOrder.nonce,\n                    buyOrder.timeLimit,\n                    buyOrder.paymentReceiver\n                )\n            );\n    }\n\n    /**\n     * @notice Verifies the seller authorization to sell a token\n     * @param buyOrder struct with buy order data\n     * @param sellerFeePermille sellerFee that is authorized by the seller(this is used in order to\n     * @param signature bytes that represent the signature\n     */\n    function verifySellerSignature(\n        Order memory buyOrder,\n        uint8 sellerFeePermille,\n        bytes memory signature\n    ) internal view {\n        bytes32 digest = _hashTypedDataV4(_hashSellOrder(buyOrder, sellerFeePermille));\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        require(buyOrder.seller == signer, \"seller sign verification failed\");\n    }\n\n    /**\n     * @notice Verifies the seller authorization to sell a token\n     * @param buyOrder struct with buy order data\n     * @param tokenData struct with data to mint new token\n     * @param sellerFeePermille sellerFee that is authorized by the seller(this is used in order to\n     * @param signature bytes that represent the signature\n     */\n    function verifyMintNewSignature(\n        Order memory buyOrder,\n        TokenData memory tokenData,\n        uint8 sellerFeePermille,\n        bytes memory signature\n    ) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        MINT_NEW_AND_SELL_ORDER_TYPE_HASH,\n                        _hashSellOrder(buyOrder, sellerFeePermille),\n                        keccak256(\n                            abi.encode(\n                                TOKEN_DATA_TYPE_HASH,\n                                keccak256(bytes(tokenData.tokenURI)),\n                                tokenData.royaltyFee,\n                                tokenData.rightsHolder\n                            )\n                        )\n                    )\n                )\n            );\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        require(buyOrder.seller == signer, \"TradeSignatureVerifier: minter/seller signature is corrupted\");\n    }\n\n    /**\n     * @notice Verifies the seller authorization to sell a token\n     * @param buyOrder struct with buy order data\n     * @param sellerFeePermille sellerFee that is authorized by the seller(this is used in order to\n     * @param signature bytes that represent the signature\n     */\n    function verifyMintExistingSignature(\n        Order memory buyOrder,\n        uint8 sellerFeePermille,\n        bytes memory signature\n    ) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(MINT_EXISTING_AND_SELL_ORDER_TYPE_HASH, _hashSellOrder(buyOrder, sellerFeePermille))\n                )\n            );\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        require(buyOrder.seller == signer, \"TradeSignatureVerifier: minter/seller signature is corrupted\");\n    }\n\n    /**\n     * @notice Verifies the custodial authorization for this withdraw for this assetOwner\n     * @param assetCustodial current asset holder\n     * @param assetOwner real asset owner address\n     * @param wr struct with the withdraw information. What asset and how much of it\n     * @param signature bytes that represent the signature\n     */\n    function verifyWithdrawSignature(\n        address assetCustodial,\n        address assetOwner,\n        WithdrawRequest memory wr,\n        bytes memory signature\n    ) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        WITHDRAW_VOUCHER_TYPE_HASH,\n                        assetOwner,\n                        wr.nonce,\n                        wr.assetAddress,\n                        wr.assetType,\n                        wr.tokenId,\n                        wr.quantity,\n                        wr.timeLimit\n                    )\n                )\n            );\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        require(assetCustodial == signer, \"TradeSignaturesVerifier: withdraw signature corrupted\");\n    }\n}\n"
      },
      "contracts/proxy/ProxyAdmin.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\n// Importing this file so it get compiled and get the artifact to deploy\nimport \"@openzeppelin/contracts/proxy/ProxyAdmin.sol\";\n\n/// @title ProxyAdmin\n"
      },
      "contracts/proxy/TransparentUpgradeableProxy.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\n// Importing this file so it get compiled and get the artifact to deploy\nimport \"@openzeppelin/contracts/proxy/TransparentUpgradeableProxy.sol\";\n\n/// @title TransparentUpgradeableProxy\n///\n/// @dev This contract implements the transparent proxy by openZeppelin that is upgradeable by an admin.\n///         The proxy admin can update the implementation logic\n"
      },
      "contracts/test/TestEnigmaMarket.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../market/EnigmaMarket.sol\";\nimport \"../ERC721/EnigmaNFT721.sol\";\n\n/// @title TestEnigmaMarket\n///\n/// @dev This contract extends from Trade Series for upgradeablity testing\n\ncontract TestEnigmaMarket is EnigmaMarket {\n    uint256 public aNewValue;\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) EnigmaMarket(name, version) {}\n\n    /// @dev makes internal storage visible\n    function getMaxDuration() external view returns (uint256) {\n        return maxDuration;\n    }\n\n    /// @dev makes internal storage visible\n    function getMinDuration() external view returns (uint256) {\n        return minDuration;\n    }\n\n    /// @dev Check that fees add up without increasing costs in productive scenario\n    function getFees(\n        uint256 paymentAmt,\n        address buyingAssetAddress,\n        uint256 tokenId,\n        uint256 sellerFeePermille,\n        uint256 buyerFeePermille,\n        address seller\n    ) internal view virtual override returns (FeeDistributionData memory) {\n        FeeDistributionData memory feeDistributionData =\n            super.getFees(paymentAmt, buyingAssetAddress, tokenId, sellerFeePermille, buyerFeePermille, seller);\n        // Amount of \"fees\" sums up to the paid amount\n        assert(\n            feeDistributionData.fees.assetFee +\n                feeDistributionData.fees.royaltyFee +\n                feeDistributionData.fees.platformFee ==\n                paymentAmt\n        );\n        // Outgoing transfers is the same as incoming one\n\n        assert(\n            feeDistributionData.toRightsHolder + feeDistributionData.toSeller + feeDistributionData.fees.platformFee ==\n                paymentAmt\n        );\n        return feeDistributionData;\n    }\n}\n\ncontract TestAuctionSeller {\n    bool public doFail;\n\n    function doApprove(\n        address enigmaNFT721,\n        address transferProxy,\n        uint256 tokenId\n    ) public {\n        EnigmaNFT721(enigmaNFT721).approve(transferProxy, tokenId);\n    }\n\n    function doCreateReserveAuction(\n        address market,\n        address nftContract,\n        uint256 tokenId,\n        uint256 duration,\n        uint256 reservePrice,\n        PlatformFees calldata platformFees\n    ) public {\n        doFail = true;\n        TestEnigmaMarket(market).createReserveAuction(nftContract, tokenId, duration, reservePrice, platformFees);\n    }\n\n    function doWithdrawTo(address market, address payable user) public {\n        doFail = false;\n        TestEnigmaMarket(market).withdrawTo(user);\n    }\n\n    function setDoFail(bool _doFail) public {\n        doFail = _doFail;\n    }\n\n    /// receive fails on purpose to test this scenario\n    receive() external payable {\n        if (doFail) revert(\"test only\");\n    }\n}\n"
      },
      "contracts/test/TestEnigmaNFT1155.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../ERC1155/EnigmaNFT1155.sol\";\n\n/// @title TestEnigmaNFT1155\n///\n/// @dev This contract extends from BaseEnigmaNFT1155 for upgradeablity testing\n\ncontract TestEnigmaNFT1155 is EnigmaNFT1155 {\n    event CollectibleCreated(uint256 tokenId);\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) EnigmaNFT1155(name, version) {}\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param supply_ tokens amount to be minted\n     * @param fee_ uint256 royalty of the token to be minted.\n     */\n    function mintNew(\n        string memory tokenURI_,\n        uint256 supply_,\n        uint256 fee_\n    ) external {\n        uint256 tokenId = _mintNew(tokenURI_, fee_, msg.sender, msg.sender, 0, msg.sender, _increaseNextId(), supply_);\n        creators[tokenId] = msg.sender;\n        emit CollectibleCreated(tokenId);\n    }\n}\n"
      },
      "contracts/test/TestEnigmaNFT721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../ERC721/BaseEnigmaNFT721.sol\";\n\n/// @title TestEnigmaNFT721\n///\n/// @dev This contract extends from BaseEnigmaNFT721 for upgradeablity testing\n\ncontract TestEnigmaNFT721 is BaseEnigmaNFT721 {\n    event CollectibleCreated(uint256 tokenId);\n\n    /**\n     * @notice public function to mint a new token.\n     * @param tokenURI_ string memory URI of the token to be minted.\n     * @param fee_ uint256 royalty of the token to be minted.\n     */\n    function mintNew(string memory tokenURI_, uint256 fee_) external returns (uint256) {\n        uint256 newItemId = tokenCounter;\n        tokenCounter = tokenCounter + 1;\n        emit CollectibleCreated(newItemId);\n        _creator[newItemId] = msg.sender;\n        _safeMint(msg.sender, newItemId, fee_, msg.sender);\n        _setTokenURI(newItemId, tokenURI_);\n        return newItemId;\n    }\n}\n"
      },
      "contracts/test/TestERC1155.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract TestERC1155 is ERC1155 {\n    constructor() ERC1155(\"https://testERC1155/\") {\n        _mint(msg.sender, 1, 10, \"\");\n    }\n}\n"
      },
      "contracts/test/TestERC721.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract TestERC721 is ERC721 {\n    constructor() ERC721(\"TestERC721\", \"TEST\") {\n        _safeMint(msg.sender, 1);\n    }\n}\n"
      },
      "contracts/test/TestsWyvernProxyRegistry.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IWyvernProxyRegistry.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\n\ncontract TestsWyvernProxy {\n    function proxyType() public pure returns (uint256 proxyTypeId) {\n        return 2;\n    }\n\n    function erc721TransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 tokenId\n    ) external {\n        IERC721Upgradeable(token).transferFrom(from, to, tokenId);\n    }\n\n    function erc1155TransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 value,\n        bytes memory data\n    ) external {\n        IERC1155Upgradeable(token).safeTransferFrom(from, to, tokenId, value, data);\n    }\n\n    function erc1155BatchTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) external {\n        IERC1155Upgradeable(token).safeBatchTransferFrom(from, to, ids, amounts, data);\n    }\n}\n\ncontract TestsWyvernProxyRegistry {\n    /* Authenticated proxies by user. */\n    mapping(address => TestsWyvernProxy) public proxies;\n\n    function registerProxy() public returns (TestsWyvernProxy proxy) {\n        require(address(proxies[msg.sender]) == address(0), \"Proxy mast not me initilized already\");\n        proxy = new TestsWyvernProxy();\n        proxies[msg.sender] = proxy;\n        return proxy;\n    }\n}\n"
      },
      "contracts/test/TestToken.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n    constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {\n        _mint(msg.sender, 1e10);\n    }\n}\n"
      },
      "contracts/test/TestTradeV4.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../market/EnigmaMarket.sol\";\n\n/// @title TestTradeV4\n///\n/// @dev This contract extends from Trade Series for upgradeablity testing\n\ncontract TestTradeV4 is TradeV4 {\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) TradeV4(name, version) {}\n\n    function initialize(\n        ITransferProxy _transferProxy,\n        address _enigmaNFT721Address,\n        address _enigmaNFT1155Address,\n        address _custodialAddress\n    ) external initializer {\n        initializeTradeV4(_transferProxy, _enigmaNFT721Address, _enigmaNFT1155Address, _custodialAddress);\n    }\n}\n"
      },
      "contracts/test/TestTransferGatekepper.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/ITransferGatekeeper.sol\";\n\n/// @title TestTransferGatekeeper\n\ncontract TestTransferGatekeeper is ITransferGatekeeper {\n    string public encodeType;\n    bytes public data;\n    uint256[2] public tokenIds;\n    uint256[2] public amounts;\n\n    function canTransfer(\n        address,\n        address,\n        address,\n        bytes memory encodedData\n    ) external view override returns (bool) {\n        if (bytes(encodeType).length != 0) {\n            string memory _encodeType = abi.decode(encodedData, (string));\n            if (keccak256(bytes(_encodeType)) == keccak256(bytes(\"721\"))) {\n                (, uint256 _tokenId) = abi.decode(encodedData, (string, uint256));\n                return tokenIds[0] == _tokenId;\n            }\n            if (keccak256(bytes(_encodeType)) == keccak256(bytes(\"1155\"))) {\n                (, uint256 _tokenId, uint256 _amount, bytes memory _data) =\n                    abi.decode(encodedData, (string, uint256, uint256, bytes));\n                return (tokenIds[0] == _tokenId &&\n                    amounts[0] == _amount &&\n                    keccak256(bytes(data)) == keccak256(bytes(_data)));\n            }\n            if (keccak256(bytes(_encodeType)) == keccak256(bytes(\"1155_batch\"))) {\n                (, uint256[] memory _tokenIds, uint256[] memory _amounts, bytes memory _data) =\n                    abi.decode(encodedData, (string, uint256[], uint256[], bytes));\n                return (tokenIds[0] == _tokenIds[0] &&\n                    tokenIds[1] == _tokenIds[1] &&\n                    amounts[0] == _amounts[0] &&\n                    amounts[1] == _amounts[1] &&\n                    keccak256(bytes(data)) == keccak256(bytes(_data)));\n            }\n        }\n        return false;\n    }\n\n    function set721Data(uint256 _tokenId) public {\n        encodeType = \"721\";\n        tokenIds[0] = _tokenId;\n    }\n\n    function set1155Data(\n        uint256 _tokenId,\n        uint256 _amount,\n        bytes memory _data\n    ) public {\n        encodeType = \"1155\";\n        tokenIds[0] = _tokenId;\n        amounts[0] = _amount;\n        data = _data;\n    }\n\n    function set1155BatchData(\n        uint256 _tokenId,\n        uint256 _amount,\n        bytes memory _data\n    ) public {\n        encodeType = \"1155_batch\";\n        tokenIds[1] = _tokenId;\n        amounts[1] = _amount;\n        data = _data;\n    }\n}\n"
      },
      "contracts/test/TestWhitelist.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IWhitelist.sol\";\n\n/* solhint-disable */\n\n///This whitelist is for test updating whitelistProxy to allow any address to transfer\ncontract TestWhitelist is IWhitelist {\n    function canTransfer(address) external pure override returns (bool) {\n        return true;\n    }\n}\n"
      },
      "contracts/transferGatekeeping/AccessControlBasedWhitelist.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"../interfaces/IWhitelist.sol\";\n\n/// @title AccessControlBasedWhitelist\n///\n/// @dev This contract is based in OpenZeppelin AccessControl that allows to implement role-based access\n\ncontract AccessControlBasedWhitelist is IWhitelist, AccessControl {\n    // Create a new role identifier for the transfer role\n    bytes32 public constant TRANSFER_ROLE = keccak256(\"TRANSFER_ROLE\");\n\n    constructor(address _trader) {\n        require(_trader != address(0), \"invalid address\");\n        // Grant the transfer role to a specified account\n        _setupRole(TRANSFER_ROLE, _trader);\n        // Grant the contract deployer the default admin role: it will be able\n        // to grant and revoke any roles\n        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n    }\n\n    /**\n     * @param _who the address that wants to transfer a NFT\n     * @dev Returns true if address has permission to transfer a NFT\n     */\n    function canTransfer(address _who) external view override returns (bool) {\n        return hasRole(TRANSFER_ROLE, _who);\n    }\n}\n"
      },
      "contracts/transferGatekeeping/TransferGatekeeperBeacon.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\nimport \"@openzeppelin/contracts/proxy/UpgradeableBeacon.sol\";\n\ncontract TransferGatekeeperBeacon is UpgradeableBeacon {\n    // solhint-disable-next-line\n    constructor(address implementation) public UpgradeableBeacon(implementation) {}\n}\n"
      },
      "contracts/transferGatekeeping/TransferGatekepper.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITransferGatekeeper.sol\";\nimport \"../interfaces/IWhitelist.sol\";\nimport \"../interfaces/IWhitelistHandler.sol\";\nimport \"../interfaces/IWyvernProxyRegistry.sol\";\n\n/// @title TransferGatekeeper\n///\n/// @dev This contract abstracts the transfer gatekeeping implementation to the caller, ie, ERC721 & ERC1155 tokens\n///\t\t\t The logic can be replaced and the `canTransfer` will invoke the proper target function. It's important\n///\t\t\t to mention that no storage is shared between this contract and the corresponding implementation\n///\t\t\t call is used instead of delegate call to avoid different implementations storage compatibility.\ncontract TransferGatekeeper is ITransferGatekeeper, IWhitelistHandler, Ownable {\n    event WhitelistChanged(address indexed _oldImplementation, address indexed _newImplementation);\n    event RegistryChanged(address indexed _oldImplementation, address indexed _newImplementation);\n\n    // The address of the whitelist implementation\n    IWhitelist public whitelist;\n\n    // The Wyvern compatible registry on wich to very user-proxy\n    IWyvernProxyRegistry public registry;\n\n    // Allowd the owner to enable/disable the registry\n    bool public useRegistry;\n\n    constructor(IWhitelist _whitelist) {\n        require(address(_whitelist) != address(0), \"invalid address\");\n        whitelist = _whitelist;\n        useRegistry = false;\n    }\n\n    /**\n        @notice Legacy function to support retrocompatibility on migration\n                from WhitelistProxy to TransferGatekeeper\n     */\n    function canTransfer(address _proxy) external view returns (bool) {\n        return whitelist.canTransfer(_proxy);\n    }\n\n    /**\n     * @inheritdoc ITransferGatekeeper\n     */\n    function canTransfer(\n        address _from,\n        address,\n        address _proxy,\n        bytes memory\n    ) external view override returns (bool) {\n        return\n            _from == _proxy || // the owner is executing the transfer\n            whitelist.canTransfer(_proxy) || // the executor is whitelisted\n            canTransferFromProxy(_from, _proxy); // the executor is an authorized proxy\n    }\n\n    function canTransferFromProxy(address _from, address _proxy) internal view returns (bool) {\n        if (!useRegistry || address(registry) == address(0)) return false;\n        address registryProxy = registry.proxies(_from);\n        return address(registryProxy) == _proxy;\n    }\n\n    /**\n     * @notice Sets the new address on wich to check whitelisting and enables its use\n     * @param _registry the address of the new proxy registry implementation\n     */\n    function setRegistry(IWyvernProxyRegistry _registry) external onlyOwner {\n        require(address(_registry) != address(0), \"setRegistry: invalid address\");\n        emit RegistryChanged(address(registry), address(_registry));\n        registry = _registry;\n        setUseRegistry(true);\n    }\n\n    /**\n     * @notice Enables/disable the registry use\n     * @param _useRegistry true if you want to enable it\n     */\n    function setUseRegistry(bool _useRegistry) public onlyOwner {\n        require(address(registry) != address(0), \"Cannot change registry use with empty address\");\n        useRegistry = _useRegistry;\n    }\n\n    /**\n     * @notice Sets the new address on wich to check whitelisting\n     * @param _whitelist the address of the new whitelist implementation\n     */\n    function setWhitelist(IWhitelist _whitelist) external override onlyOwner {\n        require(address(_whitelist) != address(0), \"updateWhitelist: invalid address\");\n        emit WhitelistChanged(address(whitelist), address(_whitelist));\n        whitelist = _whitelist;\n    }\n}\n"
      },
      "contracts/TransferProxy.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./interfaces/ITransferProxy.sol\";\n\ncontract TransferProxy is ITransferProxy {\n    event OperatorChanged(address indexed from, address indexed to);\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    address public owner;\n    address public operator;\n\n    constructor() {\n        owner = msg.sender;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n\n    modifier onlyOwner() {\n        require(owner == msg.sender, \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    modifier onlyOperator() {\n        require(operator == msg.sender, \"OperatorRole: caller does not have the Operator role\");\n        _;\n    }\n\n    /** change the OperatorRole from contract creator address to trade contractaddress\n            @param _operator :trade address \n        */\n\n    function changeOperator(address _operator) external onlyOwner returns (bool) {\n        require(_operator != address(0), \"Operator: new operator is the zero address\");\n        emit OperatorChanged(operator, _operator);\n        operator = _operator;\n        return true;\n    }\n\n    /** change the Ownership from current owner to newOwner address\n        @param newOwner : newOwner address */\n\n    function ownerTransfership(address newOwner) external onlyOwner returns (bool) {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(owner, newOwner);\n        owner = newOwner;\n        return true;\n    }\n\n    function erc721safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 tokenId\n    ) external override onlyOperator {\n        IERC721Upgradeable(token).safeTransferFrom(from, to, tokenId);\n    }\n\n    function erc1155safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 value,\n        bytes calldata data\n    ) external override onlyOperator {\n        IERC1155Upgradeable(token).safeTransferFrom(from, to, tokenId, value, data);\n    }\n\n    function erc20safeTransferFrom(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    ) external override onlyOperator {\n        require(IERC20(token).transferFrom(from, to, value), \"failure while transferring\");\n    }\n}\n"
      },
      "contracts/utils/AuthorizationBitmap.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\n/**\n * @dev This implementation is similar to the OZ one but due to the fact we are using an old version\n *\t\t\twe weren't able to import it.\n */\nlibrary AuthorizationBitmap {\n    struct Bitmap {\n        mapping(uint256 => uint256) map_;\n    }\n\n    function isAuthProcessed(Bitmap storage bitmap, uint256 index) internal view returns (bool) {\n        return isAuthProcessed(bitmap.map_, index);\n    }\n\n    function setAuthProcessed(Bitmap storage bitmap, uint256 index) internal {\n        setAuthProcessed(bitmap.map_, index);\n    }\n\n    /**\n     * @notice Verifies if this authorization index has already been processed\n     * @param _index of the Authorization signature you want to know it's been processed\n     */\n    function isAuthProcessed(mapping(uint256 => uint256) storage _map, uint256 _index) internal view returns (bool) {\n        uint256 wordIndex = _index / 256;\n        uint256 bitIndex = _index % 256;\n        uint256 processedWord = _map[wordIndex];\n        uint256 mask = (1 << bitIndex);\n        return processedWord & mask == mask;\n    }\n\n    /**\n     * @notice Sets this authorization index as processed\n     * @param _index of the Authorization signature you want to mark as processed\n     */\n    function setAuthProcessed(mapping(uint256 => uint256) storage _map, uint256 _index) internal {\n        uint256 wordIndex = _index / 256;\n        uint256 bitIndex = _index % 256;\n        _map[wordIndex] = _map[wordIndex] | (1 << bitIndex);\n    }\n}\n"
      },
      "contracts/utils/AuthorizedMintingNFT.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/// @title EnigmaNFT721\n///\nimport \"@openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol\";\nimport \"../utils/EIP712.sol\";\n\ncontract AuthorizedMintingNFT is EIP712 {\n    using ECDSAUpgradeable for bytes32;\n    bytes32 private constant NFT_MINTING_VOUCHER_TYPE_HASH =\n        keccak256(\"NFTMintingVoucher(string tokenURI,address minter,uint256 supply,uint256 nonce)\");\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) EIP712(name, version) {}\n\n    /**\n     * @notice Internal function to verify a sign to mint tokens\n     * Reverts if the sign verification fails.\n     * @param tokenURI string memory URI of the token to be minted.\n     * @param signature signature that authorizes the user to mint these tokens\n     * @param minter Address authorized to mint\n     * @param nonce nonce of the authorization\n     * @param supply amount of tokens to be minted\n     * @param authorizer address of the wallet that authorizes minters\n     */\n    function verifySign(\n        string memory tokenURI,\n        address minter,\n        uint256 supply,\n        uint256 nonce,\n        bytes memory signature,\n        address authorizer\n    ) internal view {\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(abi.encode(NFT_MINTING_VOUCHER_TYPE_HASH, keccak256(bytes(tokenURI)), minter, supply, nonce))\n            );\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        require(authorizer == signer, \"Owner sign verification failed\");\n    }\n}\n"
      },
      "contracts/utils/EIP712.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// solhint-disable\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * NOTE: This is a slighltly modified version of the EIP712 implementation by OpenZeppelin. It was copy pasted to\n * remove the caching mechanism that is not needed and it breaks things because we are using proxies.\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n    /* solhint-disable var-name-mixedcase */\n    bytes32 private immutable _HASHED_NAME;\n    bytes32 private immutable _HASHED_VERSION;\n    bytes32 private immutable _TYPE_HASH;\n\n    /* solhint-enable var-name-mixedcase */\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    constructor(string memory name, string memory version) internal {\n        bytes32 hashedName = keccak256(bytes(name));\n        bytes32 hashedVersion = keccak256(bytes(version));\n        bytes32 typeHash =\n            keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n        _HASHED_NAME = hashedName;\n        _HASHED_VERSION = hashedVersion;\n        _TYPE_HASH = typeHash;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view virtual returns (bytes32) {\n        return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n    }\n\n    function _buildDomainSeparator(\n        bytes32 typeHash,\n        bytes32 name,\n        bytes32 version\n    ) private view returns (bytes32) {\n        return keccak256(abi.encode(typeHash, name, version, _getChainId(), address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), structHash));\n    }\n\n    function _getChainId() private view returns (uint256 chainId) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            chainId := chainid()\n        }\n    }\n}\n"
      },
      "contracts/utils/MintNFTEvent.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\n\n/// @title MintNFTEventEmitter\n\ninterface MintNFTEvent {\n    event MintNewNFT(\n        uint256 tokenId,\n        address creator,\n        address receiver,\n        string tokenURI,\n        uint256 quantity,\n        uint256 royaltyFees,\n        address rightsHolder,\n        uint256 nonce\n    );\n\n    event MintExistingNFT(uint256 tokenId, address to, uint256 amount, uint256 nonce);\n}\n"
      },
      "contracts/utils/Types.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\n/* An ECDSA signature. */\nstruct Signature {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n"
      },
      "contracts/vault/Vault.sol": {
        "content": "// SPDX-License-Identifier:UNLICENSED\npragma solidity ^0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155HolderUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721HolderUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/cryptography/ECDSAUpgradeable.sol\";\nimport \"../utils/EIP712.sol\";\nimport \"../utils/AuthorizationBitmap.sol\";\nimport \"../utils/Types.sol\";\n\n/// @notice A RBAC based Vault contract:\n///             - Requires a signed payload\n///             - If signature is ok, the transaction will be forwarded using call\n/// @dev This contract was inspired by\n///      https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/MinimalForwarder.sol\ncontract Vault is AccessControlUpgradeable, ERC1155HolderUpgradeable, ERC721HolderUpgradeable, EIP712 {\n    using AuthorizationBitmap for AuthorizationBitmap.Bitmap;\n\n    bytes32 public constant ADMIN_ROLE = 0x00;\n    bytes32 public constant SIGNER_ROLE = bytes32(uint256(0x01));\n\n    AuthorizationBitmap.Bitmap private authorizationBitmap;\n    bytes32 private constant FORWARD_REQUEST_TYPE_HASH =\n        keccak256(\n            // solhint-disable max-line-length\n            \"ForwardRequest(address to,uint256 value,uint256 nonce,bytes data,uint256 timeLimit)\"\n        );\n\n    struct ForwardRequest {\n        address to;\n        uint256 value;\n        uint256 nonce;\n        bytes data;\n        uint256 timeLimit;\n    }\n\n    // Though the TradeV4 contract is upgradeable, we still have to initialize the implementation through the\n    // constructor. This is because we chose to import the non upgradeable EIP712 as it does not have storage\n    // variable(which actually makes it upgradeable) as it only uses immmutable variables. This has several advantages:\n    // - We can import it without worrying the storage layout\n    // - Is more efficient as there is no need to read from the storage\n    // Note: The cache mechanism will NOT be used here as the address will differ from the one calculated in the\n    // constructor due to the fact that when the contract is operating we will be using delegatecall, meaningn\n    // that the address will be the one from the proxy as opposed to the implementation's during the\n    // constructor execution\n    // solhint-disable-next-line no-empty-blocks\n    constructor(string memory name, string memory version) EIP712(name, version) {}\n\n    function initialize(address admin, address[] calldata signers) public initializer {\n        __AccessControl_init();\n        __ERC1155Holder_init();\n        __ERC721Holder_init();\n        _setupRole(ADMIN_ROLE, admin);\n        // Setup signers\n        uint256 signersLength = signers.length;\n        for (uint256 i = 0; i < signersLength; i++) {\n            _setupRole(SIGNER_ROLE, signers[i]);\n        }\n    }\n\n    /// @notice Signature verification function.\n    /// @param req request to be checked against the signature\n    /// @param signature signature that authorizes the msg.sender to execute req\n    /// @dev signature payload is made by req.to + req.value + req.nonce + keccak256(req.data) + the domain\n    function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {\n        require(!authorizationBitmap.isAuthProcessed(req.nonce), \"Vault: already processed\");\n        bytes32 digest =\n            _hashTypedDataV4(\n                keccak256(\n                    abi.encode(\n                        FORWARD_REQUEST_TYPE_HASH,\n                        req.to,\n                        req.value,\n                        req.nonce,\n                        keccak256(req.data),\n                        req.timeLimit\n                    )\n                )\n            );\n        address signer = ECDSAUpgradeable.recover(digest, signature);\n        return hasRole(SIGNER_ROLE, signer);\n    }\n\n    /// @notice Executes a transaction if the provided signature was made by someone whose role is SIGNER_ROLE.\n    ///         - It will use this contract as msg.sender (ie. execute a call)\n    ///         - Requests can only be executed once so they cannot be replayed\n    ///         - It doesn't care who the signer is as long as the signature is ok\n    /// @param req Request to be executed\n    /// @param signature Signature made by a SIGNER that matches the req\n    function execute(ForwardRequest calldata req, bytes calldata signature)\n        public\n        payable\n        returns (bool, bytes memory)\n    {\n        require(verify(req, signature), \"Vault: signature does not match request\");\n        require(req.timeLimit >= block.timestamp, \"Vault: forward request expired\");\n        authorizationBitmap.setAuthProcessed(req.nonce);\n\n        (bool success, bytes memory returndata) =\n            // All the gas is forwarded as this is going to be used by Enigma and not the users\n            // This is not a relayer as GSN\n            req.to.call{ value: req.value }(req.data);\n\n        require(success, _getRevertMsg(returndata));\n        return (success, returndata);\n    }\n\n    /// @dev https://ethereum.stackexchange.com/a/83577\n    function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n        // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n        if (_returnData.length < 68) return \"Transaction reverted silently\";\n\n        // solhint-disable-next-line\n        assembly {\n            // Slice the sighash.\n            _returnData := add(_returnData, 0x04)\n        }\n        return abi.decode(_returnData, (string)); // All that remains is the revert string\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {
        "": {
          "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1"
        }
      }
    }
  }}