Contract 0x6ADFcE65176C0f01c5b4f91D163c833859CF2a9e

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x5108730caf1f8388a718ba5c623b0044739db5a0a272955af39e3f48c1c3d9d9Set Approval For...325334202022-08-31 23:18:01211 days 17 hrs ago0x0121900f6d368fbd1b565b8a7d96a0ec6d0764f3 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.0014325131
0xedf7e39446b6309e18f95caf8ed908884fcb0f645f0f0a8c35f448f79dbaea1fSet Approval For...320064172022-08-17 19:55:57225 days 20 hrs ago0x0121900f6d368fbd1b565b8a7d96a0ec6d0764f3 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.0014325131
0x20b330a74004de3acb69f19506cca1336f215b0e9c1bc07cd5f15852aedb5551Mint With URI308944162022-07-19 10:31:55255 days 6 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.030192587364 150.01186162
0xe084f51c8d5a48353a4fbc68bb12eb4da2818b27653bab7c7bc50cf1e753edf9Set Approval For...302251902022-07-01 19:53:05272 days 21 hrs ago0x0121900f6d368fbd1b565b8a7d96a0ec6d0764f3 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.002310550
0xb0f457081a55ebc342a37bfc22a18d5717f78b40c85aa0257619d19758821aa9Set Approval For...301310572022-06-29 9:11:36275 days 7 hrs ago0xddf61aa823d347399e07e9bed1c835557438e34b IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.002310550
0x52e6c4fc605ab98312b8194680d4e527d73a8b211f0a26ded00793744b22930cSet Approval For...301307742022-06-29 9:01:54275 days 7 hrs ago0x79c8e6322e1febcb3085a9c05ab6481d3995b07a IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.002310550
0x43f02eb79809ea1d5032bb38120580b2ee4eaeb3b0220a946084f3ee729e9568Mint With URI298646672022-06-22 10:49:35282 days 6 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.030190200013 150.000000065
0x1e385a55074e0debfcd3d8258605991e0b07e9940209c63125c1d930d8a5f937Mint With URI298602692022-06-22 8:03:11282 days 8 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.030190200014 150.00000007
0x2208cfbe77df64575c826706f2c41b7c6c7a205f59203962f3a5556d7aea1afeMint With URI298581362022-06-22 6:43:29282 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.03408715108 169.36200032
0xb9e419c436e29d51eab293f058e55765262dddb5dcf1913d57714a75a4996a39Mint With URI248382812022-02-12 3:46:06412 days 13 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.030309158448 150.591045015
0xe2b7795784ddd4e9f8b4344e747bb0ad9d85e4122fedaca374330ee3ef4c2923Mint With URI245656982022-02-05 4:09:08419 days 12 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.001063739096 5.285187395
0x7f7cecdd2b4d6f6e7e24e1d41edff5624fc669b3ac7e071cf2403749c831af18Mint With URI245414562022-02-04 13:09:37420 days 3 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.029655431477 147.34300275
0xe99ddcffdb97c7ea487c357f3fc4a55a96109594744e5b901df2a214de43d6bcMint With URI242322272022-01-27 16:33:08428 days 22 mins ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.078518374872 390.118522925
0x44c620bda1cbee07043fc7eab61a5a84b224490d353633f187fa5af9addca5edMint With URI241599162022-01-25 21:01:10429 days 19 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.053208775636 264.367786415
0xcfd2d3fd828347dbade3ddc3dc1ee6dd7c21638617b131d4f535df8b57d3a189Transfer From240000242022-01-21 21:13:12433 days 19 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.004927376715 115.071852295
0x75c743b111330c0023ced060631b3e2fb49d08be76705fa99b73d11c2207a77aSet Approval For...239379472022-01-20 7:41:36435 days 9 hrs ago0x0121900f6d368fbd1b565b8a7d96a0ec6d0764f3 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.009533037732206.298154778
0x902b89e2ce4056280adb13ec6f4153398893b59e542607d42e983bcd44a6f026Set Approval For...239355052022-01-20 6:13:08435 days 10 hrs ago0xddf61aa823d347399e07e9bed1c835557438e34b IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.00149554260732.364046906
0xcf8689d9c6ad744756070b21620c49872cceee3e2a4eecc8bcfadc5ce6a619e2Mint With URI239352332022-01-20 6:03:48435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.03219784991 174.828688535
0x50c273b44b4506e6c950f2006b98da8b37b0dbb1e796f43a1698bdba9b6ced53Mint With URI239352242022-01-20 6:03:26435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.035187420484 174.828688535
0xb03ae3c9647d3ce31b0f8c5d6ede4345277348b2fdb55358c4bfe643f9b3a48cMint With URI239351872022-01-20 6:02:12435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.034182097001 185.602802885
0x769551f330c057cec959c9dfb2207f482cf3868c64d09f2d37443972affd30f7Mint With URI239351792022-01-20 6:01:56435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.037355904931 185.602802885
0xe73839dd28fbe1b5a11c8c2225f389510afd6f226b1d7db865ec2cee70ddd374Mint With URI239351332022-01-20 6:00:20435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.045260852506 245.758505855
0xecf073b344a531b1a9bc1301b190a46bd1e4e5c9ada394a0371ebbf93c268630Mint With URI239351252022-01-20 6:00:04435 days 10 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.049463322956 245.758505855
0x49f5760fbd388c4cfb869757c58a549c0416e5677de6779a269048f838242806Mint With URI239348212022-01-20 5:49:36435 days 11 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.045479217257 246.94418823
0xc8a1a1c239fda6467f47e5c03a639f845a794bf34024e1e24b1b3cb1df0dfbc9Mint With URI239348142022-01-20 5:49:22435 days 11 hrs ago0x69f8cb5bada13c1c419191c9c941a79eb2fe0967 IN  0x6adfce65176c0f01c5b4f91d163c833859cf2a9e0 MATIC0.049701962876 246.94418823
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GryphMarketplace

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 45 : GryphMarketplace.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "mintpress/contracts/Mintpress.sol";

contract GryphMarketplace is Mintpress {
  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;

  /**
   * @dev Constructor function
   */
  constructor(
    string memory _name,
    string memory _symbol,
    string memory _baseTokenURI,
    string memory _contractURI
  ) Mintpress(
    _name,
    _symbol,
    _baseTokenURI,
    _contractURI
  ) {}

  /**
   * @dev Mints `tokenId`, classifies it as `classId` and 
   *      transfers to `recipient`
   */
  function mintWithURI(
    uint256 classId, 
    uint256 tokenId, 
    address recipient, 
    string memory uri
  ) public virtual onlyOwner {
    //mint
    mint(classId, tokenId, recipient);
    //and set token URI
    setTokenURI(tokenId, uri);
  }

  /**
   * @dev Sets `uri` as the URI of `tokenId`.
   */
  function setTokenURI(uint256 tokenId, string memory uri) 
    public virtual onlyOwner 
  {
    _tokenURIs[tokenId] = uri;
  }

  /**
   * @dev override; super defined in MintpressInformable; Returns the 
   *      URI of the given `tokenId`. Example Format:
   *      {
   *        "description": "Friendly OpenSea Creature", 
   *        "external_url": "https://mywebsite.com/3", 
   *        "image": "https://mywebsite.com/3.png", 
   *        "name": "My NFT",
   *        "attributes": {
   *          "background_color": "#000000",
   *          "animation_url": "",
   *          "youtube_url": ""
   *        } 
   *      }
   */
  function tokenURI(uint256 tokenId) 
    public 
    view 
    virtual 
    override
    returns(string memory) 
  {
    uint256 classId = classOf(tokenId);

    require(
      classId > 0, 
      "Token is not apart of a multiclass"
    ); 

    if (bytes(_tokenURIs[tokenId]).length > 0) {
      return _tokenURIs[tokenId];
    }
    
    return classURI(classId);
  }
}

File 2 of 45 : Mintpress.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//implementation of ERC721
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
//implementation of ERC721 where tokens can be irreversibly 
//burned (destroyed).
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
//abstract of cross compliant royalties in multi classes
import "./Mintpress/abstractions/MintpressChargable.sol";
//abstract that allows tokens to be listed and exchanged considering 
//royalty fees in multi classes
import "./Mintpress/abstractions/MintpressExchangable.sol";
//abstract defines common publicly accessable contract methods
import "./Mintpress/abstractions/MintpressInformable.sol";
//abstract that opens the order book methods
import "./Mintpress/abstractions/MintpressListable.sol";
//abstract that opens up various minting methods
import "./Mintpress/abstractions/MintpressMintable.sol";
//opens up the pausible methods
import "./Mintpress/abstractions/MintpressPausable.sol";
//passes multi class methods to Mintpress
import "./Mintpress/abstractions/MintpressSortable.sol";
//abstract of a BEP721 that pre defines total supply
import "./BEP721/BEP721.sol";
//rarible royalties v2 library
import "./Rarible/LibRoyaltiesV2.sol";

contract Mintpress is
  ERC721,
  BEP721,
  MintpressSortable,
  MintpressMintable,
  MintpressListable,
  MintpressChargable,
  MintpressPausable,
  MintpressExchangable,
  MintpressInformable,
  ERC721Burnable
{
  /**
   * @dev Constructor function
   */
  constructor (
    string memory _name, 
    string memory _symbol, 
    string memory _baseTokenURI, 
    string memory _contractURI
  ) 
    ERC721(_name, _symbol)
    MintpressInformable(_baseTokenURI, _contractURI)
  {}

  /**
   * @dev override; super defined in MultiClass; Returns the class 
   *      given `tokenId`
   */
  function classOf(uint256 tokenId) 
    public 
    virtual 
    view 
    override(MintpressInformable, MultiClass, MultiClassFees) 
    returns(uint256) 
  {
    return super.classOf(tokenId);
  }

  /**
   * @dev override; super defined in MultiClassSupply; Returns true if 
   *      `classId` supply and size are equal
   */
  function classFilled(uint256 classId) 
    public 
    view 
    virtual 
    override(MintpressMintable, MultiClassSupply) 
    returns(bool)
  {
    return super.classFilled(classId);
  }

  /**
   * @dev override; super defined in MultiClassSupply; Returns the  
   *      total possible supply size of `classId`
   */
  function classSize(uint256 classId) 
    public 
    view 
    virtual 
    override(MintpressMintable, MultiClassSupply) 
    returns(uint256)
  {
    return super.classSize(classId);
  }

  /**
   * @dev override; super defined in MultiClassSupply; Returns the  
   *      current supply size of `classId`
   */
  function classSupply(uint256 classId) 
    public 
    view 
    virtual 
    override(MintpressMintable, MultiClassSupply) 
    returns(uint256)
  {
    return super.classSupply(classId);
  }

  /**
   * @dev override; super defined in MultiClassURIStorage; Returns the 
   *      data of `classId`
   */
  function classURI(uint256 classId) 
    public 
    virtual 
    view 
    override(MintpressInformable, MultiClassURIStorage) 
    returns(string memory) 
  {
    return super.classURI(classId);
  }

  /**
   * @dev override; super defined in MultiClassOrderBook; Returns the 
   *      amount a `tokenId` is being offered for.
   */
  function listingOf(uint256 tokenId) 
    public 
    view 
    virtual 
    override(MultiClassOrderBook, MintpressExchangable) 
    returns(uint256) 
  {
    return super.listingOf(tokenId);
  }

  /**
   * @dev override; super defined in ERC721; Specifies the name by 
   *      which other contracts will recognize the BEP-721 token 
   */
  function name() 
    public virtual view override(IBEP721, ERC721) returns(string memory) 
  {
    return super.name();
  }

  /**
   * @dev override; super defined in Ownable; Returns the address of 
   *      the current owner. 
   */
  function owner() 
    public 
    view 
    virtual 
    override(Ownable, MintpressMintable) 
    returns (address) 
  {
    return super.owner();
  }
  
  /**
   * @dev override; super defined in ERC721; Returns the owner of 
   *      a `tokenId`
   */
  function ownerOf(uint256 tokenId) 
    public 
    view 
    virtual 
    override(IERC721, ERC721, MultiClassOrderBook, MintpressExchangable) 
    returns(address) 
  {
    return super.ownerOf(tokenId);
  }

  /**
   * @dev References `classId` to `data` and `size`
   */
  function register(
    uint256 classId, 
    uint256 size,
    string memory uri
  ) external virtual onlyOwner {
    _setClassURI(classId, uri);
    //if size was set, fix it. Setting a zero size means no limit.
    if (size > 0) {
      _fixClassSize(classId, size);
    }
  }

  /**
   * @dev References `classId` to `data` and `size`
   */
  function registerToCreator(
    uint256 classId, 
    uint256 size,
    string memory uri,
    address creator
  ) public virtual onlyOwner {
    _setClassURI(classId, uri);
    //if size was set, fix it. Setting a zero size means no limit.
    if (size > 0) {
      _fixClassSize(classId, size);
    }

    if (creator == address(0)) {
      creator = owner();
    }

    _setCreator(classId, creator);
  }

  /**
   * @dev Rarible support interface
   */
  function supportsInterface(bytes4 interfaceId) 
    public view virtual override(ERC721, IERC165) returns(bool)
  {
    if (interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) {
      return true;
    }

    if (interfaceId == MintpressChargable._INTERFACE_ID_ERC2981) {
      return true;
    }

    return super.supportsInterface(interfaceId);
  }

  /**
   * @dev override; super defined in ERC721; A concise name for the token, 
   *      comparable to a ticker symbol 
   */
  function symbol() 
    public 
    virtual 
    view 
    override(IBEP721, ERC721) returns(string memory) 
  {
    return super.symbol();
  }

  /**
   * @dev override; super defined in MintpressInformable; Returns the 
   *      URI of the given `tokenId`. Example Format:
   *      {
   *        "description": "Friendly OpenSea Creature", 
   *        "external_url": "https://mywebsite.com/3", 
   *        "image": "https://mywebsite.com/3.png", 
   *        "name": "My NFT",
   *        "attributes": {
   *          "background_color": "#000000",
   *          "animation_url": "",
   *          "youtube_url": ""
   *        } 
   *      }
   */
  function tokenURI(uint256 tokenId) 
    public 
    view 
    virtual 
    override(ERC721, MintpressInformable)
    returns(string memory) 
  {
    return super.tokenURI(tokenId);
  }

  /**
   * @dev override; super defined in MultiClassSupply; Increases the  
   *      supply of `classId` by `amount`
   */
  function _addClassSupply(uint256 classId, uint256 amount) 
    internal virtual override(MintpressMintable, MultiClassSupply)
  {
    super._addClassSupply(classId, amount);
  }

  /**
   * @dev override; super defined in BEP721; Adds to the overall amount 
   *      of tokens generated in the contract
   */
  function _addSupply(uint256 supply) 
    internal virtual override(BEP721, MintpressMintable)
  {
    super._addSupply(supply);
  }

  /**
   * @dev Resolves duplicate _beforeTokenTransfer method definition
   * between ERC721 and ERC721Pausable
   */
  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
  ) internal virtual override(ERC721, ERC721Pausable) {
    super._beforeTokenTransfer(from, to, tokenId);
  }

  /**
   * @dev override; super defined in MultiClass; Maps `tokenId` 
   *      to `classId`
   */
  function _classify(uint256 tokenId, uint256 classId) 
    internal virtual override(MintpressMintable, MultiClass)
  {
    super._classify(tokenId, classId);
  }
  
  /**
   * @dev override; super defined in MultiClassListings; Removes 
   *      `tokenId` from the order book.
   */
  function _delist(uint256 tokenId) 
    internal 
    virtual 
    override(MintpressExchangable, MultiClassOrderBook) 
  {
    return super._delist(tokenId);
  }
  
  /**
   * @dev Pays the amount to the recipients
   */
  function _escrowFees(uint256 tokenId, uint256 amount)
    internal 
    virtual 
    override(MintpressExchangable, MintpressMintable, MultiClassFees) 
    returns(uint256) 
  {
    return super._escrowFees(tokenId, amount);
  }

  /**
   * @dev override; super defined in Context; Returns the address of  
   *      the method caller
   */
  function _msgSender() 
    internal 
    view 
    virtual 
    override(
      Context, 
      MultiClassOrderBook, 
      MintpressMintable, 
      MintpressExchangable
    ) 
    returns(address) 
  {
    return super._msgSender();
  }
    
  /**
   * @dev override; super defined in ERC721; Same as `_safeMint()`, 
   *      with an additional `data` parameter which is forwarded in 
   *      {IERC721Receiver-onERC721Received} to contract recipients.
   */
  function _safeMint(address to, uint256 tokenId) 
    internal virtual override(ERC721, MintpressMintable)
  {
    super._safeMint(to, tokenId);
  }
  
  /**
   * @dev override; super defined in ERC721; Transfers `tokenId` 
   *      from `from` to `to`.
   */
  function _transfer(address from, address to, uint256 tokenId) 
    internal virtual override(ERC721, MintpressExchangable) 
  {
    return super._transfer(from, to, tokenId);
  }
}

File 3 of 45 : ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 4 of 45 : ERC721Burnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "../../../utils/Context.sol";

/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

File 5 of 45 : MintpressChargable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//labels contract owner only methods
import "@openzeppelin/contracts/access/Ownable.sol";
//interface of an ERC2981 compliant contract
import "../../ERC2981/IERC2981.sol";
//interface of a Rarible Royalties v2 compliant contract
import "../../Rarible/RoyaltiesV2.sol";
//abstract that considers royalty fees in multi classes
import "../../MultiClass/abstractions/MultiClassFees.sol";

/**
 * @dev Abstract of cross compliant royalties in multi classes
 */
abstract contract MintpressChargable is 
  MultiClassFees, 
  RoyaltiesV2, 
  Ownable 
{
  /*
   * bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
   */
  bytes4 internal constant _INTERFACE_ID_ERC2981 = 0x2a55205a;

  /**
   * @dev Sets a fee that will be collected during the exchange method
   */
  function allocate(uint256 classId, address recipient, uint96 fee)
    external virtual onlyOwner
  {
    _allocateFee(classId, recipient, fee);
  }

  /**
   * @dev Removes a fee
   */
  function deallocate(uint256 classId, address recipient)
    external virtual onlyOwner
  {
    _deallocateFee(classId, recipient);
  }

  /**
   * @dev Removes a fee
   */
  function deallocateAll(uint256 classId)
    external virtual onlyOwner
  {
    _deallocateFees(classId);
  }
  
  /**
   * @dev implements Rari getRaribleV2Royalties()
   */
  function getRaribleV2Royalties(uint256 tokenId) 
    external view virtual returns(LibPart.Part[] memory) 
  {
    uint256 classId = classOf(tokenId);
    uint256 size = _recipients[classId].length;
    //this is how to set the size of an array in memory
    LibPart.Part[] memory royalties = new LibPart.Part[](size);
    for (uint i = 0; i < size; i++) {
      address recipient = _recipients[classId][i];
      royalties[i] = LibPart.Part(
        payable(recipient), 
        _fee[classId][recipient]
      );
    }

    return royalties;
  }

  /**
   * @dev implements ERC2981 `royaltyInfo()`
   */
  function royaltyInfo(uint256 _tokenId, uint256 _salePrice) 
    external 
    view 
    virtual 
    returns(address receiver, uint256 royaltyAmount) 
  {
    uint256 classId = classOf(_tokenId);
    if (_recipients[classId].length == 0) {
      return (address(0), 0);
    }

    address recipient = _recipients[classId][0];
    return (
      payable(recipient), 
      (_salePrice * _fee[classId][recipient]) / 10000
    );
  }
}

File 6 of 45 : MintpressExchangable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Abstract that allows tokens to be listed
 * and exchanged considering royalty fees in multi classes
 */
abstract contract MintpressExchangable {
  // manual ReentrancyGuard
  bool private _exchanging = false;

  /**
   * @dev abstract; defined in MultiClassOrderBook; Returns the 
   *      amount a `tokenId` is being offered for.
   */
  function listingOf(uint256 tokenId) 
    public view virtual returns(uint256);
  
  /**
   * @dev abstract; defined in ERC721; Returns the owner of a `tokenId`
   */
  function ownerOf(uint256 tokenId) 
    public view virtual returns(address);

  /**
   * @dev abstract; defined in MultiClassOrderBook; Removes `tokenId` 
   *      from the order book.
   */
  function _delist(uint256 tokenId) internal virtual;
  
  /**
   * @dev abstract; defined in MultiClassOrderBook; Pays the amount 
   *      to the recipients
   */
  function _escrowFees(uint256 tokenId, uint256 amount)
    internal virtual returns(uint256);
  
  /**
   * @dev abstract; defined in Context; Returns the address of the 
   *      method caller
   */
  function _msgSender() internal view virtual returns(address);
  
  /**
   * @dev abstract; defined in ERC721; Transfers `tokenId` from 
   *      `from` to `to`.
   */
  function _transfer(address from, address to, uint256 tokenId) 
    internal virtual;
  
  /**
   * @dev Allows for a sender to exchange `tokenId` for the listed amount
   */
  function exchange(uint256 tokenId) 
    external virtual payable 
  {
    //get listing
    uint256 listing = listingOf(tokenId);
    //should be a valid listing
    require(listing > 0, "Token is not listed");
    //value should equal the listing amount
    require(
      msg.value == listing,
      "Amount sent does not match the listing amount"
    );
    // manual ReentrancyGuard
    require(!_exchanging, "reentrant call");
    _exchanging = true;

    //payout the fees
    uint256 remainder = _escrowFees(tokenId, msg.value);
    //get the token owner
    address payable tokenOwner = payable(ownerOf(tokenId));
    //send the remainder to the token owner
    tokenOwner.transfer(remainder);
    //transfer token from owner to buyer
    _transfer(tokenOwner, _msgSender(), tokenId);
    //now that the sender owns it, delist it
    _delist(tokenId);

    _exchanging = false;
  }
}

File 7 of 45 : MintpressInformable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//abstract of an OpenSea compliant contract
import "../../OpenSea/ERC721OpenSea.sol";

/**
 * @dev Abstract defines common publicly accessable contract methods
 */
abstract contract MintpressInformable is ERC721OpenSea {
  /**
   * @dev abstract; defined in MultiClass; Returns the class 
   *      given `tokenId`
   */
  function classOf(uint256 tokenId) 
    public virtual view returns(uint256);

  /**
   * @dev abstract; defined in MultiClassURIStorage; Returns the 
   *      data of `classId`
   */
  function classURI(uint256 classId) 
    public virtual view returns(string memory);

  /**
   * @dev Constructor function
   */
  constructor (string memory _baseTokenURI, string memory _contractURI) 
    ERC721OpenSea(_baseTokenURI, _contractURI)
  {}

  /**
   * @dev Returns the URI of the given `tokenId`
   *      Example Format:
   *      {
   *        "description": "Friendly OpenSea Creature.", 
   *        "external_url": "https://mywebsite.com/3", 
   *        "image": "https://mywebsite.com/3.png", 
   *        "name": "My NFT",
   *        "attributes": {
   *          "background_color": "#000000",
   *          "animation_url": "",
   *          "youtube_url": ""
   *        } 
   *      }
   */
  function tokenURI(uint256 tokenId) 
    public 
    view 
    virtual 
    returns(string memory) 
  {
    uint256 classId = classOf(tokenId);

    require(
      classId > 0, 
      "Token is not apart of a multiclass"
    ); 
    
    return classURI(classId);
  }
}

File 8 of 45 : MintpressListable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//abstract that allows tokens to be listed in an order book
import "../../MultiClass/abstractions/MultiClassOrderBook.sol";

/**
 * @dev Abstract that opens the order book methods
 */
abstract contract MintpressListable is MultiClassOrderBook {
  /**
   * @dev Removes `tokenId` from the order book.
   */
  function delist(uint256 tokenId) external virtual {
    _delist(tokenId);
  }

  /**
   * @dev Lists `tokenId` on the order book for `amount` in wei.
   */
  function list(uint256 tokenId, uint256 amount) 
    external virtual 
  {
    _list(tokenId, amount);
  }
}

File 9 of 45 : MintpressMintable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//labels contract owner only methods
import "@openzeppelin/contracts/access/Ownable.sol";
//for verifying messages in lazyMint
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
//provably fair library for `mintPack()`
import "../generators/ProvablyFair.sol";
//random prize picker for `mintPack()`
import "../generators/RandomPrize.sol";
//abstract implementation of managing token supplies in multi classes
import "../../MultiClass/abstractions/MultiClassOffer.sol";

/**
 * @dev Abstract that opens up various minting methods
 */
abstract contract MintpressMintable is Ownable, MultiClassOffer {
  // manual ReentrancyGuard
  bool private _minting = false;

  /**
   * @dev abstract; defined in MultiClassSupply; Returns true if 
   *      `classId` supply and size are equal
   */
  function classFilled(uint256 classId) 
    public view virtual returns(bool);

  /**
   * @dev abstract; defined in MultiClassSupply; Returns the total 
   *      possible supply size of `classId`
   */
  function classSize(uint256 classId) 
    public view virtual returns(uint256);

  /**
   * @dev abstract; defined in MultiClassSupply; Returns the current 
   *      supply size of `classId`
   */
  function classSupply(uint256 classId) 
    public view virtual returns(uint256);

  /**
   * @dev override; super defined in Ownable; Returns the address of 
   *      the current owner. 
   */
  function owner() 
    public 
    view 
    virtual 
    override(MultiClassOffer, Ownable) 
    returns (address) 
  {
    return super.owner();
  }

  /**
   * @dev override; super defined in Context; Returns msg.sender
   */
  function _msgSender() 
    internal 
    view 
    virtual 
    override(Context, MultiClassOffer)
    returns (address) 
  {
    return super._msgSender();
  }

  /**
   * @dev abstract; defined in MultiClassSupply; Increases the supply 
   *      of `classId` by `amount`
   */
  function _addClassSupply(uint256 classId, uint256 amount) 
    internal virtual;

  /**
   * @dev abstract; defined in BEP721; Adds to the overall amount 
   *      of tokens generated in the contract
   */
  function _addSupply(uint256 supply) internal virtual;

  /**
   * @dev abstract; defined in MultiClass; Maps `tokenId` to `classId`
   */
  function _classify(uint256 tokenId, uint256 classId) 
    internal virtual;
  
  /**
   * @dev abstract; defined in MultiClassOrderBook; Pays the amount 
   *      to the recipients
   */
  function _escrowFees(uint256 tokenId, uint256 amount)
    internal virtual returns(uint256);
    
  /**
   * @dev abstract; defined in ERC721; Same as `_safeMint()`, with an 
   *      additional `data` parameter which is forwarded in 
   *      {IERC721Receiver-onERC721Received} to contract recipients.
   */
  function _safeMint(address to, uint256 tokenId) 
    internal virtual;
  
  /**
   * @dev Allows anyone to self mint a token
   */
  function lazyMint(
    uint256 classId,
    uint256 tokenId,
    address recipient,
    bytes calldata proof
  ) external virtual {
    //check size
    require(!classFilled(classId), "Class filled.");
    //make sure the admin signed this off
    require(
      ECDSA.recover(
        ECDSA.toEthSignedMessageHash(
          keccak256(
            abi.encodePacked(classId, tokenId, recipient)
          )
        ),
        proof
      ) == owner(),
      "Invalid proof."
    );
    // manual ReentrancyGuard
    require(!_minting, "reentrant call");
    _minting = true;

    //mint first and wait for errors
    _safeMint(recipient, tokenId);
    //then classify it
    _classify(tokenId, classId);
    //then increment supply
    _addClassSupply(classId, 1);
    //add to supply
    _addSupply(1);

    _minting = false;
  }

  /**
   * @dev Allows for the creator to make an offering on their tokens
   */
  function makeOffer(
    uint256 classId, 
    uint256 amount, 
    uint256 start, 
    uint256 end
  ) external onlyCreatorOrOwner(classId) {
    _makeOffer(classId, amount, start, end);
  }

  /**
   * @dev Mints `tokenId`, classifies it as `classId` and 
   *      transfers to `recipient`
   */
  function mint(uint256 classId, uint256 tokenId, address recipient)
    public virtual onlyOwner
  {
    //check size
    require(!classFilled(classId), "Class filled.");
    //mint first and wait for errors
    _safeMint(recipient, tokenId);
    //then classify it
    _classify(tokenId, classId);
    //then increment supply
    _addClassSupply(classId, 1);
    //add to supply
    _addSupply(1);
  }

  /**
   * @dev Allows for consumers to buy and mint tokens themselves
   */
  function payAndMint(
    uint256 classId, 
    uint256 tokenId, 
    address recipient
  ) external virtual payable offerValid(classId) {
    // manual ReentrancyGuard
    require(!_minting, "reentrant call");
    _minting = true;
    uint256 offer = offerOf(classId);
    require(msg.value == offer, "Incorrect payment");

    //mint first and wait for errors
    _safeMint(recipient, tokenId);
    //then classify it
    _classify(tokenId, classId);
    //then increment supply
    _addClassSupply(classId, 1);
    //add to supply
    _addSupply(1);

    //payout the fees
    uint256 remainder = _escrowFees(tokenId, msg.value);
    //get the creator
    address payable creator = payable(creatorOf(classId));
    //send the remainder to the token owner
    creator.transfer(remainder);

    _minting = false;
  }

  /**
   * @dev Randomly assigns a set of NFTs to a `recipient`
   */
  function mintPack(
    uint256[] memory classIds, 
    uint256 fromTokenId,
    address recipient, 
    uint8 tokensInPack,
    uint256 defaultSize,
    string memory seed
  ) external virtual onlyOwner {
    require(defaultSize > 0, "Missing default size");
    require(
      tokensInPack <= classIds.length, 
      "Not enough token classes to make a mint pack"
    );
    uint256[] memory rollToPrizeMap = new uint256[](classIds.length);
    uint256 size;
    uint256 supply;
    uint256 difference = 0;
    //loop through classIds
    for (uint8 i = 0; i < classIds.length; i++) {
      if (i > 0 && rollToPrizeMap[i - 1] > 0) {
        difference = rollToPrizeMap[i - 1];
      }
      //get the class size
      size = classSize(classIds[i]);
      //if the class size is no limits
      if (size == 0) {
        //use the default size
        size = defaultSize;
      }
      //get the supply
      supply = classSupply(classIds[i]);
      //if the supply is greater than the size
      if (supply >= size) {
        //then we should zero out the 
        rollToPrizeMap[i] = 0;
        continue;
      }
      //determine the roll range for this class
      rollToPrizeMap[i] = size - supply;
      //to make it really a range we need 
      //to append the the last class range
      if (i > 0 && rollToPrizeMap[i] > 0) {
        rollToPrizeMap[i] += difference;
      }
    }

    //figure out the max roll value 
    //(which should be the last value in the roll to prize map)
    uint256 maxRollValue = rollToPrizeMap[rollToPrizeMap.length - 1];
    //max roll value is also the total available tokens that can be 
    //minted if the tokens in pack is more than that, then we should 
    //error
    require(
      tokensInPack <= classIds.length, 
      "Not enough tokens to make a mint pack"
    );

    //now we can create a prize pool
    RandomPrize.PrizePool memory pool = RandomPrize.PrizePool(
      ProvablyFair.RollState(
        maxRollValue, 0, 0, blockhash(block.number - 1)
      ), 
      classIds, 
      rollToPrizeMap
    );

    // manual ReentrancyGuard
    require(!_minting, "reentrant call");
    _minting = true;

    uint256 classId;
    // for each token in the pack
    for (uint8 i = 0; i < tokensInPack; i++) {
      //figure out what the winning class id is
      classId = RandomPrize.roll(pool, seed, (i + 1) < tokensInPack);
      //if there is a class id
      if (classId > 0) {
        //then lets mint it
        mint(classId, fromTokenId + i, recipient);
      }
    }

    _minting = false;
  }
}

File 10 of 45 : MintpressPausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//labels contract owner only methods
import "@openzeppelin/contracts/access/Ownable.sol";
//implementation of ERC721 where transers can be paused
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";

/**
 * @dev Opens up the pausible methods
 */
abstract contract MintpressPausable is ERC721Pausable, Ownable {
  /**
   * @dev Pauses all token transfers.
   *
   * See {ERC721Pausable} and {Pausable-_pause}.
   *
   * Requirements:
   *
   * - the caller must have the `PAUSER_ROLE`.
   */
  function pause() public virtual onlyOwner {
    _pause();
  }

  /**
   * @dev Unpauses all token transfers.
   *
   * See {ERC721Pausable} and {Pausable-_unpause}.
   *
   * Requirements:
   *
   * - the caller must have the `PAUSER_ROLE`.
   */
  function unpause() public virtual onlyOwner {
    _unpause();
  }
}

File 11 of 45 : MintpressSortable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//abstract implementation of a multi class token factory
import "../../MultiClass/abstractions/MultiClass.sol";
//abstract implementation of managing token supplies in multi classes
import "../../MultiClass/abstractions/MultiClassSupply.sol";
//abstract implementation of attaching URIs in token classes
import "../../MultiClass/abstractions/MultiClassURIStorage.sol";

/**
 * @dev Passes multi class methods to Mintpress
 */
abstract contract MintpressSortable is 
  MultiClass, 
  MultiClassSupply, 
  MultiClassURIStorage
{
}

File 12 of 45 : BEP721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a BEP721 compliant contract
import "./interfaces/IBEP721.sol";

/**
 * @dev Abstract of a BEP721 that pre defines total supply
 */
abstract contract BEP721 is IBEP721 {
  //for total supply
  uint256 private _supply = 0;

  /**
   * @dev Shows the overall amount of tokens generated in the contract
   */
  function totalSupply() public virtual view returns (uint256) {
    return _supply;
  }

  /**
   * @dev Adds to the overall amount of tokens generated in the contract
   */
  function _addSupply(uint256 supply) internal virtual {
    _supply += supply;
  }
}

File 13 of 45 : LibRoyaltiesV2.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library LibRoyaltiesV2 {
  /*
   * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca
   */
  bytes4 constant _INTERFACE_ID_ROYALTIES = 0xcad96cca;
}

File 14 of 45 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 15 of 45 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 16 of 45 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 17 of 45 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 18 of 45 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

File 19 of 45 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

File 20 of 45 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 21 of 45 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 22 of 45 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 23 of 45 : IERC2981.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of an ERC165 compliant contract
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard
 */
interface IERC2981 is IERC165 {
  /** 
   * @dev ERC165 bytes to add to interface array - set in parent contract
   *  implementing this standard
   * 
   *  bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
   *  bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
   *  _registerInterface(_INTERFACE_ID_ERC2981);
   */
  function royaltyInfo(
    uint256 _tokenId,
    uint256 _salePrice
  ) external view returns (
    address receiver,
    uint256 royaltyAmount
  );
}

File 24 of 45 : RoyaltiesV2.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./LibPart.sol";

interface RoyaltiesV2 {
  event RoyaltiesSet(uint256 tokenId, LibPart.Part[] royalties);

  function getRaribleV2Royalties(uint256 id) external view returns (LibPart.Part[] memory);
}

File 25 of 45 : MultiClassFees.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClassFees compliant contract
import "./../interfaces/IMultiClassFees.sol";

/**
 * @dev Abstract that considers royalty fees in multi classes
 */
abstract contract MultiClassFees is IMultiClassFees {
  //10000 means 100.00%
  uint256 private constant TOTAL_ALLOWABLE_FEES = 10000;
  //mapping of `classId` to total fees (could be problematic if not synced)
  mapping(uint256 => uint96) private _fees;
  //mapping of `classId` to `recipient` fee
  mapping(uint256 => mapping(address => uint96)) internal _fee;
  //index mapping of `classId` to recipients (so we can loop the map)
  mapping(uint256 => address[]) internal _recipients;

  /**
   * @dev Returns the class given `tokenId`
   */
  function classOf(uint256 tokenId) 
    public view virtual returns(uint256);

  /**
   * @dev Returns the fee of a `recipient` in `classId`
   */
  function classFeeOf(uint256 classId, address recipient)
    public view virtual returns(uint256)
  {
    return _fee[classId][recipient];
  }

  /**
   * @dev returns the total fees of `classId`
   */
  function classFees(uint256 classId) 
    public view virtual returns(uint256) 
  {
    return _fees[classId];
  }

  /**
   * @dev Sets a fee that will be collected during the exchange method
   */
  function _allocateFee(uint256 classId, address recipient, uint96 fee)
    internal virtual
  {
    require(
      fee > 0,
      "Fee should be more than 0"
    );

    //if no recipient
    if (_fee[classId][recipient] == 0) {
      //add recipient
      _recipients[classId].push(recipient);
      //map fee
      _fee[classId][recipient] = fee;
      //add to total fee
      _fees[classId] += fee;
    //else there"s already an existing recipient
    } else {
      //remove old fee from total fee
      _fees[classId] -= _fee[classId][recipient];
      //map fee
      _fee[classId][recipient] = fee;
      //add to total fee
      _fees[classId] += fee;
    }

    //safe check
    require(
      _fees[classId] <= TOTAL_ALLOWABLE_FEES,
      "Exceeds allowable fees"
    );
  }

  /**
   * @dev Removes a fee
   */
  function _deallocateFee(uint256 classId, address recipient) internal virtual {
    //this is for the benefit of the sender so they
    //dont have to pay gas on things that dont matter
    require(
      _fee[classId][recipient] != 0,
      "Recipient has no fees"
    );
    //deduct total fees
    _fees[classId] -= _fee[classId][recipient];
    //remove fees from the map
    delete _fee[classId][recipient];
    //Tricky logic to remove an element from an array...
    //if there are at least 2 elements in the array,
    if (_recipients[classId].length > 1) {
      //find the recipient
      for (uint i = 0; i < _recipients[classId].length; i++) {
        if(_recipients[classId][i] == recipient) {
          //move the last element to the deleted element
          uint last = _recipients[classId].length - 1;
          _recipients[classId][i] = _recipients[classId][last];
          break;
        }
      }
    }

    //either way remove the last element
    _recipients[classId].pop();
  }

  /**
   * @dev Removes all fees from a `classId`
   */
  function _deallocateFees(uint256 classId) internal virtual {
    //zero out total fees
    _fees[classId] = 0;
    //remove fees from the map
    for (uint i = 0; i < _recipients[classId].length; i++) {
      delete _fee[classId][_recipients[classId][i]];
      delete _recipients[classId][i];
    }
  }

  /**
   * @dev Pays the amount to the recipients
   */
  function _escrowFees(uint256 tokenId, uint256 amount)
    internal virtual returns(uint256)
  {
    //get class from token
    uint256 classId = classOf(tokenId);
    require(classId != 0, "Class does not exist");

    //placeholder for recipient in the loop
    address recipient;
    //release payments to recipients
    for (uint i = 0; i < _recipients[classId].length; i++) {
      //get the recipient
      recipient = _recipients[classId][i];
      // (10 eth * 2000) / 10000 =
      payable(recipient).transfer(
        (amount * _fee[classId][recipient]) / TOTAL_ALLOWABLE_FEES
      );
    }

    //determine the remaining fee percent
    uint256 remainingFee = TOTAL_ALLOWABLE_FEES - _fees[classId];
    //return the remainder amount
    return (amount * remainingFee) / TOTAL_ALLOWABLE_FEES;
  }
}

File 26 of 45 : LibPart.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library LibPart {
  bytes32 public constant TYPE_HASH = keccak256("Part(address account,uint96 value)");

  struct Part {
    address payable account;
    uint96 value;
  }

  function hash(Part memory part) internal pure returns (bytes32) {
    return keccak256(abi.encode(TYPE_HASH, part.account, part.value));
  }
}

File 27 of 45 : IMultiClassFees.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClassFees compliant contract.
 */
interface IMultiClassFees {
  /**
   * @dev Returns the fee of a `recipient` in `classId`
   */
  function classFeeOf(uint256 classId, address recipient)
    external view returns(uint256);

  /**
   * @dev returns the total fees of `classId`
   */
  function classFees(uint256 classId)
    external view returns(uint256);
}

File 28 of 45 : ERC721OpenSea.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a OpenSea compliant contract
import "./interfaces/IERC721OpenSea.sol";

/**
 * @dev Abstract of an OpenSea compliant contract
 */
abstract contract ERC721OpenSea is IERC721OpenSea {
  string private _baseTokenURI;
  string private _contractURI;

  /**
   * @dev Constructor function
   */
  constructor (string memory baseTokenURI_, string memory contractURI_) {
    _contractURI = contractURI_;
    _baseTokenURI = baseTokenURI_;
  }

  /**
   * @dev The base URI for token data ex. https://creatures-api.opensea.io/api/creature/
   * Example Usage: 
   *  Strings.strConcat(baseTokenURI(), Strings.uint2str(tokenId))
   */
  function baseTokenURI() public view returns (string memory) {
    return _baseTokenURI;
  }

  /**
   * @dev The URI for contract data ex. https://creatures-api.opensea.io/contract/opensea-creatures
   * Example Format:
   * {
   *   "name": "OpenSea Creatures",
   *   "description": "OpenSea Creatures are adorable aquatic beings primarily for demonstrating what can be done using the OpenSea platform. Adopt one today to try out all the OpenSea buying, selling, and bidding feature set.",
   *   "image": "https://openseacreatures.io/image.png",
   *   "external_link": "https://openseacreatures.io",
   *   "seller_fee_basis_points": 100, # Indicates a 1% seller fee.
   *   "fee_recipient": "0xA97F337c39cccE66adfeCB2BF99C1DdC54C2D721" # Where seller fees will be paid to.
   * }
   */
  function contractURI() public view returns (string memory) {
    return _contractURI;
  }
}

File 29 of 45 : IERC721OpenSea.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of an ERC721 compliant contract
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

/**
 * @dev see: https://docs.opensea.io/docs/1-structuring-your-smart-contract
 *      see: https://github.com/ProjectOpenSea/opensea-creatures/blob/master/contracts/ERC721Tradable.sol#L70-L86
 */
interface IERC721OpenSea is IERC721 {
  /**
   * @dev The base URI for token data ex. https://creatures-api.opensea.io/api/creature/
   * Example Usage: 
   *  Strings.strConcat(baseTokenURI(), Strings.uint2str(tokenId))
   */
  function baseTokenURI() external view returns (string memory);

  /**
   * @dev The URI for contract data ex. https://creatures-api.opensea.io/contract/opensea-creatures/contract.json
   * Example Format:
   * {
   *   "name": "OpenSea Creatures",
   *   "description": "OpenSea Creatures are adorable aquatic beings primarily for demonstrating what can be done using the OpenSea platform. Adopt one today to try out all the OpenSea buying, selling, and bidding feature set.",
   *   "image": "https://openseacreatures.io/image.png",
   *   "external_link": "https://openseacreatures.io",
   *   "seller_fee_basis_points": 100, # Indicates a 1% seller fee.
   *   "fee_recipient": "0xA97F337c39cccE66adfeCB2BF99C1DdC54C2D721" # Where seller fees will be paid to.
   * }
   */
  function contractURI() external view returns (string memory);
}

File 30 of 45 : MultiClassOrderBook.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClassOrderBook compliant contract
import "./../interfaces/IMultiClassOrderBook.sol";

/**
 * @dev Abstract that allows tokens to be listed in an order book
 */
abstract contract MultiClassOrderBook is IMultiClassOrderBook {
  // mapping of `tokenId` to amount
  // amount defaults to 0 and is in wei
  // apparently the data type for ether units is uint256 so we can interact
  // with it the same
  // see: https://docs.soliditylang.org/en/v0.7.1/units-and-global-variables.html
  mapping (uint256 => uint256) private _book;

  /**
   * @dev abstract; defined in ERC721; See {IERC721-ownerOf}.
   */
  function ownerOf(uint256 tokenId) 
    public view virtual returns (address);

  /**
   * @dev abstract; defined in Context; Returns the caller of 
   *      a contract method
   */
  function _msgSender() internal view virtual returns (address);

  /**
   * @dev Returns the amount a `tokenId` is being offered for.
   */
  function listingOf(uint256 tokenId) 
    public view virtual returns(uint256) 
  {
    return _book[tokenId];
  }

  /**
   * @dev Lists `tokenId` on the order book for `amount` in wei.
   */
  function _list(uint256 tokenId, uint256 amount) internal virtual {
    //error if the sender is not the owner
    // even the contract owner cannot list a token
    require(
      ownerOf(tokenId) == _msgSender(),
      "Only the token owner can list a token"
    );
    //disallow free listings because solidity defaults amounts to zero
    //so it's impractical to determine a free listing from an unlisted one
    require(
      amount > 0,
      "Listing amount should be more than 0"
    );
    //add the listing
    _book[tokenId] = amount;
    //emit that something was listed
    emit Listed(_msgSender(), tokenId, amount);
  }

  /**
   * @dev Removes `tokenId` from the order book.
   */
  function _delist(uint256 tokenId) internal virtual {
    address owner = ownerOf(tokenId);
    //error if the sender is not the owner
    // even the contract owner cannot delist a token
    require(
      owner == _msgSender(),
      "Only the token owner can delist a token"
    );
    //this is for the benefit of the sender so they
    //dont have to pay gas on things that dont matter
    require(
      _book[tokenId] != 0,
      "Token is not listed"
    );
    //remove the listing
    delete _book[tokenId];
    //emit that something was delisted
    emit Delisted(owner, tokenId);
  }
}

File 31 of 45 : IMultiClassOrderBook.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClassOrderBook compliant contract.
 */
interface IMultiClassOrderBook {
  /**
   * @dev Emitted when `owner` books their `tokenId` to
   *      be sold for `amount` in wei.
   */
  event Listed(
    address indexed owner,
    uint256 indexed tokenId,
    uint256 indexed amount
  );

  /**
   * @dev Emitted when `owner` removes their `tokenId` from the 
   *      order book.
   */
  event Delisted(address indexed owner, uint256 indexed tokenId);

  /**
   * @dev Returns the amount a `tokenId` is being offered for.
   */
  function listingOf(uint256 tokenId) external view returns(uint256);
}

File 32 of 45 : ECDSA.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

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

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

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

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

File 33 of 45 : ProvablyFair.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Implementation of a provably fair library
 */
library ProvablyFair {
  /**
   * @dev Pattern to manage the roll settings
   */
  struct RollState {
    uint256 max;
    uint256 min;
    uint256 nonce;
    bytes32 seed;
  }

  /**
   * @dev Helper to expose the hashed version of the server seed
   */
  function serverSeed(RollState memory state) 
    internal pure returns(bytes32) 
  {
    require(
      state.seed.length != 0, 
      "Missing server seed."
    );
    return keccak256(abi.encodePacked(state.seed));
  }

  /**
   * @dev rolls the dice and makes it relative to the range
   */
  function roll(
    RollState memory state, 
    string memory seed, 
    bool saveSeed
  ) internal view returns(uint256) {
    require(
      state.seed.length != 0, 
      "Missing server seed."
    );

    require(
      state.min < state.max, 
      "Minimum is greater than maximum."
    );

    //roll the dice
    uint256 results = uint256(
      keccak256(
        abi.encodePacked(
          state.seed, 
          msg.sender, 
          seed, 
          state.nonce
        )
      )
    ) + state.min;

    //increase nonce
    state.nonce += 1;

    if (!saveSeed) {
      //reset server seed
      state.seed = "";
    }

    //if there is a max
    if (state.max > 0) {
      //cap the results
      return results % state.max;  
    }

    return results;
  }
}

File 34 of 45 : RandomPrize.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//provably fair library used as the prize roller
import "./ProvablyFair.sol";

/**
 * @dev Random prize roller 
 */
library RandomPrize {
  /**
   * @dev Pattern to manage prize pool and roll to prize map
   */
  struct PrizePool {
    ProvablyFair.RollState state;
    uint256[] prizes;
    uint256[] rollToPrizeMap;
  }

  /**
   * @dev rolls the dice and assigns the prize
   */
  function roll(
    PrizePool memory pool, 
    string memory clientSeed, 
    bool saveSeed
  ) internal view returns(uint256) {
    // provably fair roller
    uint256 _roll = ProvablyFair.roll(pool.state, clientSeed, saveSeed);
    //this is the determined prize
    uint256 prize;
    uint256 less;
    uint256 difference = 0;
    for (uint8 i = 0; i < pool.rollToPrizeMap.length; i++) {
      if (i > 0 && pool.rollToPrizeMap[i - 1] > 0) {
        difference = pool.rollToPrizeMap[i - 1];
      }
      // if the roll value is not zero 
      // and the roll is less than the roll value
      if (prize == 0 
        && pool.rollToPrizeMap[i] > 0 
        && _roll <= pool.rollToPrizeMap[i]
      ) {
        //set the respective prize
        prize = pool.prizes[i];
        //get what we need to less
        less = pool.rollToPrizeMap[i] - difference;
        //set this now to zero so it can't be rolled for again
        pool.rollToPrizeMap[i] = 0;
        //less the max in the state
        pool.state.max -= less;
      }
      //if we have a prize, then we should just less the map range
      if (prize > 0 && pool.rollToPrizeMap[i] > 0) {
        pool.rollToPrizeMap[i] -= less;
      }
    }
    return prize;
  }
}

File 35 of 45 : MultiClassOffer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClassOffer compliant contract
import "./../interfaces/IMultiClassOffer.sol";

/**
 * @dev Abstract implementation of managing token offers 
 *      in multi classes
 */
abstract contract MultiClassOffer is IMultiClassOffer {
  //index mapping of classId to offer
  mapping(uint256 => uint256) private _offer;
  //index mapping of classId to creator
  mapping(uint256 => address) private _creator;
  //index mapping of classId to sale period
  mapping(uint256 => uint256[2]) private _period;

  /**
   * @dev abstract; defined in Ownable; Returns the address of the 
   *      current owner.
   */
  function owner() public view virtual returns (address);

  /**
   * @dev abstract; defined in Context; Returns the msg.sender.
   */
  function _msgSender() internal view virtual returns (address);

  /**
   * @dev Checks the validity of the offer
   */
  modifier offerValid(uint256 classId) {
    uint256 offer = _offer[classId];
    require(_creator[classId] != address(0), "No offer recipient");
    require(_offer[classId] > 0, "No offer availalable");
    require(
      _period[classId][0] == 0 || block.timestamp >= _period[classId][0], 
      "Offer not started"
    );

    require(
      _period[classId][1] == 0 || block.timestamp <= _period[classId][1], 
      "Offer has ended"
    );

    _;
  }

  /**
   * @dev Permission for creator or owner
   */
  modifier onlyCreatorOrOwner(uint256 classId) {
    uint256 offer = _offer[classId];
    address sender = _msgSender();
    require(
      sender == owner() || sender == _creator[classId], 
      "Caller is not the owner or creator"
    );

    _;
  }

  /**
   * @dev Returns the offer of a `classId`
   */
  function offerOf(uint256 classId)
    public view returns(uint256)
  {
    return _offer[classId];
  }

  /**
   * @dev Returns the creator of a `classId`
   */
  function creatorOf(uint256 classId)
    public view returns(address) 
  {
    return _creator[classId];
  }

  /**
   * @dev Sets the offer of `amount` in `classId`
   */
  function _makeOffer(
    uint256 classId, 
    uint256 amount, 
    uint256 start, 
    uint256 end
  ) internal virtual {
    require(_creator[classId] != address(0), "No offer recipient");
    require(amount > 0, "Offer amount should be more than zero");
    require(
      (start == 0 && end == 0) || end > start, 
      "Start time exceeds end time"
    );
    _offer[classId] = amount;
    
    if (start > 0) {
      _period[classId][0] = start;
    }

    if (end > 0) {
      _period[classId][1] = end;
    }
  }

  /**
   * @dev Sets the `creator` of the `classId`
   */
  function _setCreator(uint256 classId, address creator) 
    internal virtual 
  {
    _creator[classId] = creator;
  }
}

File 36 of 45 : IMultiClassOffer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClassFees compliant contract.
 */
interface IMultiClassOffer {
  /**
   * @dev Returns the offer of a `classId`
   */
  function offerOf(uint256 classId)
    external view returns(uint256);

  /**
   * @dev Returns the creator of a `classId`
   */
  function creatorOf(uint256 classId)
    external view returns(address);
}

File 37 of 45 : ERC721Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}

File 38 of 45 : Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

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

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

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

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

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 39 of 45 : MultiClass.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClass compliant contract
import "./../interfaces/IMultiClass.sol";

/**
 * @dev Abstract implementation of a multi class token factory
 */
abstract contract MultiClass is IMultiClass {
  //mapping of token id to class
  mapping(uint256 => uint256) private _tokens;

  /**
   * @dev Returns the class given `tokenId`
   */
  function classOf(uint256 tokenId) 
    public view virtual returns(uint256) 
  {
    return _tokens[tokenId];
  }

  /**
   * @dev Maps `tokenId` to `classId`
   */
  function _classify(uint256 tokenId, uint256 classId) 
    internal virtual 
  {
    require(
      _tokens[tokenId] == 0,
      "Token is already classified"
    );
    _tokens[tokenId] = classId;
  }
}

File 40 of 45 : MultiClassSupply.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClassSupply compliant contract
import "./../interfaces/IMultiClassSupply.sol";

/**
 * @dev Abstract implementation of managing token supplies 
 *      in multi classes
 */
abstract contract MultiClassSupply is IMultiClassSupply {
  //index mapping of classId to current supply size
  mapping(uint256 => uint256) private _supply;
  //mapping of classId to total supply size
  mapping(uint256 => uint256) private _size;

  /**
   * @dev Returns true if `classId` supply and size are equal
   */
  function classFilled(uint256 classId) 
    public view virtual returns(bool) 
  {
    return _size[classId] != 0 && _supply[classId] == _size[classId];
  }

  /**
   * @dev Returns the total possible supply size of `classId`
   */
  function classSize(uint256 classId) 
    public view virtual returns(uint256) 
  {
    return _size[classId];
  }

  /**
   * @dev Returns the current supply size of `classId`
   */
  function classSupply(uint256 classId) 
    public view virtual returns(uint256) 
  {
    return _supply[classId];
  }

  /**
   * @dev Sets an immutable fixed `size` to `classId`
   */
  function _fixClassSize(uint256 classId, uint256 size) 
    internal virtual 
  {
    require (
      _size[classId] == 0,
      "Class is already sized."
    );
    _size[classId] = size;
  }

  /**
   * @dev Increases the supply of `classId` by `amount`
   */
  function _addClassSupply(uint256 classId, uint256 amount) 
    internal virtual 
  {
    uint256 size = _supply[classId] + amount;
    require(
      _size[classId] == 0 || size <= _size[classId],
      "Amount overflows class size."
    );
    _supply[classId] = size;
  }
}

File 41 of 45 : MultiClassURIStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of a MultiClassURIStorage compliant contract
import "./../interfaces/IMultiClassURIStorage.sol";

/**
 * @dev Abstract implementation of attaching URIs in token classes
 */
abstract contract MultiClassURIStorage is IMultiClassURIStorage {
  //mapping of `classId` to `data`
  mapping(uint256 => string) private _classURIs;

  /**
   * @dev Returns the reference of `classId`
   */
  function classURI(uint256 classId)
    public view virtual returns(string memory)
  {
    return _classURIs[classId];
  }

  /**
   * @dev References `data` to `classId`
   */
  function _setClassURI(uint256 classId, string memory data)
    internal virtual
  {
    require(
      bytes(_classURIs[classId]).length == 0,
      "Class is already referenced"
    );
    _classURIs[classId] = data;
  }
}

File 42 of 45 : IMultiClass.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClass compliant contract.
 */
interface IMultiClass {
  /**
   * @dev Returns the class given `tokenId`
   */
  function classOf(uint256 tokenId) external view returns(uint256);
}

File 43 of 45 : IMultiClassSupply.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClassSupply compliant contract.
 */
interface IMultiClassSupply {
  /**
   * @dev Returns the total possible supply size of `classId`
   */
  function classSize(uint256 classId) external view returns(uint256);

  /**
   * @dev Returns true if `classId` supply and size are equal
   */
  function classFilled(uint256 classId) external view returns(bool);

  /**
   * @dev Returns the current supply size of `classId`
   */
  function classSupply(uint256 classId) external view returns(uint256);
}

File 44 of 45 : IMultiClassURIStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an MultiClassURIStorage compliant contract.
 */
interface IMultiClassURIStorage {
  /**
   * @dev Returns the data of `classId`
   */
  function classURI(uint256 classId) 
    external view returns(string memory);
}

File 45 of 45 : IBEP721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

//interface of an ERC721 compliant contract
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

/**
 * @dev Required interface of an BEP721 compliant contract.
 */
interface IBEP721 is IERC721 {
  /**
   * @dev Specifies the name by which other contracts will recognize 
   *      the BEP-721 token 
   */
  function name() external view returns (string memory);

  /**
   * @dev A concise name for the token, comparable to a ticker symbol 
   */
  function symbol() external view returns (string memory);

  /**
   * @dev Shows the overall amount of tokens generated
   */
  function totalSupply() external view returns (uint256);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_baseTokenURI","type":"string"},{"internalType":"string","name":"_contractURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Delisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Listed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"}],"indexed":false,"internalType":"struct LibPart.Part[]","name":"royalties","type":"tuple[]"}],"name":"RoyaltiesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"classFeeOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"classFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"classFilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"classOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"classSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"classSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"classURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"creatorOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"deallocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"deallocateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"delist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exchange","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRaribleV2Royalties","outputs":[{"components":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"}],"internalType":"struct LibPart.Part[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"lazyMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"list","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"listingOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"makeOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"classIds","type":"uint256[]"},{"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint8","name":"tokensInPack","type":"uint8"},{"internalType":"uint256","name":"defaultSize","type":"uint256"},{"internalType":"string","name":"seed","type":"string"}],"name":"mintPack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"name":"mintWithURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"}],"name":"offerOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"payAndMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"classId","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"address","name":"creator","type":"address"}],"name":"registerToCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260006009556012805460ff199081169091556014805490911690553480156200002c57600080fd5b5060405162004e7138038062004e718339810160408190526200004f91620002ea565b8383838381818181878781600390805190602001906200007192919062000177565b5080516200008790600490602084019062000177565b5050600e805460ff1916905550620000a8620000a2620000e6565b62000102565b8051620000bd90601690602084019062000177565b508151620000d390601590602085019062000177565b50505050505050505050505050620003e0565b6000620000fd6200015c60201b6200214c1760201c565b905090565b600e80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000620000fd6200017360201b6200214c1760201c565b3390565b8280546200018590620003a3565b90600052602060002090601f016020900481019282620001a95760008555620001f4565b82601f10620001c457805160ff1916838001178555620001f4565b82800160010185558215620001f4579182015b82811115620001f4578251825591602001919060010190620001d7565b506200020292915062000206565b5090565b5b8082111562000202576000815560010162000207565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200024557600080fd5b81516001600160401b03808211156200026257620002626200021d565b604051601f8301601f19908116603f011681019082821181831017156200028d576200028d6200021d565b81604052838152602092508683858801011115620002aa57600080fd5b600091505b83821015620002ce5785820183015181830184015290820190620002af565b83821115620002e05760008385830101525b9695505050505050565b600080600080608085870312156200030157600080fd5b84516001600160401b03808211156200031957600080fd5b620003278883890162000233565b955060208701519150808211156200033e57600080fd5b6200034c8883890162000233565b945060408701519150808211156200036357600080fd5b620003718883890162000233565b935060608701519150808211156200038857600080fd5b50620003978782880162000233565b91505092959194509250565b600181811c90821680620003b857607f821691505b60208210811415620003da57634e487b7160e01b600052602260045260246000fd5b50919050565b614a8180620003f06000396000f3fe6080604052600436106102c95760003560e01c806370a0823111610175578063cad96cca116100dc578063e8a3d48511610095578063f2fde38b1161006f578063f2fde38b14610917578063f39a67dd14610937578063f8d23a3514610957578063fae87d241461097757600080fd5b8063e8a3d48514610883578063e985e9c514610898578063eae3e3b3146108e157600080fd5b8063cad96cca146107c1578063cf5483dc146107ee578063d4e218501461080e578063d547cfb71461082e578063e340498114610843578063e7d3fe6b1461086357600080fd5b8063964bc33f1161012e578063964bc33f146106c8578063a11d63cb146106e8578063a22cb46514610734578063a3cb2f4414610754578063b88d4fde14610781578063c87b56dd146107a157600080fd5b806370a0823114610626578063715018a614610646578063792382bb1461065b5780638456cb591461067b5780638da5cb5b1461069057806395d89b41146106b357600080fd5b80634000a0b811610234578063589a1743116101ed5780636352211e116101c75780636352211e146105a657806364e574c2146105c6578063671e4248146105e6578063679e20a11461060657600080fd5b8063589a1743146105385780635c975abb1461056e57806361420e8c1461058657600080fd5b80634000a0b81461049257806342842e0e146104a557806342966c68146104c55780634324aa21146104e557806350fd736714610505578063535565591461052557600080fd5b8063162094c411610286578063162094c4146103bf57806318160ddd146103df578063228e2eeb146103fe57806323b872dd1461041e5780632a55205a1461043e5780633f4ba83a1461047d57600080fd5b806301ffc9a7146102ce57806306fdde0314610303578063081812fc14610325578063095ea7b31461035d5780630a3917111461037f5780630d95fed41461039f575b600080fd5b3480156102da57600080fd5b506102ee6102e9366004613fa3565b610997565b60405190151581526020015b60405180910390f35b34801561030f57600080fd5b506103186109ea565b6040516102fa9190614018565b34801561033157600080fd5b5061034561034036600461402b565b6109f9565b6040516001600160a01b0390911681526020016102fa565b34801561036957600080fd5b5061037d610378366004614060565b610a93565b005b34801561038b57600080fd5b5061037d61039a36600461402b565b610ba9565b3480156103ab57600080fd5b506103186103ba36600461402b565b610be5565b3480156103cb57600080fd5b5061037d6103da366004614149565b610bf0565b3480156103eb57600080fd5b506009545b6040519081526020016102fa565b34801561040a57600080fd5b506103f061041936600461402b565b610c3f565b34801561042a57600080fd5b5061037d610439366004614190565b610c53565b34801561044a57600080fd5b5061045e6104593660046141cc565b610c85565b604080516001600160a01b0390931683526020830191909152016102fa565b34801561048957600080fd5b5061037d610d37565b61037d6104a03660046141ee565b610d71565b3480156104b157600080fd5b5061037d6104c0366004614190565b611016565b3480156104d157600080fd5b5061037d6104e036600461402b565b611031565b3480156104f157600080fd5b506103f061050036600461402b565b6110a8565b34801561051157600080fd5b5061037d6105203660046141cc565b6110bc565b61037d61053336600461402b565b6110ca565b34801561054457600080fd5b5061034561055336600461402b565b6000908152601060205260409020546001600160a01b031690565b34801561057a57600080fd5b50600e5460ff166102ee565b34801561059257600080fd5b5061037d6105a1366004614223565b611229565b3480156105b257600080fd5b506103456105c136600461402b565b611273565b3480156105d257600080fd5b5061037d6105e1366004614273565b61127e565b3480156105f257600080fd5b506103f061060136600461402b565b611335565b34801561061257600080fd5b5061037d6106213660046142a5565b611349565b34801561063257600080fd5b506103f06106413660046142f1565b611384565b34801561065257600080fd5b5061037d61140b565b34801561066757600080fd5b5061037d61067636600461430c565b611445565b34801561068757600080fd5b5061037d6114df565b34801561069c57600080fd5b50600e5461010090046001600160a01b0316610345565b3480156106bf57600080fd5b50610318611517565b3480156106d457600080fd5b5061037d6106e336600461402b565b611521565b3480156106f457600080fd5b506103f061070336600461436d565b60009182526001602090815260408084206001600160a01b039390931684529190529020546001600160601b031690565b34801561074057600080fd5b5061037d61074f366004614399565b61152a565b34801561076057600080fd5b506103f061076f36600461402b565b6000908152600f602052604090205490565b34801561078d57600080fd5b5061037d61079c3660046143d5565b6115fc565b3480156107ad57600080fd5b506103186107bc36600461402b565b61162e565b3480156107cd57600080fd5b506107e16107dc36600461402b565b611768565b6040516102fa9190614451565b3480156107fa57600080fd5b5061037d6108093660046144a5565b61189a565b34801561081a57600080fd5b5061037d610829366004614539565b611a80565b34801561083a57600080fd5b50610318611ac5565b34801561084f57600080fd5b506103f061085e36600461402b565b611b57565b34801561086f57600080fd5b5061037d61087e3660046141ee565b611b6b565b34801561088f57600080fd5b50610318611c0a565b3480156108a457600080fd5b506102ee6108b336600461458e565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b3480156108ed57600080fd5b506103f06108fc36600461402b565b6000908152602081905260409020546001600160601b031690565b34801561092357600080fd5b5061037d6109323660046142f1565b611c19565b34801561094357600080fd5b5061037d6109523660046145c9565b611cb7565b34801561096357600080fd5b506102ee61097236600461402b565b612107565b34801561098357600080fd5b5061037d61099236600461436d565b612112565b60006001600160e01b0319821663656cb66560e11b14156109ba57506001919050565b6001600160e01b0319821663152a902d60e11b14156109db57506001919050565b6109e482612150565b92915050565b60606109f46121a0565b905090565b6000818152600560205260408120546001600160a01b0316610a775760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600760205260409020546001600160a01b031690565b6000610a9e826121af565b9050806001600160a01b0316836001600160a01b03161415610b0c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a6e565b336001600160a01b0382161480610b285750610b2881336108b3565b610b9a5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a6e565b610ba48383612226565b505050565b600e546001600160a01b03610100909104163314610bd95760405162461bcd60e51b8152600401610a6e906146c5565b610be281612294565b50565b60606109e482612370565b600e546001600160a01b03610100909104163314610c205760405162461bcd60e51b8152600401610a6e906146c5565b60008281526017602090815260409091208251610ba492840190613ef4565b6000818152600c60205260408120546109e4565b610c5e335b82612412565b610c7a5760405162461bcd60e51b8152600401610a6e906146fa565b610ba4838383612509565b6000806000610c93856110a8565b600081815260026020526040902054909150610cb6576000809250925050610d30565b600081815260026020526040812080548290610cd457610cd461474b565b60009182526020808320909101548483526001825260408084206001600160a01b0390921680855291909252912054909150819061271090610d1f906001600160601b031688614777565b610d2991906147ac565b9350935050505b9250929050565b600e546001600160a01b03610100909104163314610d675760405162461bcd60e51b8152600401610a6e906146c5565b610d6f612514565b565b6000838152600f60209081526040808320546010909252909120548491906001600160a01b0316610dd95760405162461bcd60e51b8152602060048201526012602482015271139bc81bd999995c881c9958da5c1a595b9d60721b6044820152606401610a6e565b6000828152600f6020526040902054610e2b5760405162461bcd60e51b81526020600482015260146024820152734e6f206f6666657220617661696c616c61626c6560601b6044820152606401610a6e565b6000828152601160205260409020541580610e5457506000828152601160205260409020544210155b610e945760405162461bcd60e51b815260206004820152601160248201527013d999995c881b9bdd081cdd185c9d1959607a1b6044820152606401610a6e565b6000828152601160205260409020600101541580610ec357506000828152601160205260409020600101544211155b610f015760405162461bcd60e51b815260206004820152600f60248201526e13d999995c881a185cc8195b991959608a1b6044820152606401610a6e565b60125460ff1615610f245760405162461bcd60e51b8152600401610a6e906147c0565b6012805460ff191660011790556000858152600f60205260408120549050803414610f855760405162461bcd60e51b8152602060048201526011602482015270125b98dbdc9c9958dd081c185e5b595b9d607a1b6044820152606401610a6e565b610f8f84866125a7565b610f9985876125b1565b610fa48660016125bb565b610fae60016125c5565b6000610fba86346125ce565b6000888152601060205260408082205490519293506001600160a01b03169182916108fc851502918591818181858888f19350505050158015611001573d6000803e3d6000fd5b50506012805460ff1916905550505050505050565b610ba4838383604051806020016040528060008152506115fc565b61103a33610c58565b61109f5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b6064820152608401610a6e565b610be2816125da565b6000818152600a60205260408120546109e4565b6110c68282612681565b5050565b60006110d582611b57565b90506000811161111d5760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cc81b9bdd081b1a5cdd1959606a1b6044820152606401610a6e565b8034146111825760405162461bcd60e51b815260206004820152602d60248201527f416d6f756e742073656e7420646f6573206e6f74206d6174636820746865206c60448201526c1a5cdd1a5b99c8185b5bdd5b9d609a1b6064820152608401610a6e565b60145460ff16156111a55760405162461bcd60e51b8152600401610a6e906147c0565b6014805460ff1916600117905560006111be83346125ce565b905060006111cb84611273565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611204573d6000803e3d6000fd5b50611210813386612509565b6112198461278b565b50506014805460ff191690555050565b600e546001600160a01b036101009091041633146112595760405162461bcd60e51b8152600401610a6e906146c5565b6112638382612794565b8115610ba457610ba4838361281b565b60006109e4826121af565b6000848152600f6020526040902054600e54859190339061010090046001600160a01b03168114806112c957506000838152601060205260409020546001600160a01b038281169116145b6113205760405162461bcd60e51b815260206004820152602260248201527f43616c6c6572206973206e6f7420746865206f776e6572206f7220637265617460448201526137b960f11b6064820152608401610a6e565b61132c87878787612889565b50505050505050565b6000818152600b60205260408120546109e4565b600e546001600160a01b036101009091041633146113795760405162461bcd60e51b8152600401610a6e906146c5565b610ba48383836129eb565b60006001600160a01b0382166113ef5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a6e565b506001600160a01b031660009081526006602052604090205490565b600e546001600160a01b0361010090910416331461143b5760405162461bcd60e51b8152600401610a6e906146c5565b610d6f6000612c65565b600e546001600160a01b036101009091041633146114755760405162461bcd60e51b8152600401610a6e906146c5565b61147f8483612794565b821561148f5761148f848461281b565b6001600160a01b0381166114b157600e5461010090046001600160a01b031690505b600084815260106020526040902080546001600160a01b0319166001600160a01b0383161790555b50505050565b600e546001600160a01b0361010090910416331461150f5760405162461bcd60e51b8152600401610a6e906146c5565b610d6f612cbf565b60606109f4612d3a565b610be28161278b565b6001600160a01b0382163314156115835760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a6e565b3360008181526008602090815260408083206001600160a01b0387168085529252909120805460ff1916841515179055906001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115f0911515815260200190565b60405180910390a35050565b6116063383612412565b6116225760405162461bcd60e51b8152600401610a6e906146fa565b6114d984848484612d49565b6060600061163b836110a8565b9050600081116116985760405162461bcd60e51b815260206004820152602260248201527f546f6b656e206973206e6f74206170617274206f662061206d756c7469636c61604482015261737360f01b6064820152608401610a6e565b600083815260176020526040812080546116b1906147e8565b9050111561175857600083815260176020526040902080546116d2906147e8565b80601f01602080910402602001604051908101604052809291908181526020018280546116fe906147e8565b801561174b5780601f106117205761010080835404028352916020019161174b565b820191906000526020600020905b81548152906001019060200180831161172e57829003601f168201915b5050505050915050919050565b61176181610be5565b9392505050565b60606000611775836110a8565b6000818152600260205260408120549192508167ffffffffffffffff8111156117a0576117a061408a565b6040519080825280602002602001820160405280156117e557816020015b60408051808201909152600080825260208201528152602001906001900390816117be5790505b50905060005b828110156118915760008481526002602052604081208054839081106118135761181361474b565b60009182526020808320909101546040805180820182526001600160a01b039092168083528985526001845281852081865284529320546001600160601b0316918101919091528451919250908490849081106118725761187261474b565b602002602001018190525050808061188990614823565b9150506117eb565b50949350505050565b6118a385612107565b156118e05760405162461bcd60e51b815260206004820152600d60248201526c21b630b9b9903334b63632b21760991b6044820152606401610a6e565b600e5461010090046001600160a01b03166001600160a01b03166119cf61199387878760405160200161193393929190928352602083019190915260601b6001600160601b031916604082015260540190565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612d7c92505050565b6001600160a01b031614611a165760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b210383937b7b31760911b6044820152606401610a6e565b60125460ff1615611a395760405162461bcd60e51b8152600401610a6e906147c0565b6012805460ff19166001179055611a5083856125a7565b611a5a84866125b1565b611a658560016125bb565b611a6f60016125c5565b50506012805460ff19169055505050565b600e546001600160a01b03610100909104163314611ab05760405162461bcd60e51b8152600401610a6e906146c5565b611abb848484611b6b565b6114d98382610bf0565b606060158054611ad4906147e8565b80601f0160208091040260200160405190810160405280929190818152602001828054611b00906147e8565b8015611b4d5780601f10611b2257610100808354040283529160200191611b4d565b820191906000526020600020905b815481529060010190602001808311611b3057829003601f168201915b5050505050905090565b6000818152601360205260408120546109e4565b600e546001600160a01b03610100909104163314611b9b5760405162461bcd60e51b8152600401610a6e906146c5565b611ba483612107565b15611be15760405162461bcd60e51b815260206004820152600d60248201526c21b630b9b9903334b63632b21760991b6044820152606401610a6e565b611beb81836125a7565b611bf582846125b1565b611c008360016125bb565b610ba460016125c5565b606060168054611ad4906147e8565b600e546001600160a01b03610100909104163314611c495760405162461bcd60e51b8152600401610a6e906146c5565b6001600160a01b038116611cae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a6e565b610be281612c65565b600e546001600160a01b03610100909104163314611ce75760405162461bcd60e51b8152600401610a6e906146c5565b60008211611d2e5760405162461bcd60e51b81526020600482015260146024820152734d697373696e672064656661756c742073697a6560601b6044820152606401610a6e565b85518360ff161115611d975760405162461bcd60e51b815260206004820152602c60248201527f4e6f7420656e6f75676820746f6b656e20636c617373657320746f206d616b6560448201526b2061206d696e74207061636b60a01b6064820152608401610a6e565b6000865167ffffffffffffffff811115611db357611db361408a565b604051908082528060200260200182016040528015611ddc578160200160208202803683370190505b5090506000806000805b8a518160ff161015611f7f5760008160ff16118015611e2b5750600085611e0e60018461483e565b60ff1681518110611e2157611e2161474b565b6020026020010151115b15611e5a5784611e3c60018361483e565b60ff1681518110611e4f57611e4f61474b565b602002602001015191505b611e7f8b8260ff1681518110611e7257611e7261474b565b6020026020010151610c3f565b935083611e8a578693505b611eaf8b8260ff1681518110611ea257611ea261474b565b6020026020010151611335565b9250838310611ee0576000858260ff1681518110611ecf57611ecf61474b565b602002602001018181525050611f6d565b611eea8385614861565b858260ff1681518110611eff57611eff61474b565b60200260200101818152505060008160ff16118015611f3a57506000858260ff1681518110611f3057611f3061474b565b6020026020010151115b15611f6d5781858260ff1681518110611f5557611f5561474b565b60200260200101818151611f699190614878565b9052505b80611f7781614890565b915050611de6565b5060008460018651611f919190614861565b81518110611fa157611fa161474b565b602002602001015190508a518860ff16111561200d5760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f75676820746f6b656e7320746f206d616b652061206d696e74604482015264207061636b60d81b6064820152608401610a6e565b60006040518060600160405280604051806080016040528085815260200160008152602001600081526020016001436120469190614861565b4090528152602081018e905260400187905260125490915060ff161561207e5760405162461bcd60e51b8152600401610a6e906147c0565b6012805460ff191660011790556000805b8a60ff168160ff1610156120ed576120ba838a60ff8e166120b18560016148b0565b60ff1610612da0565b915081156120db576120db828260ff168f6120d59190614878565b8e611b6b565b806120e581614890565b91505061208f565b50506012805460ff19169055505050505050505050505050565b60006109e482612fae565b600e546001600160a01b036101009091041633146121425760405162461bcd60e51b8152600401610a6e906146c5565b6110c68282612fe6565b3390565b60006001600160e01b031982166380ac58cd60e01b148061218157506001600160e01b03198216635b5e139f60e01b145b806109e457506301ffc9a760e01b6001600160e01b03198316146109e4565b606060038054611ad4906147e8565b6000818152600560205260408120546001600160a01b0316806109e45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a6e565b600081815260076020526040902080546001600160a01b0319166001600160a01b038416908117909155819061225b826121af565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600081815260208190526040812080546001600160601b03191690555b6000828152600260205260409020548110156110c6576000828152600160209081526040808320600290925282208054919291849081106122f4576122f461474b565b60009182526020808320909101546001600160a01b03168352828101939093526040918201812080546001600160601b0319169055848152600290925290208054829081106123455761234561474b565b600091825260209091200180546001600160a01b03191690558061236881614823565b9150506122b1565b6000818152600d6020526040902080546060919061238d906147e8565b80601f01602080910402602001604051908101604052809291908181526020018280546123b9906147e8565b80156124065780601f106123db57610100808354040283529160200191612406565b820191906000526020600020905b8154815290600101906020018083116123e957829003601f168201915b50505050509050919050565b6000818152600560205260408120546001600160a01b031661248b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a6e565b6000612496836121af565b9050806001600160a01b0316846001600160a01b031614806124d15750836001600160a01b03166124c6846109f9565b6001600160a01b0316145b8061250157506001600160a01b0380821660009081526008602090815260408083209388168352929052205460ff165b949350505050565b610ba4838383613266565b600e5460ff1661255d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a6e565b600e805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6110c68282613411565b6110c6828261342b565b6110c68282613499565b610be281613541565b6000611761838361355b565b60006125e5826121af565b90506125f3816000846136c3565b6125fe600083612226565b6001600160a01b0381166000908152600660205260408120805460019290612627908490614861565b909155505060008281526005602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b3361268b83611273565b6001600160a01b0316146126ef5760405162461bcd60e51b815260206004820152602560248201527f4f6e6c792074686520746f6b656e206f776e65722063616e206c6973742061206044820152643a37b5b2b760d91b6064820152608401610a6e565b6000811161274b5760405162461bcd60e51b8152602060048201526024808201527f4c697374696e6720616d6f756e742073686f756c64206265206d6f72652074686044820152630616e20360e41b6064820152608401610a6e565b600082815260136020526040808220839055518291849133917f6e16e8064e3c8254cef11e01e152416398602d7e8785f743f1c2f93a9a15ff3591a45050565b610be2816136ce565b6000828152600d6020526040902080546127ad906147e8565b1590506127fc5760405162461bcd60e51b815260206004820152601b60248201527f436c61737320697320616c7265616479207265666572656e63656400000000006044820152606401610a6e565b6000828152600d602090815260409091208251610ba492840190613ef4565b6000828152600c6020526040902054156128775760405162461bcd60e51b815260206004820152601760248201527f436c61737320697320616c72656164792073697a65642e0000000000000000006044820152606401610a6e565b6000918252600c602052604090912055565b6000848152601060205260409020546001600160a01b03166128e25760405162461bcd60e51b8152602060048201526012602482015271139bc81bd999995c881c9958da5c1a595b9d60721b6044820152606401610a6e565b600083116129405760405162461bcd60e51b815260206004820152602560248201527f4f6666657220616d6f756e742073686f756c64206265206d6f7265207468616e604482015264207a65726f60d81b6064820152608401610a6e565b8115801561294c575080155b8061295657508181115b6129a25760405162461bcd60e51b815260206004820152601b60248201527f53746172742074696d65206578636565647320656e642074696d6500000000006044820152606401610a6e565b6000848152600f6020526040902083905581156129cb5760008481526011602052604090208290555b80156114d957600084815260116020526040902081906001015550505050565b6000816001600160601b031611612a445760405162461bcd60e51b815260206004820152601960248201527f4665652073686f756c64206265206d6f7265207468616e2030000000000000006044820152606401610a6e565b60008381526001602090815260408083206001600160a01b03861684529091529020546001600160601b0316612b245760008381526002602090815260408083208054600180820183559185528385200180546001600160a01b0319166001600160a01b038816908117909155878552908352818420908452825280832080546001600160601b0319166001600160601b0386811691909117909155868452918390528220805484939192612afb918591166148d5565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612c01565b60008381526001602090815260408083206001600160a01b038616845282528083205486845291839052822080546001600160601b03928316939192612b6c91859116614900565b82546101009290920a6001600160601b0381810219909316918316021790915560008581526001602090815260408083206001600160a01b0388168452825280832080546001600160601b03191687861617905587835290829052812080548594509092612bdc918591166148d5565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6000838152602081905260409020546127106001600160601b039091161115610ba45760405162461bcd60e51b81526020600482015260166024820152754578636565647320616c6c6f7761626c65206665657360501b6044820152606401610a6e565b600e80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600e5460ff1615612d055760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a6e565b600e805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861258a3390565b606060048054611ad4906147e8565b612d54848484612509565b612d60848484846137dc565b6114d95760405162461bcd60e51b8152600401610a6e90614928565b6000806000612d8b85856138e9565b91509150612d9881613956565b509392505050565b600080612db285600001518585613b11565b90506000806000805b8860400151518160ff161015612fa15760008160ff16118015612e0957506040890151600090612dec60018461483e565b60ff1681518110612dff57612dff61474b565b6020026020010151115b15612e3c576040890151612e1e60018361483e565b60ff1681518110612e3157612e3161474b565b602002602001015191505b83158015612e6a5750600089604001518260ff1681518110612e6057612e6061474b565b6020026020010151115b8015612e96575088604001518160ff1681518110612e8a57612e8a61474b565b60200260200101518511155b15612f285788602001518160ff1681518110612eb457612eb461474b565b602002602001015193508189604001518260ff1681518110612ed857612ed861474b565b6020026020010151612eea9190614861565b9250600089604001518260ff1681518110612f0757612f0761474b565b602090810291909101015288518051849190612f24908390614861565b9052505b600084118015612f585750600089604001518260ff1681518110612f4e57612f4e61474b565b6020026020010151115b15612f8f578289604001518260ff1681518110612f7757612f7761474b565b60200260200101818151612f8b9190614861565b9052505b80612f9981614890565b915050612dbb565b5091979650505050505050565b6000818152600c6020526040812054158015906109e45750506000908152600c6020908152604080832054600b909252909120541490565b60008281526001602090815260408083206001600160a01b03851684529091529020546001600160601b03166130565760405162461bcd60e51b8152602060048201526015602482015274526563697069656e7420686173206e6f206665657360581b6044820152606401610a6e565b60008281526001602090815260408083206001600160a01b038516845282528083205485845291839052822080546001600160601b0392831693919261309e91859116614900565b82546001600160601b039182166101009390930a92830291909202199091161790555060008281526001602081815260408084206001600160a01b0386168552825280842080546001600160601b031916905585845260029091529091205411156132235760005b60008381526002602052604090205481101561322157600083815260026020526040902080546001600160a01b0384169190839081106131485761314861474b565b6000918252602090912001546001600160a01b0316141561320f5760008381526002602052604081205461317e90600190614861565b6000858152600260205260409020805491925090829081106131a2576131a261474b565b60009182526020808320909101548683526002909152604090912080546001600160a01b0390921691849081106131db576131db61474b565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050613221565b8061321981614823565b915050613106565b505b60008281526002602052604090208054806132405761324061497a565b600082815260209020810160001990810180546001600160a01b03191690550190555050565b826001600160a01b0316613279826121af565b6001600160a01b0316146132e15760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a6e565b6001600160a01b0382166133435760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a6e565b61334e8383836136c3565b613359600082612226565b6001600160a01b0383166000908152600660205260408120805460019290613382908490614861565b90915550506001600160a01b03821660009081526006602052604081208054600192906133b0908490614878565b909155505060008181526005602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6110c6828260405180602001604052806000815250613bf0565b6000828152600a6020526040902054156134875760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e20697320616c726561647920636c617373696669656400000000006044820152606401610a6e565b6000918252600a602052604090912055565b6000828152600b60205260408120546134b3908390614878565b6000848152600c602052604090205490915015806134df57506000838152600c60205260409020548111155b61352b5760405162461bcd60e51b815260206004820152601c60248201527f416d6f756e74206f766572666c6f777320636c6173732073697a652e000000006044820152606401610a6e565b6000928352600b60205260409092209190915550565b80600960008282546135539190614878565b909155505050565b600080613567846110a8565b9050806135ad5760405162461bcd60e51b815260206004820152601460248201527310db185cdcc8191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610a6e565b6000805b60008381526002602052604090205481101561367b5760008381526002602052604090208054829081106135e7576135e761474b565b60009182526020808320909101548583526001825260408084206001600160a01b039092168085529190925291205490925082906108fc9061271090613636906001600160601b031689614777565b61364091906147ac565b6040518115909202916000818181858888f19350505050158015613668573d6000803e3d6000fd5b508061367381614823565b9150506135b1565b506000828152602081905260408120546136a0906001600160601b0316612710614861565b90506127106136af8287614777565b6136b991906147ac565b9695505050505050565b610ba4838383613c23565b60006136d982611273565b90506001600160a01b03811633146137435760405162461bcd60e51b815260206004820152602760248201527f4f6e6c792074686520746f6b656e206f776e65722063616e2064656c6973742060448201526630903a37b5b2b760c91b6064820152608401610a6e565b6000828152601360205260409020546137945760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cc81b9bdd081b1a5cdd1959606a1b6044820152606401610a6e565b6000828152601360205260408082208290555183916001600160a01b038416917f070be797ebb4cddc2d58b4fe8de5939531dd771aaed937a59fbe5c9dc8a5d0999190a35050565b60006001600160a01b0384163b156138de57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613820903390899088908890600401614990565b602060405180830381600087803b15801561383a57600080fd5b505af192505050801561386a575060408051601f3d908101601f19168201909252613867918101906149c3565b60015b6138c4573d808015613898576040519150601f19603f3d011682016040523d82523d6000602084013e61389d565b606091505b5080516138bc5760405162461bcd60e51b8152600401610a6e90614928565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612501565b506001949350505050565b6000808251604114156139205760208301516040840151606085015160001a61391487828585613c8a565b94509450505050610d30565b82516040141561394a576020830151604084015161393f868383613d77565b935093505050610d30565b50600090506002610d30565b600081600481111561396a5761396a6149e0565b14156139735750565b6001816004811115613987576139876149e0565b14156139d55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a6e565b60028160048111156139e9576139e96149e0565b1415613a375760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a6e565b6003816004811115613a4b57613a4b6149e0565b1415613aa45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a6e565b6004816004811115613ab857613ab86149e0565b1415610be25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a6e565b60008351602085015110613b675760405162461bcd60e51b815260206004820181905260248201527f4d696e696d756d2069732067726561746572207468616e206d6178696d756d2e6044820152606401610a6e565b60008460200151856060015133868860400151604051602001613b8d94939291906149f6565b6040516020818303038152906040528051906020012060001c613bb09190614878565b9050600185604001818151613bc59190614878565b90525082613bd557600060608601525b845115612501578451613be89082614a37565b915050611761565b613bfa8383613da6565b613c0760008484846137dc565b610ba45760405162461bcd60e51b8152600401610a6e90614928565b600e5460ff1615610ba45760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b6064820152608401610a6e565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613cc15750600090506003613d6e565b8460ff16601b14158015613cd957508460ff16601c14155b15613cea5750600090506004613d6e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613d3e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613d6757600060019250925050613d6e565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01613d9887828885613c8a565b935093505050935093915050565b6001600160a01b038216613dfc5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a6e565b6000818152600560205260409020546001600160a01b031615613e615760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a6e565b613e6d600083836136c3565b6001600160a01b0382166000908152600660205260408120805460019290613e96908490614878565b909155505060008181526005602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054613f00906147e8565b90600052602060002090601f016020900481019282613f225760008555613f68565b82601f10613f3b57805160ff1916838001178555613f68565b82800160010185558215613f68579182015b82811115613f68578251825591602001919060010190613f4d565b50613f74929150613f78565b5090565b5b80821115613f745760008155600101613f79565b6001600160e01b031981168114610be257600080fd5b600060208284031215613fb557600080fd5b813561176181613f8d565b60005b83811015613fdb578181015183820152602001613fc3565b838111156114d95750506000910152565b60008151808452614004816020860160208601613fc0565b601f01601f19169290920160200192915050565b6020815260006117616020830184613fec565b60006020828403121561403d57600080fd5b5035919050565b80356001600160a01b038116811461405b57600080fd5b919050565b6000806040838503121561407357600080fd5b61407c83614044565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156140c9576140c961408a565b604052919050565b600067ffffffffffffffff8311156140eb576140eb61408a565b6140fe601f8401601f19166020016140a0565b905082815283838301111561411257600080fd5b828260208301376000602084830101529392505050565b600082601f83011261413a57600080fd5b611761838335602085016140d1565b6000806040838503121561415c57600080fd5b82359150602083013567ffffffffffffffff81111561417a57600080fd5b61418685828601614129565b9150509250929050565b6000806000606084860312156141a557600080fd5b6141ae84614044565b92506141bc60208501614044565b9150604084013590509250925092565b600080604083850312156141df57600080fd5b50508035926020909101359150565b60008060006060848603121561420357600080fd5b833592506020840135915061421a60408501614044565b90509250925092565b60008060006060848603121561423857600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561425d57600080fd5b61426986828701614129565b9150509250925092565b6000806000806080858703121561428957600080fd5b5050823594602084013594506040840135936060013592509050565b6000806000606084860312156142ba57600080fd5b833592506142ca60208501614044565b915060408401356001600160601b03811681146142e657600080fd5b809150509250925092565b60006020828403121561430357600080fd5b61176182614044565b6000806000806080858703121561432257600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561434757600080fd5b61435387828801614129565b92505061436260608601614044565b905092959194509250565b6000806040838503121561438057600080fd5b8235915061439060208401614044565b90509250929050565b600080604083850312156143ac57600080fd5b6143b583614044565b9150602083013580151581146143ca57600080fd5b809150509250929050565b600080600080608085870312156143eb57600080fd5b6143f485614044565b935061440260208601614044565b925060408501359150606085013567ffffffffffffffff81111561442557600080fd5b8501601f8101871361443657600080fd5b614445878235602084016140d1565b91505092959194509250565b602080825282518282018190526000919060409081850190868401855b82811015612fa157815180516001600160a01b031685528601516001600160601b031686850152928401929085019060010161446e565b6000806000806000608086880312156144bd57600080fd5b85359450602086013593506144d460408701614044565b9250606086013567ffffffffffffffff808211156144f157600080fd5b818801915088601f83011261450557600080fd5b81358181111561451457600080fd5b89602082850101111561452657600080fd5b9699959850939650602001949392505050565b6000806000806080858703121561454f57600080fd5b843593506020850135925061456660408601614044565b9150606085013567ffffffffffffffff81111561458257600080fd5b61444587828801614129565b600080604083850312156145a157600080fd5b6145aa83614044565b915061439060208401614044565b803560ff8116811461405b57600080fd5b60008060008060008060c087890312156145e257600080fd5b863567ffffffffffffffff808211156145fa57600080fd5b818901915089601f83011261460e57600080fd5b81356020828211156146225761462261408a565b8160051b6146318282016140a0565b928352848101820192828101908e85111561464b57600080fd5b958301955b8487101561466957863582529583019590830190614650565b9b5050508a01359750614680905060408a01614044565b955061468e60608a016145b8565b94506080890135935060a08901359150808211156146ab57600080fd5b506146b889828a01614129565b9150509295509295509295565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561479157614791614761565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826147bb576147bb614796565b500490565b6020808252600e908201526d1c99595b9d1c985b9d0818d85b1b60921b604082015260600190565b600181811c908216806147fc57607f821691505b6020821081141561481d57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561483757614837614761565b5060010190565b600060ff821660ff84168082101561485857614858614761565b90039392505050565b60008282101561487357614873614761565b500390565b6000821982111561488b5761488b614761565b500190565b600060ff821660ff8114156148a7576148a7614761565b60010192915050565b600060ff821660ff84168060ff038211156148cd576148cd614761565b019392505050565b60006001600160601b038083168185168083038211156148f7576148f7614761565b01949350505050565b60006001600160601b038381169083168181101561492057614920614761565b039392505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906136b990830184613fec565b6000602082840312156149d557600080fd5b815161176181613f8d565b634e487b7160e01b600052602160045260246000fd5b8481526001600160601b03198460601b16602082015260008351614a21816034850160208801613fc0565b6034920191820192909252605401949350505050565b600082614a4657614a46614796565b50069056fea26469706673582212200f14d2c8443fbefec721f22d191d2dd4a85c3e93f9b18663cbba2ef42622748164736f6c63430008090033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000010475259504820537472656574776561720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054752595048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a68747470733a2f2f6772792e70682f746f6b656e2f6a736f6e2f000000000000000000000000000000000000000000000000000000000000000000000000001c68747470733a2f2f6772792e70682f636f6e74726163742e6a736f6e00000000

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000010475259504820537472656574776561720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054752595048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a68747470733a2f2f6772792e70682f746f6b656e2f6a736f6e2f000000000000000000000000000000000000000000000000000000000000000000000000001c68747470733a2f2f6772792e70682f636f6e74726163742e6a736f6e00000000

-----Decoded View---------------
Arg [0] : _name (string): GRYPH Streetwear
Arg [1] : _symbol (string): GRYPH
Arg [2] : _baseTokenURI (string): https://gry.ph/token/json/
Arg [3] : _contractURI (string): https://gry.ph/contract.json

-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [5] : 4752595048205374726565747765617200000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 4752595048000000000000000000000000000000000000000000000000000000
Arg [8] : 000000000000000000000000000000000000000000000000000000000000001a
Arg [9] : 68747470733a2f2f6772792e70682f746f6b656e2f6a736f6e2f000000000000
Arg [10] : 000000000000000000000000000000000000000000000000000000000000001c
Arg [11] : 68747470733a2f2f6772792e70682f636f6e74726163742e6a736f6e00000000


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.