Contract 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 2

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x2b58921e2939083fa14b2b8e01344ac60c619c8906e3ec76466fd3a2d7188314Send Pack284469692022-05-17 23:25:384 hrs 14 mins ago0x1dd7134a77f5e3e2e63162bbdcfd494140908270 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.004341605752 37.64768
0x3a1f2c1f0d7fd418f596abc12f97389db46da531bf5c8289d2d0bda6e04980f9Send Pack284469492022-05-17 23:24:584 hrs 14 mins ago0x1dd7134a77f5e3e2e63162bbdcfd494140908270 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.005100163276 44.225414725
0x7ea62d440d43bbc3f64f34ab25762dd5d61072fd6ff8e01067125c155a45de1bSend Pack284468472022-05-17 23:21:264 hrs 18 mins ago0x1dd7134a77f5e3e2e63162bbdcfd494140908270 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.004317316197 37.43705622
0x21fed105b60936d179e5279dd8c906fd12c558a3af988b624175d41110f5318dSell Item284397252022-05-17 19:05:228 hrs 34 mins ago0x1f7b9fb9d7bfaa54ff9de366b91f01f741ef6b47 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0x0819e333e0a62ef1ab51098d8cf7d2399a65c1f779b35bf1b8bd0b2f19418688Sell Item284397182022-05-17 19:05:088 hrs 34 mins ago0x1f7b9fb9d7bfaa54ff9de366b91f01f741ef6b47 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0x542564fab520be205e078ca90fcaafa32941ea214ca2d8b330fdcdde3395ebe9Remove From Sale284396802022-05-17 19:03:528 hrs 35 mins ago0x1f7b9fb9d7bfaa54ff9de366b91f01f741ef6b47 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0040609 100
0x55b8b2cf860106fb6e96325b7f4514a2b1bde479418b5b613d96fec1e60ba98dSell Item284396732022-05-17 19:03:228 hrs 36 mins ago0x1f7b9fb9d7bfaa54ff9de366b91f01f741ef6b47 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0xb65684be9b7361673070f5e291f04009df62232a64d165d2cd03e2eb607c6606Sell Item284396672022-05-17 19:02:588 hrs 36 mins ago0x1f7b9fb9d7bfaa54ff9de366b91f01f741ef6b47 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0xbe891d40b91ade346bd5c290da525dedf832dea4837f86e818ae520db7958c27Buy Pack284382522022-05-17 18:08:209 hrs 31 mins ago0x1dd7134a77f5e3e2e63162bbdcfd494140908270 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd637 MATIC0.010443609121 41.160000004
0x29439c2dbec6c0b57bb06c3f658adab4ff8e4b51b6f1571fc99f64fc80213360Sell Item283230692022-05-14 21:37:073 days 6 hrs ago0xc7fbe09bd372edbdb9490f14254ef0cf8ec4cf73 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0043932354 37.406109998
0x81560451f246d7d6500b9d52b2bced34635dc75e5ec91664e9394ada68b7486fBuy Pack283121802022-05-14 15:17:453 days 12 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6325 MATIC0.135444400349 529.443681396
0x84b83063b07486c2d731c5dcfaac4fee6f3bffd5dec46ba9ef8d88ef7484a9a9Buy Pack283121482022-05-14 15:14:333 days 12 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6325 MATIC0.098033338458 383.206182604
0x3dfc04353914a5b278a4320ab2bbadc426d73e4dc129d99e89e823f047266b17Sell Item282898952022-05-14 1:55:054 days 1 hr ago0x25976522372ee1ecf7f1d171f7f2626389c96042 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0080447 100
0xfc2b5de14dd8c30fe668f604fd819a38afdc309707adf7e1777a287df7a9617cBuy Pack282406422022-05-12 20:17:595 days 7 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd637 MATIC0.141779723624 554.208063451
0x289c85957be5f85cf51797874bdc98da7421a27629048f8f08150519b05af5c3Buy Pack282405862022-05-12 20:15:575 days 7 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd637 MATIC0.122818246038 480.088834663
0x1f1e3be07cb8bc84b9418ef0a54e106c384a3eca8b15797632ec4ab3ec3941c8Buy Pack282405112022-05-12 20:13:195 days 7 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd637 MATIC0.211293209605 825.931928221
0xa5e9a12e40caca496db62de599557df3ef070cafea30931d2f8c4b0867d4eb37Sell Item282060022022-05-11 22:27:066 days 5 hrs ago0xb621cdf79b37ff766fa109cbef97ba3b45ed490c IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0080447 100
0xb3926fbf3864952686f34e7e771aca3b715a5fdbd5a25eb86859b6034b84bad2Sell Item282060022022-05-11 22:27:066 days 5 hrs ago0xb621cdf79b37ff766fa109cbef97ba3b45ed490c IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097547 100
0xfa9002e3a8fe27be077eaa2650b1f25d83cff3425c436f8fcda6a12574f3c948Buy Pack282053082022-05-11 22:03:086 days 5 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6325 MATIC0.208731573123 815.918651588
0xd08b75ec8e80fd06b29bbaa81999596138539482f8366f782e585ed4d520d222Buy Pack282046052022-05-11 21:36:486 days 6 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6335 MATIC11.73264189747 10,950.512493159
0xcba6efad57cb809576455ed96cd76ab80ccd9bb92c1ea28f03f401186454f3d4Buy Pack282045132022-05-11 21:29:326 days 6 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6375 MATIC4.836461416253 7,287.954348025
0x189558a1dfa30f78ca5744f34ba7923dba99412496d06e2a36a9e4601d73b274Buy Pack282020352022-05-11 19:52:346 days 7 hrs ago0xc16157e00b1bff1522c6f01246b4fb621da048d0 IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd6325 MATIC1.005774678057 3,931.510249457
0x4e5605be275cff6f3e7693909d48db33e968a3607bb2a4d2c4b72fa3aba31aacSell Item281985102022-05-11 17:23:316 days 10 hrs ago0xb621cdf79b37ff766fa109cbef97ba3b45ed490c IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0xf567c46b1709982d58619199c921dd4be85b1417200e592ef9121d31721efc2eSell Item281985102022-05-11 17:23:316 days 10 hrs ago0xb621cdf79b37ff766fa109cbef97ba3b45ed490c IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
0x51c590ff707775bd28c5d504d74b1a3a326fa981e045b0e9d3040f66ba3c27faSell Item281985102022-05-11 17:23:316 days 10 hrs ago0xb621cdf79b37ff766fa109cbef97ba3b45ed490c IN  0xc3f25ee6dadcabbd6267bd86e8991acb0476fd630 MATIC0.0097535 100
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xbe891d40b91ade346bd5c290da525dedf832dea4837f86e818ae520db7958c27284382522022-05-17 18:08:209 hrs 31 mins ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x81560451f246d7d6500b9d52b2bced34635dc75e5ec91664e9394ada68b7486f283121802022-05-14 15:17:453 days 12 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb425 MATIC
0x84b83063b07486c2d731c5dcfaac4fee6f3bffd5dec46ba9ef8d88ef7484a9a9283121482022-05-14 15:14:333 days 12 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb425 MATIC
0xfc2b5de14dd8c30fe668f604fd819a38afdc309707adf7e1777a287df7a9617c282406422022-05-12 20:17:595 days 7 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x289c85957be5f85cf51797874bdc98da7421a27629048f8f08150519b05af5c3282405862022-05-12 20:15:575 days 7 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x1f1e3be07cb8bc84b9418ef0a54e106c384a3eca8b15797632ec4ab3ec3941c8282405112022-05-12 20:13:195 days 7 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0xfa9002e3a8fe27be077eaa2650b1f25d83cff3425c436f8fcda6a12574f3c948282053082022-05-11 22:03:086 days 5 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb425 MATIC
0xd08b75ec8e80fd06b29bbaa81999596138539482f8366f782e585ed4d520d222282046052022-05-11 21:36:486 days 6 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb435 MATIC
0xcba6efad57cb809576455ed96cd76ab80ccd9bb92c1ea28f03f401186454f3d4282045132022-05-11 21:29:326 days 6 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb475 MATIC
0x189558a1dfa30f78ca5744f34ba7923dba99412496d06e2a36a9e4601d73b274282020352022-05-11 19:52:346 days 7 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb425 MATIC
0x24d35643097221264b5c46016796253c4346a96bb550df2d87fa236d8f77061e281959182022-05-11 15:48:036 days 11 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb426.25 MATIC
0x017afed85a3c54a2e5bba0c228440a4848fd57c97a0db78e1667a04a1af026bc281957372022-05-11 15:41:486 days 11 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb425 MATIC
0x8321f5e6866c995f5d1581e4a220f15a18bd5b0c675799c50824348a3b23cfa4281645222022-05-10 20:02:397 days 7 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x445a1841d6cfd5298c8424051c459e27fe7b9da54aaec4bc5d3b875eaabb90cf281348302022-05-10 2:28:198 days 1 hr ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0xbb4ee3b57f07c943bcd48cca693638f83a0f8655a16363ab439c14ec202b082f281063632022-05-09 9:16:418 days 18 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0xc1a7db1074fa3ad501f314cce0daf14bec4f79bc1ea3d5d2fac791eaf19936ae280987082022-05-09 4:42:508 days 22 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0x68c24ef360c3bef45b2188f06642efb027ab9d213c5f8ec04dee09bff1ac1d2b280985792022-05-09 4:37:308 days 23 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0x4a2a60b67539214dba36965a9f451c4d4bb3abb0f0141b738154a500792420c6280985042022-05-09 4:34:568 days 23 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0xf8cb0469ec283c8c5993eb2fbf61388e58b75d2b24f87a190f506c8457fe9873280984132022-05-09 4:31:468 days 23 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0x8ca8340d2c5820dc305a2ea900c4789ce4103365e02ec098d6f13546fa1b5ff7280983332022-05-09 4:29:028 days 23 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb412.6 MATIC
0xc041e5a69d38024e26aa18c5852ae24f1ff6b05bca3a6695df012c2b046652e1280755322022-05-08 14:42:579 days 12 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0xffdc1c70b05758ed0543405afd9a7480fb12fda71c1eb6c72bf2c15dfab0a6aa280424332022-05-07 18:38:3410 days 9 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
0x13ea99ae0e091bd8ad360677c465e8d6d37b24407b8d55e3b1680b1381332544280401212022-05-07 17:16:4210 days 10 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x4a9af504adcbbe500f3931a6212cd08df5c9bd57a6f41f3e9a2133ca5bc9776d280079082022-05-06 22:27:0411 days 5 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47 MATIC
0x6a2dad0ecca94b6d1493f0dc59c9b663fd2b110e8f13b3aa7e89cef7d7fbd532279642662022-05-05 19:33:4912 days 8 hrs ago 0xc3f25ee6dadcabbd6267bd86e8991acb0476fd63 0xa43c9d200995a8fa67aafd82ccba49c438c34bb47.35 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Proxy

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 1 of 17: Proxy.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;

import "./Storage.sol";
import "./Ownable.sol";
contract Proxy is Storage, Ownable {
    address public currentAddress;
    constructor(address _currentAddress, address multisigAddress, address payable _pay) {
        currentAddress = _currentAddress;
        _multisig = multisigAddress;
        pay = _pay;
    }
    
    function changePay(address payable _newPay) public onlyMultisig {
        pay = _newPay;
    }

    function upgrade(address _newAddress) public onlyMultisig{
        require(_newAddress != address(0), "Proxy: new address is the zero address");
        require(_newAddress != currentAddress, "Proxy: new address is already current address");
        
        currentAddress = _newAddress;
    }

    fallback () payable external {
        //Redirect to current address
        address implementation = currentAddress;
        require(currentAddress != address(0));
        bytes memory _data = msg.data;

        assembly {
            let result := delegatecall(gas(), implementation, add(_data, 0x20), mload(_data), 0, 0)
            let size := returndatasize()
            let ptr := mload(0x40)
            returndatacopy(ptr, 0, size)
            switch result 
            case 0 {revert(ptr, size)}
            default {return(ptr, size)}
        }
    }
    
     receive() external payable virtual { }
    
}

File 2 of 17: 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;
        // solhint-disable-next-line no-inline-assembly
        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");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 3 of 17: 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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 4 of 17: Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (utils/Counters.sol)

pragma solidity ^0.8.0;

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

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

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

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

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 5 of 17: ERC1155.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./IERC1155MetadataURI.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";
import "./Ownable.sol";
import "./Storage.sol";

/**
 *
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, Ownable {
    using Address for address;

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;
    

    /**
     * @dev See {_setURI}.
     */
    constructor (string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    )
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(_msgSender() != operator, "ERC1155: setting approval status for self");

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

    /**
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[account][operator];
    }
    
    function setSaleApproval(address operator, uint256 id, bool approved) public {
        _idApprovals[itemsForSale[id].owner][operator][id] = approved;
        
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    )
        public
        virtual
        override
        /*payable*/
    {
        require(to != address(0), "ERC1155: transfer to the zero address");
        
        // THIS PORTION HAS BEEN MODIFIED FROM ITS ORIGINAL FORM AND NEEDS 
        // TO BE CHECKED FOR SECURITY FLAWS
        // MODIFIED PORTION BEGINS: 
        
        // Transfer is allowed if the caller is the owner of the item or 
        // if the owner of the item has approved the caller to make the transfer or 
        // if the caller is a buyer who has passed all checks and submitted adequate payment 
         require(
            from == _msgSender() || 
            isApprovedForAll(from, _msgSender()) || 
            (isApprovedForAll(from, owner()) || _idApprovals[from][to][id]),
            "ERC1155: transfer caller is not owner nor approved"
        );
        
        // Prevent reentrancy
        _idApprovals[from][to][id] = false;
        
        // Require the transfer is being made from within our marketplace contract
        // And not being transferred outside of the marketplace 
        require(isLocal[id][to], "ERC1155: transfer outside of marketplace unauthorized.");
    
        // This portion is redundant, because transfers outside of marketplace are already prohibited
        // Will be useful when we do allow outside transfers, though
        // Can get creative with Royalty model
       // if(!isLocal[id][to] && _msgSender() != owner()) {
            //require(activeItems[from][id] == false, "ERC1155: cannot transfer item while it is for sale");
            // require(msg.value == itemsForSale[id].royalty, "ERC1155: must pay transfer fee");
            // uint256 royalty = itemsForSale[id].royalty;
            // itemsForSale[id].royalty = itemsForSale[id].royalty * 2;
            // itemsForSale[id].royaltyRecipient.transfer(royalty);
        //}
        
        // Set isLocal to false to prevent reentrancy attack
        isLocal[id][to] = false;
        
        // MODIFIED PORTION ENDS
        // The intent of the modifications was 
        // To make it impossible for users to transfer their NFTs outside of our marketplace. We will allow this when royalties
        // can be enforced on outside marketplaces.
        
        
        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
        
        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        _balances[id][from] = fromBalance - amount;
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        public
        virtual
        override
    {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()) || isPackPurchase[from][to],
            "ERC1155: transfer caller is not owner nor approved"
        );
        isPackPurchase[from][to] = false;
        
        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            // Make sure batch transfer is not used to send NFTs outside of our marketplace
            require(isLocal[ids[i]][to] == true, "ERC1155: Transfer not authorized");
            // Set isLocal to false to prevent reentrancy attack 
            isLocal[ids[i]][to] = false;
            require(activeItems[from][ids[i]] == false, "ERC1155: Cannot transfer item while it is for sale");
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            _balances[id][from] = fromBalance - amount;
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
        require(account != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][account] += amount;
        emit TransferSingle(operator, address(0), account, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `account`
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens of token type `id`.
     */
    function _burn(address account, uint256 id, uint256 amount) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");

        uint256 accountBalance = _balances[id][account];
        require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
        _balances[id][account] = accountBalance - amount;

        emit TransferSingle(operator, account, address(0), id, amount);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");

        for (uint i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 accountBalance = _balances[id][account];
            require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
            _balances[id][account] = accountBalance - amount;
        }

        emit TransferBatch(operator, account, address(0), ids, amounts);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        internal
        virtual
    { }

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    )
        private
    {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver(to).onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        private
    {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
                if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

File 6 of 17: 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 7 of 17: IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

File 8 of 17: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

import "./IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 9 of 17: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.0;

import "./IERC165.sol";

/**
 * _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {

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

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

File 10 of 17: 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 11 of 17: Marketplace.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;

import "./Tokens.sol";
import "./SafeMath.sol";
import "./Counters.sol";
contract Marketplace is Tokens {
    // Function for owner to withdraw all funds from contract 
    // Use only in emergencies and make sure all users' pending payouts are recorded so no one loses funds
    function withdrawAll() public onlyMultisig {
        require(address(this).balance > 0, "Marketplace: No funds in contract.");
        (bool success,) = pay.call{value: address(this).balance}("");
        require(success, "Transfer fail");

    }

    // Function for owner to put a batch for sale on the marketplace
    // Buying this batch/pack gives the buyer ownership of all contents in the pack
    function sellPack(string memory packName, uint256[] memory _ids, uint256[] memory _amounts, uint256 price) public onlyOwner {
        // Pack size will be from 3 to 7 items
        for(uint i = 0; i < _ids.length; i++) {
            require(balanceOf(owner(), _ids[i]) >= _amounts[i], "Marketplace: Owner does not own enough of each item");
            require(activeItems[_msgSender()][_ids[i]] == true, "Marketplace: Already in pack or sold");
            activeItems[_msgSender()][_ids[i]] = false;
        }
        
        uint newBatchId = Counters.current(batchID);
        batchesForSale.push(Pack(_ids, price, _amounts, packName, false));

        emit batchAddedForSale(packName, newBatchId, _ids, price);
        Counters.increment(batchID);
    }
    
    // Takes a pack off of the marketplace
    function dissolvePack(uint256 batchId) public onlyOwner {
        require(batchesForSale[batchId].isSold == false, "Marketplace: Pack has already been sold or dissovled.");
        //require(activeBatches[_msgSender()][batchId] == true, "Marketplace: Pack has already been sold or removed from sale.");
        batchesForSale[batchId].isSold = true;
        //activeBatches[_msgSender()][batchId] = false;
    }
    
    // Function to remove an item from marketplace.
    // Can be used to take item off of primary or secondary marketplace
    function removeFromSale(uint256 _id) public whenNotPaused {
        require(activeItems[_msgSender()][_id] == true);
        require(itemsForSale[_id].owner == _msgSender());
        
        activeItems[_msgSender()][_id] = false;
        setApprovalForAll(owner(), false);
    }
    
    // Function for user to sell an item they own 
    // on the secondary marketplace, which allows crypto payments only 
    // Payments must be on Polygon network 
    function sellItem(uint256 id, uint256 _price) public whenNotPaused {
        require(itemsForSale[id].owner == _msgSender(), "Marketplace: you do not own this item");
        require(balanceOf(_msgSender(), id) > 0, "Marketplace: you do not own this item");
        require(!activeItems[_msgSender()][id], "Marketplace: item is already for sale by message sender");
        require(_price >= 5, "Marketplace: item price must be at least 5 MATIC");

        activeItems[_msgSender()][id] = true;
        setApprovalForAll(address(this), true);
        itemsForSale[id].price = _price;
        emit itemAddedForSale(id, _msgSender(), _price, itemsForSale[id].URI);
    }
    
    function buy(uint256 id, address recipient, bool wert) public payable whenNotPaused {
        require(activeItems[itemsForSale[id].owner][id] == true, "Marketplace: item is not for sale by owner");
        require(itemsForSale[id].owner != owner(), "Marketplace: item is not purchasable via this function");
        activeItems[itemsForSale[id].owner][id] = false;
        //uint256 cost = itemsForSale[id].price * 1000000;
        uint256 cost = itemsForSale[id].price * 1000000000000000000;
        uint256 fee = 0;
        
        if(!wert) {
            fee = cost / 20;
        }
        require(msg.value == (cost + fee), "Value sent is not equal to price + fee");

        uint256 royalty = cost / royaltyPortion;
        uint256 payout = cost - royalty;
        
        // Should probably make royalty recipient different account 
        // from owner, for security reasons
        // Done, using address pay 
        // usdc.transferFrom(_msgSender(), itemsForSale[id].owner, payout);
        // usdc.transferFrom(_msgSender(), pay, royalty + fee);
        
        itemsForSale[id].owner.transfer(payout);
        (bool success,) = pay.call{value: royalty + fee}("");
        require(success, "Transfer fail");

        isLocal[id][recipient] = true;
        setSaleApproval(recipient, id, true);
        address oldOwner = itemsForSale[id].owner;
        safeTransferFrom(itemsForSale[id].owner, recipient, id, 1, data);
        itemsForSale[id].owner = payable(_msgSender());
        emit itemBought(id, cost, payout, royalty, oldOwner, _msgSender());
    }
    
    function buyPack(uint256[] memory packId, address recipient, bool wert) public payable whenNotPaused{
        uint256 totalCost;
        for(uint k = 0; k < packId.length; k++) {
            require(batchesForSale[packId[k]].price != 0, "Starter Packs not purchasable");
            totalCost += batchesForSale[packId[k]].price * 1000000000000000000;
        }
        uint256 fee = 0;
        if(!wert) {
            fee = totalCost / 20;
        }
        
        require(msg.value == (totalCost + fee), "Value sent is not equal to price + fee");

        (bool success, ) = pay.call{value: msg.value}(""); // This forwards all available gas
        require(success, "Transfer failed."); // Return value is checked   

        
        for(uint i = 0; i < packId.length; i++) {
            require(batchesForSale[packId[i]].isSold == false, "Marketplace: Pack has already been sold.");
            batchesForSale[packId[i]].isSold = true;
            
            isPackPurchase[owner()][recipient] = true;
            for(uint256 j = 0; j < batchesForSale[packId[i]].tokenIds.length; j++) {
                isLocal[batchesForSale[packId[i]].tokenIds[j]][recipient] = true;
                itemsForSale[batchesForSale[packId[i]].tokenIds[j]].owner = payable(recipient);
            }
            safeBatchTransferFrom(owner(), recipient, batchesForSale[packId[i]].tokenIds, batchesForSale[packId[i]].amounts, data);   
        }
        
        emit packBought(packId, totalCost + fee, _msgSender());
    }
    
    // Function to send a batch of NFTs to a user account
    // Batch is minted to recipient's account
    // To be used for NFT giveaways and promotions
    function sendPack(uint256[] memory packId, address[] memory recipient) public onlyOwner {
        require(packId.length == recipient.length, "Mismatched ID and Address array sizes");
        for(uint i = 0; i < packId.length; i++) {
            require(batchesForSale[packId[i]].isSold == false, "Pack has already been sold.");
            
            batchesForSale[packId[i]].isSold = true;
            // Take pack off of marketplace 

            for(uint256 j = 0; i < batchesForSale[packId[i]].tokenIds.length; j++) {
                isLocal[batchesForSale[packId[i]].tokenIds[j]][recipient[i]] = true;
                itemsForSale[batchesForSale[packId[i]].tokenIds[j]].owner = payable(recipient[i]);
            }
            safeBatchTransferFrom(_msgSender(), recipient[i], batchesForSale[packId[i]].tokenIds, batchesForSale[packId[i]].amounts, data);
        }
    }
}

File 12 of 17: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <=0.8.0;
import "./Storage.sol";
import "./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 Storage, Context {
    address private _owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }
    
    function multisig() public view virtual returns (address) {
        return _multisig;
    }
    
    modifier onlyMultisig() {
        require(multisig() == _msgSender(), "Ownable: caller is not Multisig wallet");
        _;
    }
    

    /**
     * @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 {
    //     emit OwnershipTransferred(_owner, address(0));
    //     _owner = 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 onlyMultisig {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
            emit OwnershipTransferred(_owner, newOwner);
            _owner = newOwner;
    }
}

File 13 of 17: Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Context.sol";
import "./Ownable.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.
 */
contract Pausable is Context, Ownable {
    /**
     * @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 _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() public whenNotPaused onlyOwner {
        _paused = true;
        emit Paused(_msgSender());
    }

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

File 14 of 17: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

File 15 of 17: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

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

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

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

File 16 of 17: Storage.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
import "./Counters.sol";

contract Storage {
    using Counters for Counters.Counter;
    Counters.Counter public currentID;
    Counters.Counter public batchID;

    address _multisig;
    
    // Variable storage for upgraded contracts
    mapping(string => uint256) _uintStorage;
    mapping(string => address) _addressStorage;
    mapping(string => bool) _boolStorage;
    mapping(string => string) _stringStorage;
    mapping(string => bytes) _bytesStorage;

    // Events
    event itemAddedForSale(uint256 id, address seller, uint256 askingPrice, string info);
    event batchAddedForSale(string packName, uint256 batchId, uint256[] tokenId, uint256 priceOfBatch);
    event singleItemCreated(uint256 _id, uint256 _amount, string _data);
    event itemBalance(address sender, uint256 _id, uint256 balance, string data);
    event serializedItemCreated(uint256[] _ids, string _data);
    event itemBought(uint256 id, uint256 price, uint256 payout, uint256 royalty, address seller, address buyer);
    event packBought(uint256[] packId, uint256 price, address buyer);
    
    // struct of items for sale
    struct Item { 
        uint256 tokenId; //ID set when item was created
        address payable owner; //address of person selling item
        //uint256 askingPrice; //in Wei (1 * 10^(-18) Ether)
        //string info;  // Description of NFT
        string URI; // Link to media content
        //uint royalty;  // Portion of sale that will be sent to royalty recipient at point of resell
        //address payable royaltyRecipient; // Recipient of royaltyPortion
        //bool isMinted;  // True or False value telling whether item has been sold or not. Once set to false, the item is considered to be on the "secondary marketplace" 
                    // "primary marketplace" being the initial sell of the NFT by us
        uint256 price;
   }
   
   struct Pack {
        uint256[] tokenIds;     //IDs of NFTs within the pack
        //address payable seller; // Seller of the pack (will always be contract owner, secondary market will not allow for packs)
        uint256 price;   // Price of the pack
        uint256[] amounts;      // Amounts of each ID in the pack (will always be 1 per ID)
        string batchName;       // Name of the pack
        bool isSold;            // True or false value telling whether the pack has been sold. Once set to false, the items contained in the pack are considered to be on the 
                                // secondary marketplace
    }
    
    // Creates arrays of instances of the above structs
    Item[] public itemsForSale;
    Pack[] public batchesForSale;

    // Data variable 
    // Needed for mint and transfer functions
    bytes data = "Fandem";
    
    // Denominator in division of item price at point of sale
    // Portion of price to be sent to owner as royalty 
    uint256 royaltyPortion = 10;
    address payable pay;

    // Mapping of address to boolean value. Used to determine whether a transfer is taking place from our "rebuy" function
    // If set to true, the transfer is allowed, otherwise it is not allowed
    // This is to keep NFTs from leaving our marketplace. 
    mapping(uint256 => mapping(address => bool)) isLocal;
    mapping(address => mapping(address => bool)) isPackPurchase;
    // Contains the addresses of items on the marketplace and 
    // associates them with a bool value representing whether 
    // they are actively for sale.
    mapping(address => mapping(uint256 => bool)) public activeItems; 
    //mapping(address => mapping(uint256 => bool)) public activeBatches; 

    // Mapping from token ID to account balances, moved from ERC1155 to Storage.sol
    mapping (uint256 => mapping(address => uint256)) public _balances;

    // Mapping from account to operator approvals, moved from ERC1155 to Storage.sol
    mapping (address => mapping(address => bool)) public _operatorApprovals;
    
    // Used to authorize transfers through our "rebuy" function
    // Once the buyer has called the "rebuy" function and passes all require checks
    // their address is approved and the transfer is allowed to proceed
    // Described logic is in ERC1155.sol
    mapping(address => mapping(address => mapping(uint256 => bool))) public _idApprovals;

}

File 17 of 17: Tokens.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;

import "./ERC1155.sol";
import "./Ownable.sol";
import "./Pausable.sol";
import "./SafeMath.sol";

contract Tokens is ERC1155, Pausable {
    
    constructor() ERC1155("https://glorysmacks.com") {
        
    }
    
    // Mint a new item
    // This function could be used to mint items when their serial number is not important
    // Could be promotional items or very cheap items
    function createNewSingle(uint256 _amount, string memory URI) public onlyOwner {
        require(_amount > 0);

        uint256 newItemId = itemsForSale.length;
        itemsForSale.push(Item(newItemId, payable(_msgSender()), URI, 0));
        _mint(_msgSender(), newItemId, _amount, data);
        // Item will be minted at point of purchase
        emit singleItemCreated(itemsForSale[newItemId].tokenId, _amount, itemsForSale[newItemId].URI);
    }

    // Mint a new collection of items
    // To be used to mint items when the serial number is important
    // Each item in the batch will have a unique serial ID which will tell the user how early the item is in the batch 
    function createNewSerializedItem(uint256[] memory _ids, string memory URI, uint256[] memory amounts) public onlyOwner {
                                    // _ids variable is used only to capture the amount of items to be created 
                                    // the ids inputted will not be saved, rather they will be updated in the for loop
                                    // inputting an amount into the variable and using that in the for loop will return an error for some reason
        uint256 itemNum = itemsForSale.length;
        for(uint i = 0; i < _ids.length; i++) {
            _ids[i] = itemNum;
            itemsForSale.push(Item(_ids[i], payable(_msgSender()), URI, 0));

            activeItems[_msgSender()][_ids[i]] = true;

            itemNum = SafeMath.add(itemNum, 1);
            
        }
        
        _mintBatch(_msgSender(), _ids, amounts, data);

        emit serializedItemCreated(_ids, "Fandem");
    }
    
    // Function for owner to update the URI of an item 
    // Use in case item's URI is no longer pointing to intended material 
    function changeItemURI(uint256 _id, string memory _URI) public onlyOwner {
        itemsForSale[_id].URI = _URI;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_currentAddress","type":"address"},{"internalType":"address","name":"multisigAddress","type":"address"},{"internalType":"address payable","name":"_pay","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"string","name":"packName","type":"string"},{"indexed":false,"internalType":"uint256","name":"batchId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tokenId","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"priceOfBatch","type":"uint256"}],"name":"batchAddedForSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"askingPrice","type":"uint256"},{"indexed":false,"internalType":"string","name":"info","type":"string"}],"name":"itemAddedForSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"itemBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"royalty","type":"uint256"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"itemBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"packId","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"packBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"serializedItemCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"singleItemCreated","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"_balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_idApprovals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"_operatorApprovals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"activeItems","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"batchID","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"batchesForSale","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"string","name":"batchName","type":"string"},{"internalType":"bool","name":"isSold","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newPay","type":"address"}],"name":"changePay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentID","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"itemsForSale","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address payable","name":"owner","type":"address"},{"internalType":"string","name":"URI","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"upgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c0604052600660808190526546616e64656d60d01b60a09081526200002991600a919062000100565b50600a600b553480156200003c57600080fd5b5060405162000d4d38038062000d4d8339810160408190526200005f91620001a6565b60006200006b620000fc565b601380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350601480546001600160a01b039485166001600160a01b0319918216179091556002805493851693821693909317909255600c80549190931691161790556200024f565b3390565b8280546200010e90620001f9565b90600052602060002090601f0160209004810192826200013257600085556200017d565b82601f106200014d57805160ff19168380011785556200017d565b828001600101855582156200017d579182015b828111156200017d57825182559160200191906001019062000160565b506200018b9291506200018f565b5090565b5b808211156200018b576000815560010162000190565b600080600060608486031215620001bb578283fd5b8351620001c88162000236565b6020850151909350620001db8162000236565b6040850151909250620001ee8162000236565b809150509250925092565b6002810460018216806200020e57607f821691505b602082108114156200023057634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b03811681146200024c57600080fd5b50565b610aee806200025f6000396000f3fe6080604052600436106100e15760003560e01c80638da5cb5b1161007f578063edc3bc3f11610059578063edc3bc3f146102a8578063f2fde38b146102c8578063f8712fbc146102e8578063fc25a4da14610317576100e8565b80638da5cb5b1461025e578063a18d812214610273578063eca4f6a314610288576100e8565b80634783c35b116100bb5780634783c35b146101da5780634b1b921f146101fc578063684eaeca1461022957806381bf471814610249576100e8565b80630900f0101461015d578063092d0afc1461017f5780631c75cfb4146101b8576100e8565b366100e857005b6014546001600160a01b0316806100fe57600080fd5b600080368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525084519495509384935091505060208401855af43d604051816000823e828015610159578282f35b8282fd5b34801561016957600080fd5b5061017d61017836600461076b565b610337565b005b34801561018b57600080fd5b5061019f61019a366004610831565b6103f5565b6040516101af94939291906109ff565b60405180910390f35b3480156101c457600080fd5b506101cd6104c4565b6040516101af91906109f6565b3480156101e657600080fd5b506101ef6104ca565b6040516101af91906108b8565b34801561020857600080fd5b5061021c6102173660046107c6565b6104d9565b6040516101af91906108cc565b34801561023557600080fd5b5061017d61024436600461076b565b6104ff565b34801561025557600080fd5b506101ef610560565b34801561026a57600080fd5b506101ef61056f565b34801561027f57600080fd5b506101cd61057e565b34801561029457600080fd5b5061021c6102a3366004610806565b610584565b3480156102b457600080fd5b5061021c6102c336600461078e565b6105a4565b3480156102d457600080fd5b5061017d6102e336600461076b565b6105c4565b3480156102f457600080fd5b50610308610303366004610831565b610685565b6040516101af93929190610a3a565b34801561032357600080fd5b506101cd610332366004610849565b61074a565b61033f610767565b6001600160a01b03166103506104ca565b6001600160a01b03161461037f5760405162461bcd60e51b8152600401610376906109b0565b60405180910390fd5b6001600160a01b0381166103a55760405162461bcd60e51b8152600401610376906108d7565b6014546001600160a01b03828116911614156103d35760405162461bcd60e51b81526004016103769061091d565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6008818154811061040557600080fd5b60009182526020909120600490910201805460018201546002830180549294506001600160a01b03909116929161043b90610a65565b80601f016020809104026020016040519081016040528092919081815260200182805461046790610a65565b80156104b45780601f10610489576101008083540402835291602001916104b4565b820191906000526020600020905b81548152906001019060200180831161049757829003601f168201915b5050505050908060030154905084565b60005481565b6002546001600160a01b031690565b601260209081526000938452604080852082529284528284209052825290205460ff1681565b610507610767565b6001600160a01b03166105186104ca565b6001600160a01b03161461053e5760405162461bcd60e51b8152600401610376906109b0565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6014546001600160a01b031681565b6013546001600160a01b031690565b60015481565b600f60209081526000928352604080842090915290825290205460ff1681565b601160209081526000928352604080842090915290825290205460ff1681565b6105cc610767565b6001600160a01b03166105dd6104ca565b6001600160a01b0316146106035760405162461bcd60e51b8152600401610376906109b0565b6001600160a01b0381166106295760405162461bcd60e51b81526004016103769061096a565b6013546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3601380546001600160a01b0319166001600160a01b0392909216919091179055565b6009818154811061069557600080fd5b90600052602060002090600502016000915090508060010154908060030180546106be90610a65565b80601f01602080910402602001604051908101604052809291908181526020018280546106ea90610a65565b80156107375780601f1061070c57610100808354040283529160200191610737565b820191906000526020600020905b81548152906001019060200180831161071a57829003601f168201915b5050506004909301549192505060ff1683565b601060209081526000928352604080842090915290825290205481565b3390565b60006020828403121561077c578081fd5b813561078781610aa0565b9392505050565b600080604083850312156107a0578081fd5b82356107ab81610aa0565b915060208301356107bb81610aa0565b809150509250929050565b6000806000606084860312156107da578081fd5b83356107e581610aa0565b925060208401356107f581610aa0565b929592945050506040919091013590565b60008060408385031215610818578182fd5b823561082381610aa0565b946020939093013593505050565b600060208284031215610842578081fd5b5035919050565b6000806040838503121561085b578182fd5b8235915060208301356107bb81610aa0565b60008151808452815b8181101561089257602081850181015186830182015201610876565b818111156108a35782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b901515815260200190565b60208082526026908201527f50726f78793a206e6577206164647265737320697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252602d908201527f50726f78793a206e6577206164647265737320697320616c726561647920637560408201526c7272656e74206164647265737360981b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526026908201527f4f776e61626c653a2063616c6c6572206973206e6f74204d756c7469736967206040820152651dd85b1b195d60d21b606082015260800190565b90815260200190565b8481526001600160a01b0384166020820152608060408201819052600090610a299083018561086d565b905082606083015295945050505050565b600084825260606020830152610a53606083018561086d565b90508215156040830152949350505050565b600281046001821680610a7957607f821691505b60208210811415610a9a57634e487b7160e01b600052602260045260246000fd5b50919050565b6001600160a01b0381168114610ab557600080fd5b5056fea264697066735822122059f6f21ca3103d5ef91a0e3f443267d27d5bdb0d3277481f392138c9a5f29e7064736f6c63430008000033000000000000000000000000996403ea8910a16a959751872249b3f595d7b156000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4

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

000000000000000000000000996403ea8910a16a959751872249b3f595d7b156000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4

-----Decoded View---------------
Arg [0] : _currentAddress (address): 0x996403ea8910a16a959751872249b3f595d7b156
Arg [1] : multisigAddress (address): 0xa43c9d200995a8fa67aafd82ccba49c438c34bb4
Arg [2] : _pay (address): 0xa43c9d200995a8fa67aafd82ccba49c438c34bb4

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000996403ea8910a16a959751872249b3f595d7b156
Arg [1] : 000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4
Arg [2] : 000000000000000000000000a43c9d200995a8fa67aafd82ccba49c438c34bb4


Deployed ByteCode Sourcemap

110:1294:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;888:14;;-1:-1:-1;;;;;888:14:12;920:28;912:37;;;;;;959:18;980:8;;959:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1090:12:12;;959:29;;-1:-1:-1;959:29:12;;;-1:-1:-1;1090:12:12;-1:-1:-1;;1083:4:12;1072:16;;1056:14;1049:5;1036:73;1134:16;1180:4;1174:11;1221:4;1218:1;1213:3;1198:28;1246:6;1266:26;;;;1326:4;1321:3;1314:17;1266:26;1286:4;1281:3;1274:17;486:294;;;;;;;;;;-1:-1:-1;486:294:12;;;;;:::i;:::-;;:::i;:::-;;2631:26:15;;;;;;;;;;-1:-1:-1;2631:26:15;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;151:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1034:91:10:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;4246:84:15:-;;;;;;;;;;-1:-1:-1;4246:84:15;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;386:94:12:-;;;;;;;;;;-1:-1:-1;386:94:12;;;;;:::i;:::-;;:::i;151:29::-;;;;;;;;;;;;;:::i;1345:85:10:-;;;;;;;;;;;;;:::i;190:31:15:-;;;;;;;;;;;;;:::i;3517:63::-;;;;;;;;;;-1:-1:-1;3517:63:15;;;;;:::i;:::-;;:::i;3903:71::-;;;;;;;;;;-1:-1:-1;3903:71:15;;;;;:::i;:::-;;:::i;2283:251:10:-;;;;;;;;;;-1:-1:-1;2283:251:10;;;;;:::i;:::-;;:::i;2663:28:15:-;;;;;;;;;;-1:-1:-1;2663:28:15;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;3746:65::-;;;;;;;;;;-1:-1:-1;3746:65:15;;;;;:::i;:::-;;:::i;486:294:12:-;1191:12:10;:10;:12::i;:::-;-1:-1:-1;;;;;1177:26:10;:10;:8;:10::i;:::-;-1:-1:-1;;;;;1177:26:10;;1169:77;;;;-1:-1:-1;;;1169:77:10;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;561:25:12;::::1;553:76;;;;-1:-1:-1::0;;;553:76:12::1;;;;;;;:::i;:::-;662:14;::::0;-1:-1:-1;;;;;647:29:12;;::::1;662:14:::0;::::1;647:29;;639:87;;;;-1:-1:-1::0;;;639:87:12::1;;;;;;;:::i;:::-;745:14;:28:::0;;-1:-1:-1;;;;;;745:28:12::1;-1:-1:-1::0;;;;;745:28:12;;;::::1;::::0;;;::::1;::::0;;486:294::o;2631:26:15:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;2631:26:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;151:33::-;;;;:::o;1034:91:10:-;1109:9;;-1:-1:-1;;;;;1109:9:10;1034:91;:::o;4246:84:15:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;386:94:12:-;1191:12:10;:10;:12::i;:::-;-1:-1:-1;;;;;1177:26:10;:10;:8;:10::i;:::-;-1:-1:-1;;;;;1177:26:10;;1169:77;;;;-1:-1:-1;;;1169:77:10;;;;;;;:::i;:::-;460:3:12::1;:13:::0;;-1:-1:-1;;;;;;460:13:12::1;-1:-1:-1::0;;;;;460:13:12;;;::::1;::::0;;;::::1;::::0;;386:94::o;151:29::-;;;-1:-1:-1;;;;;151:29:12;;:::o;1345:85:10:-;1417:6;;-1:-1:-1;;;;;1417:6:10;1345:85;:::o;190:31:15:-;;;;:::o;3517:63::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3903:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2283:251:10:-;1191:12;:10;:12::i;:::-;-1:-1:-1;;;;;1177:26:10;:10;:8;:10::i;:::-;-1:-1:-1;;;;;1177:26:10;;1169:77;;;;-1:-1:-1;;;1169:77:10;;;;;;;:::i;:::-;-1:-1:-1;;;;;2374:22:10;::::1;2366:73;;;;-1:-1:-1::0;;;2366:73:10::1;;;;;;;:::i;:::-;2479:6;::::0;2458:38:::1;::::0;-1:-1:-1;;;;;2458:38:10;;::::1;::::0;2479:6:::1;::::0;2458:38:::1;::::0;2479:6:::1;::::0;2458:38:::1;2510:6;:17:::0;;-1:-1:-1;;;;;;2510:17:10::1;-1:-1:-1::0;;;;;2510:17:10;;;::::1;::::0;;;::::1;::::0;;2283:251::o;2663:28:15:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2663:28:15;;;;;;;-1:-1:-1;;2663:28:15;;;:::o;3746:65::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;585:96:1:-;664:10;585:96;:::o;14:259:17:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:33;237:5;210:33;:::i;:::-;262:5;84:189;-1:-1:-1;;;84:189:17:o;550:402::-;;;679:2;667:9;658:7;654:23;650:32;647:2;;;700:6;692;685:22;647:2;744:9;731:23;763:33;790:5;763:33;:::i;:::-;815:5;-1:-1:-1;872:2:17;857:18;;844:32;885:35;844:32;885:35;:::i;:::-;939:7;929:17;;;637:315;;;;;:::o;957:470::-;;;;1103:2;1091:9;1082:7;1078:23;1074:32;1071:2;;;1124:6;1116;1109:22;1071:2;1168:9;1155:23;1187:33;1214:5;1187:33;:::i;:::-;1239:5;-1:-1:-1;1296:2:17;1281:18;;1268:32;1309:35;1268:32;1309:35;:::i;:::-;1061:366;;1363:7;;-1:-1:-1;;;1417:2:17;1402:18;;;;1389:32;;1061:366::o;1432:327::-;;;1561:2;1549:9;1540:7;1536:23;1532:32;1529:2;;;1582:6;1574;1567:22;1529:2;1626:9;1613:23;1645:33;1672:5;1645:33;:::i;:::-;1697:5;1749:2;1734:18;;;;1721:32;;-1:-1:-1;;;1519:240:17:o;1764:190::-;;1876:2;1864:9;1855:7;1851:23;1847:32;1844:2;;;1897:6;1889;1882:22;1844:2;-1:-1:-1;1925:23:17;;1834:120;-1:-1:-1;1834:120:17:o;1959:327::-;;;2088:2;2076:9;2067:7;2063:23;2059:32;2056:2;;;2109:6;2101;2094:22;2056:2;2150:9;2137:23;2127:33;;2210:2;2199:9;2195:18;2182:32;2223:33;2250:5;2223:33;:::i;2291:478::-;;2373:5;2367:12;2400:6;2395:3;2388:19;2425:3;2437:162;2451:6;2448:1;2445:13;2437:162;;;2513:4;2569:13;;;2565:22;;2559:29;2541:11;;;2537:20;;2530:59;2466:12;2437:162;;;2617:6;2614:1;2611:13;2608:2;;;2683:3;2676:4;2667:6;2662:3;2658:16;2654:27;2647:40;2608:2;-1:-1:-1;2751:2:17;2730:15;-1:-1:-1;;2726:29:17;2717:39;;;;2758:4;2713:50;;2343:426;-1:-1:-1;;2343:426:17:o;2774:203::-;-1:-1:-1;;;;;2938:32:17;;;;2920:51;;2908:2;2893:18;;2875:102::o;2982:187::-;3147:14;;3140:22;3122:41;;3110:2;3095:18;;3077:92::o;3174:402::-;3376:2;3358:21;;;3415:2;3395:18;;;3388:30;3454:34;3449:2;3434:18;;3427:62;-1:-1:-1;;;3520:2:17;3505:18;;3498:36;3566:3;3551:19;;3348:228::o;3581:409::-;3783:2;3765:21;;;3822:2;3802:18;;;3795:30;3861:34;3856:2;3841:18;;3834:62;-1:-1:-1;;;3927:2:17;3912:18;;3905:43;3980:3;3965:19;;3755:235::o;3995:402::-;4197:2;4179:21;;;4236:2;4216:18;;;4209:30;4275:34;4270:2;4255:18;;4248:62;-1:-1:-1;;;4341:2:17;4326:18;;4319:36;4387:3;4372:19;;4169:228::o;4402:402::-;4604:2;4586:21;;;4643:2;4623:18;;;4616:30;4682:34;4677:2;4662:18;;4655:62;-1:-1:-1;;;4748:2:17;4733:18;;4726:36;4794:3;4779:19;;4576:228::o;4809:177::-;4955:25;;;4943:2;4928:18;;4910:76::o;4991:479::-;5222:25;;;-1:-1:-1;;;;;5283:32:17;;5278:2;5263:18;;5256:60;5352:3;5347:2;5332:18;;5325:31;;;4991:479;;5373:48;;5401:19;;5393:6;5373:48;:::i;:::-;5365:56;;5457:6;5452:2;5441:9;5437:18;5430:34;5212:258;;;;;;;:::o;5475:374::-;;5674:6;5663:9;5656:25;5717:2;5712;5701:9;5697:18;5690:30;5737:47;5780:2;5769:9;5765:18;5757:6;5737:47;:::i;:::-;5729:55;;5834:6;5827:14;5820:22;5815:2;5804:9;5800:18;5793:50;5646:203;;;;;;:::o;5854:380::-;5939:1;5929:12;;5986:1;5976:12;;;5997:2;;6051:4;6043:6;6039:17;6029:27;;5997:2;6104;6096:6;6093:14;6073:18;6070:38;6067:2;;;6150:10;6145:3;6141:20;6138:1;6131:31;6185:4;6182:1;6175:15;6213:4;6210:1;6203:15;6067:2;;5909:325;;;:::o;6239:133::-;-1:-1:-1;;;;;6316:31:17;;6306:42;;6296:2;;6362:1;6359;6352:12;6296:2;6286:86;:::o

Swarm Source

ipfs://59f6f21ca3103d5ef91a0e3f443267d27d5bdb0d3277481f392138c9a5f29e70
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.