ETH Price: $3,488.96 (-0.06%)

Token

SoundMint Vinyl ()
 

Overview

Max Total Supply

1,297

Holders

862

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

0xce1a7a707721a7d16af0e99955e81aedbca4a252
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

SoundMint Vinyl. Your all-access pass to SoundMint. Rewarded to holders of SoundMint's Genesis collection 'WE ARE KLOUD'.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
VINYL

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 500 runs

Other Settings:
default evmVersion
File 1 of 11 : VINYL.sol
// SPDX-License-Identifier: MIT
/// @dev SOUNDMINT VINYL
///
/********************************************************************************
*                                                                               *
*                           ,%@@@&&&&&&&&&&&&&&&&@%*                            *
*                      /@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&@@(                       *
*                  .@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&%%#%#&@*                   *
*                @@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&%%%%%%###&@.                *
*             *@&&&@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&%#%%%#%%#####(@#              *
*            @&&&&&&@@@@@@@@@@@@@@@@@@@@@@&&&&&&&%%#%###%##%#####(@%            *
*          @%&&&&&&&@@@@@@@@@@@@@@@@@@@&&&&&&&&&%%%#######%##%######&           *
*         @&&&&&&&&&&@@@@@@@@@@@@@@@@@@&&&&&&&@%%%%#%###%###%##%#####@/         *
*        &@@@@@&&&&&&&@@@@@@@@@@@@@@@@@@@@@@@%%%######%###%#####%####(@#        *
*       @@@@@@@@@@@&&&@@@@@@@@@@@/.,,,,,,,,.(@@@%##(####%##########%%%&@,       *
*      @@@@@@@@@@@@@@@@@@@@@@@/,,,,,,,,,,,,,,,.(&@%##%######%%&&&@@@@@@@@       *
*      @@@@@@@@@@@@@@@@@@@@@@.,,,,,,,,,,,,,,,,,,.@@@%%@&@&@@@@@@@@@@@@@@@(      *
*     /@@@@@@@@@@@@@@@@@@@@@.,,,,,,,,,,,,,,,,,,,,.@@@@@@@@@@@@@@@@@@@@@@@@      *
*     (@@@@@@@@@@@@@@@@@@@@&,,,,,,,,,,* ,,,,,,,,,,&@@@@@@@@@@@@@@@@@@@@@@@      *
*     /@@@@@@@@@@@@@@@@@@@@@,,,,,,,,,,,,,,,,,,,,,.@@@@@@@@@@@@@@@@@@@@@@@@      *
*      @@@@@@@@@@@@&@&&&%&&@@,,,,,,,,,,,,,,,,,,,,&@@@@@@@@@@@@@@@@@@@@@@@#      *
*      &@@@@&@&&%%##%%%%%%%&@@*,,,,,,,,,,,,,,,,,@@@@@@@@@@@@@@@@@@@@@@@@@.      *
*       @%%%#%###%%%%%%%%%&%%@@@@*.,,,,,,,,,,@@@@&&&&&&@@@@@@@@@@@@@@@@@%       *
*        @####%%%%%%%%%%%&&&@&&&@@@@@@@@@@@@@@&&&&&&&&&&&&&@@@@@@@@@@@@&        *
*         @#%%#%%#%%%%&%&&@&&@&@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&@@@@@@@&         *
*          @&%#%%%%%%%%&&@&&&@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&@,          *
*            @###%%%&&&&&&&&@@@@@@@@@@@@@@@@@@@@@&&&&&&&@&&&&&&&&&@@            *
*              @#%%%%&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&@@              *
*                &@%%&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&@&                *
*                   @@&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@                   *
*                      *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,                      *
*                           ,%@@@@@@@@@@@@@@@@@@@@@%,                           *
*                                                                               *
*********************************************************************************/
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

import "./subContracts/ERC1155PackedBalance.sol";

contract VINYL is ERC1155PackedBalance, Ownable {
    using Address for address;
    using Strings for uint256;

    string private baseURI;
    bytes32 public merkleRoot = 0xdb9f7b75bd7be5081adf28065e8d2dd1322f281c829a80c122d483779b958616;

    mapping (uint256 => uint256) _redeemed;

    bool public isActive = false;
    
    enum VINYLTYPE {
        MINT,
        GOLD,
        ONYX
    }
    string public name = "SoundMint Vinyl";

    /*
     * Function to mint NFTs (internal)
    */
    function mint(address to, uint mint_type) internal 
    {
        if (mint_type == 1)
	{
		_mint(to, uint(VINYLTYPE.MINT), 1, "");
        } 
        else if (mint_type == 2)
        {
        	_mint(to, uint(VINYLTYPE.MINT), 2, "");
        } 
        else
	{
            uint256[] memory Collect = new uint256[](2);
            uint256[] memory Count = new uint256[](2);
            if (mint_type == 5)
            {
                Collect[0] = uint(VINYLTYPE.GOLD);
                Collect[1] = uint(VINYLTYPE.ONYX);
                Count[0] = 10;
                Count[1] = 10;
            }
            else
	    {
                Collect[0] = uint(VINYLTYPE.MINT);
                Collect[1] = uint(VINYLTYPE.GOLD);
                if (mint_type == 3)
                {
                    Count[0] = 2;
                    Count[1] = 1;
                }
                else if(mint_type == 4)
                {
                    Count[0] = 4;
                    Count[1] = 2;
                }
            }
            _batchMint(to, Collect, Count, "");
        }
    }
    
    
    /*
     * Function to burn NFTs (public)
    */

    function burn(uint _id, uint amount) external 
    {
        require(isActive, "Contract is not active");
       _burn(msg.sender, _id, amount);
    }
    /*
     * Function toggleActive to activate/desactivate the smart contract
    */

    function toggleActive() external onlyOwner 
    {
        isActive = !isActive;
    }

    /*
     * Function to set Base URI
    */
    function setURI(string memory _URI) external onlyOwner 
    {
        require(keccak256(abi.encodePacked(baseURI)) != keccak256(abi.encodePacked(_URI)), "baseURI is already the value being set.");
        baseURI = _URI;
    }

    /*
     * Function to set the merkle root
    */

    function setMerkleRoot(bytes32 merkleRootHash) external onlyOwner 
    {
	    require(merkleRoot != merkleRootHash,"merkelRoot already being set.");
        merkleRoot = merkleRootHash;
    }

    function hasNotMinted(uint256 index) external view returns (bool)
    {
      uint256 redeemedBlock = _redeemed[index / 256];
      uint256 redeemedMask = (uint256(1) << uint256(index % 256));
      return ((redeemedBlock & redeemedMask) == 0);
    }

    /*
     * Function to mint new NFTs during presale/raffle
     */
  
    function mintNFT(uint256 index, uint256 mint_type, bytes32[] memory _proof) external
    {
        require(isActive, "Contract is not active");
      
      	// Check Allowlist
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender, mint_type, index));
        require(verify(merkleRoot, _proof, leaf), "Not Allowlisted");
      
        // To prevent several mint
	uint256 redeemedBlock = _redeemed[index / 256]; 
        uint256 redeemedMask = (uint256(1) << uint256(index % 256)); 
        require((redeemedBlock & redeemedMask) == 0, "Drop already claimed");
        _redeemed[index / 256] = redeemedBlock | redeemedMask;
	
        mint(msg.sender, mint_type);
        
    }

    /*
     * Function to get token URI of given token ID
     * URI will be blank untill totalSupply reaches MAX_NFT_PUBLIC
    */

    function uri(uint256 _tokenId) external view returns (string memory) {
        return string(abi.encodePacked(baseURI, _tokenId.toString(), ".json"));
    }

    /*
     * Function to verify the Merkle Tree Proof
    */
    function verify(
        bytes32 root,
        bytes32[] memory proof,
        bytes32 leaf
    ) public pure returns (bool) 
    {
        bytes32 hash = leaf;

        for (uint i = 0; i < proof.length; i++) 
	    {
            bytes32 proofElement = proof[i];

            if (hash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                hash = keccak256(abi.encodePacked(hash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                hash = keccak256(abi.encodePacked(proofElement, hash));
            }            
        }

        return hash == root;
    }
}

File 2 of 11 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 11 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 4 of 11 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 5 of 11 : ERC1155PackedBalance.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

import "../interfaces/IERC1155TokenReceiver.sol";
import "./ERC165.sol";

contract ERC1155PackedBalance is IERC1155, ERC165 {
  using SafeMath for uint256;
  using Address for address;

  /***********************************|
  |        Variables and Events       |
  |__________________________________*/

  // onReceive function signatures
  bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
  bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;

  // Constants regarding bin sizes for balance packing
  // IDS_BITS_SIZE **MUST** be a power of 2 (e.g. 2, 4, 8, 16, 32, 64, 128)
  uint256 internal constant IDS_BITS_SIZE   = 32;                  // Max balance amount in bits per token ID
  uint256 internal constant IDS_PER_UINT256 = 256 / IDS_BITS_SIZE; // Number of ids per uint256

  // Operations for _updateIDBalance
  enum Operations { Add, Sub }

  // Token IDs balances ; balances[address][id] => balance (using array instead of mapping for efficiency)
  mapping (address => mapping(uint256 => uint256)) internal balances;

  // Operators
  mapping (address => mapping(address => bool)) internal operators;


  /***********************************|
  |     Public Transfer Functions     |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   * @param _data    Additional data with no specified format, sent in call to `_to`
   */
  function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeTransferFrom: INVALID_RECIPIENT");
    // require(_amount <= balances);  Not necessary since checked with _viewUpdateBinValue() checks

    _safeTransferFrom(_from, _to, _id, _amount);
    _callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   * @param _data     Additional data with no specified format, sent in call to `_to`
   */
  function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    public override
  {
    // Requirements
    require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeBatchTransferFrom: INVALID_OPERATOR");
    require(_to != address(0),"ERC1155PackedBalance#safeBatchTransferFrom: INVALID_RECIPIENT");

    _safeBatchTransferFrom(_from, _to, _ids, _amounts);
    _callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
  }


  /***********************************|
  |    Internal Transfer Functions    |
  |__________________________________*/

  /**
   * @notice Transfers amount amount of an _id from the _from address to the _to address specified
   * @param _from    Source address
   * @param _to      Target address
   * @param _id      ID of the token type
   * @param _amount  Transfered amount
   */
  function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
    internal
  {
    //Update balances
    _updateIDBalance(_from, _id, _amount, Operations.Sub); // Subtract amount from sender
    _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

    // Emit event
    emit TransferSingle(msg.sender, _from, _to, _id, _amount);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
   */
  function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Check if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas:_gasLimit}(msg.sender, _from, _id, _amount, _data);
      require(retval == ERC1155_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
    }
  }

  /**
   * @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
   * @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
   * @param _from     Source addresses
   * @param _to       Target addresses
   * @param _ids      IDs of each token type
   * @param _amounts  Transfer amounts per token type
   */
  function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
    internal
  {
    uint256 nTransfer = _ids.length; // Number of transfer to execute
    require(nTransfer == _amounts.length, "ERC1155PackedBalance#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");

    if (_from != _to && nTransfer > 0) {
      // Load first bin and index where the token ID balance exists
      (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

      // Balance for current bin in memory (initialized with first transfer)
      uint256 balFrom = _viewUpdateBinValue(balances[_from][bin], index, _amounts[0], Operations.Sub);
      uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

      // Last bin updated
      uint256 lastBin = bin;

      for (uint256 i = 1; i < nTransfer; i++) {
        (bin, index) = getIDBinIndex(_ids[i]);

        // If new bin
        if (bin != lastBin) {
          // Update storage balance of previous bin
          balances[_from][lastBin] = balFrom;
          balances[_to][lastBin] = balTo;

          balFrom = balances[_from][bin];
          balTo = balances[_to][bin];

          // Bin will be the most recent bin
          lastBin = bin;
        }

        // Update memory balance
        balFrom = _viewUpdateBinValue(balFrom, index, _amounts[i], Operations.Sub);
        balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
      }

      // Update storage of the last bin visited
      balances[_from][bin] = balFrom;
      balances[_to][bin] = balTo;

    // If transfer to self, just make sure all amounts are valid
    } else {
      for (uint256 i = 0; i < nTransfer; i++) {
        require(balanceOf(_from, _ids[i]) >= _amounts[i], "ERC1155PackedBalance#_safeBatchTransferFrom: UNDERFLOW");
      }
    }

    // Emit event
    emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
  }

  /**
   * @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
   */
  function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
    internal
  {
    // Pass data if recipient is contract
    if (_to.isContract()) {
      bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
      require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
    }
  }


  /***********************************|
  |         Operator Functions        |
  |__________________________________*/

  /**
   * @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
   * @param _operator  Address to add to the set of authorized operators
   * @param _approved  True if the operator is approved, false to revoke approval
   */
  function setApprovalForAll(address _operator, bool _approved)
    external override
  {
    // Update operator status
    operators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @notice Queries the approval status of an operator for a given owner
   * @param _owner     The owner of the Tokens
   * @param _operator  Address of authorized operator
   * @return isOperator True if the operator is approved, false if not
   */
  function isApprovedForAll(address _owner, address _operator)
    public override view returns (bool isOperator)
  {
    return operators[_owner][_operator];
  }


  /***********************************|
  |     Public Balance Functions      |
  |__________________________________*/

  /**
   * @notice Get the balance of an account's Tokens
   * @param _owner  The address of the token holder
   * @param _id     ID of the Token
   * @return The _owner's balance of the Token type requested
   */
  function balanceOf(address _owner, uint256 _id)
    public override view returns (uint256)
  {
    uint256 bin;
    uint256 index;

    //Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);
    return getValueInBin(balances[_owner][bin], index);
  }

  /**
   * @notice Get the balance of multiple account/token pairs
   * @param _owners The addresses of the token holders (sorted owners will lead to less gas usage)
   * @param _ids    ID of the Tokens (sorted ids will lead to less gas usage
   * @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
    */
  function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
    public override view returns (uint256[] memory)
  {
    uint256 n_owners = _owners.length;
    require(n_owners == _ids.length, "ERC1155PackedBalance#balanceOfBatch: INVALID_ARRAY_LENGTH");

    // First values
    (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
    uint256 balance_bin = balances[_owners[0]][bin];
    uint256 last_bin = bin;

    // Initialization
    uint256[] memory batchBalances = new uint256[](n_owners);
    batchBalances[0] = getValueInBin(balance_bin, index);

    // Iterate over each owner and token ID
    for (uint256 i = 1; i < n_owners; i++) {
      (bin, index) = getIDBinIndex(_ids[i]);

      // SLOAD if bin changed for the same owner or if owner changed
      if (bin != last_bin || _owners[i-1] != _owners[i]) {
        balance_bin = balances[_owners[i]][bin];
        last_bin = bin;
      }

      batchBalances[i] = getValueInBin(balance_bin, index);
    }

    return batchBalances;
  }


  /***********************************|
  |      Packed Balance Functions     |
  |__________________________________*/

  /**
   * @notice Update the balance of a id for a given address
   * @param _address    Address to update id balance
   * @param _id         Id to update balance of
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to id balance
   *   Operations.Sub: Substract _amount from id balance
   */
  function _updateIDBalance(address _address, uint256 _id, uint256 _amount, Operations _operation)
    internal
  {
    uint256 bin;
    uint256 index;

    // Get bin and index of _id
    (bin, index) = getIDBinIndex(_id);

    // Update balance
    balances[_address][bin] = _viewUpdateBinValue(balances[_address][bin], index, _amount, _operation);
  }

  /**
   * @notice Update a value in _binValues
   * @param _binValues  Uint256 containing values of size IDS_BITS_SIZE (the token balances)
   * @param _index      Index of the value in the provided bin
   * @param _amount     Amount to update the id balance
   * @param _operation  Which operation to conduct :
   *   Operations.Add: Add _amount to value in _binValues at _index
   *   Operations.Sub: Substract _amount from value in _binValues at _index
   */
  function _viewUpdateBinValue(uint256 _binValues, uint256 _index, uint256 _amount, Operations _operation)
    internal pure returns (uint256 newBinValues)
  {
    uint256 shift = IDS_BITS_SIZE * _index;
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    if (_operation == Operations.Add) {
      newBinValues = _binValues + (_amount << shift);
      require(newBinValues >= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW");
      require(
        ((_binValues >> shift) & mask) + _amount < 2**IDS_BITS_SIZE, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW"
      );

    } else if (_operation == Operations.Sub) {
      newBinValues = _binValues - (_amount << shift);
      require(newBinValues <= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW");
      require(
        ((_binValues >> shift) & mask) >= _amount, // Checks that no other id changed
        "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW"
      );

    } else {
      revert("ERC1155PackedBalance#_viewUpdateBinValue: INVALID_BIN_WRITE_OPERATION"); // Bad operation
    }

    return newBinValues;
  }

  /**
  * @notice Return the bin number and index within that bin where ID is
  * @param _id  Token id
  * @return bin index (Bin number, ID"s index within that bin)
  */
  function getIDBinIndex(uint256 _id)
    public pure returns (uint256 bin, uint256 index)
  {
    bin = _id / IDS_PER_UINT256;
    index = _id % IDS_PER_UINT256;
    return (bin, index);
  }

  /**
   * @notice Return amount in _binValues at position _index
   * @param _binValues  uint256 containing the balances of IDS_PER_UINT256 ids
   * @param _index      Index at which to retrieve amount
   * @return amount at given _index in _bin
   */
  function getValueInBin(uint256 _binValues, uint256 _index)
    public pure returns (uint256)
  {
    // require(_index < IDS_PER_UINT256) is not required since getIDBinIndex ensures `_index < IDS_PER_UINT256`

    // Mask to retrieve data for a given binData
    uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;

    // Shift amount
    uint256 rightShift = IDS_BITS_SIZE * _index;
    return (_binValues >> rightShift) & mask;
  }

    function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
    internal
    {
        //Add _amount
        _updateIDBalance(_to,   _id, _amount, Operations.Add); // Add amount to recipient

        // Emit event
        emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);

        // Calling onReceive method if recipient is contract
        _callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
    }

    /**
   * @notice Mint tokens for each (_ids[i], _amounts[i]) pair
   * @param _to       The address to mint tokens to
   * @param _ids      Array of ids to mint
   * @param _amounts  Array of amount of tokens to mint per id
   * @param _data    Data to pass if receiver is contract
   */
    function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
    internal
    {
        require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#_batchMint: INVALID_ARRAYS_LENGTH");

        if (_ids.length > 0) {
        // Load first bin and index where the token ID balance exists
        (uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);

        // Balance for current bin in memory (initialized with first transfer)
        uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);

        // Number of transfer to execute
        uint256 nTransfer = _ids.length;

        // Last bin updated
        uint256 lastBin = bin;

        for (uint256 i = 1; i < nTransfer; i++) {
            (bin, index) = getIDBinIndex(_ids[i]);

            // If new bin
            if (bin != lastBin) {
            // Update storage balance of previous bin
            balances[_to][lastBin] = balTo;
            balTo = balances[_to][bin];

            // Bin will be the most recent bin
            lastBin = bin;
            }

            // Update memory balance
            balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
        }

        // Update storage of the last bin visited
        balances[_to][bin] = balTo;
        }

        // //Emit event
        emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);

        // Calling onReceive method if recipient is contract
        _callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
    }
    /****************************************|
    |            Burning Functions           |
    |_______________________________________*/

    /**
    * @notice Burn _amount of tokens of a given token id
    * @param _from    The address to burn tokens from
    * @param _id      Token id to burn
    * @param _amount  The amount to be burned
    */
    function _burn(address _from, uint256 _id, uint256 _amount)
      internal
    {
      // Substract _amount
      _updateIDBalance(_from, _id, _amount, Operations.Sub);

      // Emit event
      emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
    }

    /**
    * @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
    * @dev This batchBurn method does not implement the most efficient way of updating
    *      balances to reduce the potential bug surface as this function is expected to
    *      be less common than transfers. EIP-2200 makes this method significantly
    *      more efficient already for packed balances.
    * @param _from     The address to burn tokens from
    * @param _ids      Array of token ids to burn
    * @param _amounts  Array of the amount to be burned
    */
    function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
      internal
    {
      // Number of burning to execute
      uint256 nBurn = _ids.length;
      require(nBurn == _amounts.length, "ERC1155MintBurnPackedBalance#batchBurn: INVALID_ARRAYS_LENGTH");

      // Executing all burning
      for (uint256 i = 0; i < nBurn; i++) {
        // Update storage balance
        _updateIDBalance(_from,   _ids[i], _amounts[i], Operations.Sub); // Add amount to recipient
      }

      // Emit batch burn event
      emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
    }
    /***********************************|
    |          ERC165 Functions         |
    |__________________________________*/

    /**
    * @notice Query if a contract implements an interface
    * @param _interfaceID  The interface identifier, as specified in ERC-165
    * @return `true` if the contract implements `_interfaceID` and
    */
    function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
      if (_interfaceID == type(IERC1155).interfaceId) {
        return true;
      }
      return super.supportsInterface(_interfaceID);
    }
}

File 6 of 11 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 7 of 11 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

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 generally not needed starting with Solidity 0.8, since 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) {
        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) {
        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) {
        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 8 of 11 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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 9 of 11 : IERC1155TokenReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
/**
 * @dev Implementation of Multi-Token Standard contract. This implementation of the ERC-1155 standard
 *      utilizes the fact that balances of different token ids can be concatenated within individual
 *      uint256 storage slots. This allows the contract to batch transfer tokens more efficiently at
 *      the cost of limiting the maximum token balance each address can hold. This limit is
 *      2^IDS_BITS_SIZE, which can be adjusted below. In practice, using IDS_BITS_SIZE smaller than 16
 *      did not lead to major efficiency gains.
 */
 interface IERC1155TokenReceiver {

  /**
   * @notice Handle the receipt of a single ERC1155 token type
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value MUST result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _id        The id of the token being transferred
   * @param _amount    The amount of tokens being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
   */
  function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);

  /**
   * @notice Handle the receipt of multiple ERC1155 token types
   * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
   * This function MAY throw to revert and reject the transfer
   * Return of other amount than the magic value WILL result in the transaction being reverted
   * Note: The token contract address is always the message sender
   * @param _operator  The address which called the `safeBatchTransferFrom` function
   * @param _from      The address which previously owned the token
   * @param _ids       An array containing ids of each token being transferred
   * @param _amounts   An array containing amounts of each token being transferred
   * @param _data      Additional data with no specified format
   * @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
   */
  function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
}

File 10 of 11 : ERC165.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

abstract contract ERC165 is IERC165 {
  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceID The interface identifier, as specified in ERC-165
   * @return `true` if the contract implements `_interfaceID`
   */
  function supportsInterface(bytes4 _interfaceID) virtual override public pure returns (bool) {
    return _interfaceID == this.supportsInterface.selector;
  }
}

File 11 of 11 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/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;
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getIDBinIndex","outputs":[{"internalType":"uint256","name":"bin","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_binValues","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getValueInBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"hasNotMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"mint_type","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"mintNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRootHash","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_URI","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"toggleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"leaf","type":"bytes32"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]

7fdb9f7b75bd7be5081adf28065e8d2dd1322f281c829a80c122d483779b9586166004556006805460ff1916905560c0604052600f60808190526e14dbdd5b99135a5b9d08159a5b9e5b608a1b60a0908152620000609160079190620000d2565b503480156200006e57600080fd5b506200007a3362000080565b620001b5565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620000e09062000178565b90600052602060002090601f0160209004810192826200010457600085556200014f565b82601f106200011f57805160ff19168380011785556200014f565b828001600101855582156200014f579182015b828111156200014f57825182559160200191906001019062000132565b506200015d92915062000161565b5090565b5b808211156200015d576000815560010162000162565b600181811c908216806200018d57607f821691505b60208210811415620001af57634e487b7160e01b600052602260045260246000fd5b50919050565b612bff80620001c56000396000f3fe608060405234801561001057600080fd5b506004361061017c5760003560e01c806365aad4fd116100e3578063db90e83c1161008c578063eaec5f8111610066578063eaec5f8114610351578063f242432a14610364578063f2fde38b1461037757600080fd5b8063db90e83c146102da578063ddc5ba1b14610302578063e985e9c51461031557600080fd5b80638da5cb5b116100bd5780638da5cb5b14610299578063a22cb465146102b4578063b390c0ab146102c757600080fd5b806365aad4fd1461026b578063715018a61461027e5780637cb647591461028657600080fd5b80630e89341c116101455780632eb2c2d61161011f5780632eb2c2d61461022f5780632eb4a7ab146102425780634e1273f41461024b57600080fd5b80630e89341c1461020757806322f3e2d41461021a57806329c68dc11461022757600080fd5b8062fdd58e1461018157806301ffc9a7146101a757806302fe5305146101ca57806306fdde03146101df5780630a02831c146101f4575b600080fd5b61019461018f36600461246b565b61038a565b6040519081526020015b60405180910390f35b6101ba6101b53660046125c5565b6103d4565b604051901515815260200161019e565b6101dd6101d83660046125ff565b610410565b005b6101e7610533565b60405161019e91906128fa565b6101ba610202366004612575565b6105c1565b6101e761021536600461255c565b610670565b6006546101ba9060ff1681565b6101dd6106a4565b6101dd61023d366004612320565b610712565b61019460045481565b61025e610259366004612495565b61085b565b60405161019e91906128b9565b6101dd61027936600461266a565b610aed565b6101dd610c9d565b6101dd61029436600461255c565b610d03565b6002546040516001600160a01b03909116815260200161019e565b6101dd6102c236600461242f565b610db4565b6101dd6102d5366004612648565b610e20565b6102ed6102e836600461255c565b610e7d565b6040805192835260208301919091520161019e565b6101ba61031036600461255c565b610eb7565b6101ba6103233660046122ed565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61019461035f366004612648565b610efa565b6101dd6103723660046123ca565b610f28565b6101dd6103853660046122d2565b61106a565b600080600061039884610e7d565b6001600160a01b03871660009081526020818152604080832085845290915290205491935091506103c99082610efa565b925050505b92915050565b60006001600160e01b03198216636cdb3d1360e11b14156103f757506001919050565b6301ffc9a760e01b6001600160e01b03198316146103ce565b6002546001600160a01b0316331461046f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b8060405160200161048091906127bb565b6040516020818303038152906040528051906020012060036040516020016104a891906127d7565b60405160208183030381529060405280519060200120141561051c5760405162461bcd60e51b815260206004820152602760248201527f6261736555524920697320616c7265616479207468652076616c75652062656960448201526637339039b2ba1760c91b6064820152608401610466565b805161052f90600390602084019061212c565b5050565b6007805461054090612adb565b80601f016020809104026020016040519081016040528092919081815260200182805461056c90612adb565b80156105b95780601f1061058e576101008083540402835291602001916105b9565b820191906000526020600020905b81548152906001019060200180831161059c57829003601f168201915b505050505081565b600081815b84518110156106655760008582815181106105e3576105e3612b87565b60200260200101519050808311610625576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250610652565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061065d81612b16565b9150506105c6565b509093149392505050565b6060600361067d83611135565b60405160200161068e9291906127e3565b6040516020818303038152906040529050919050565b6002546001600160a01b031633146106fe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b6006805460ff19811660ff90911615179055565b336001600160a01b038616148061074c57506001600160a01b038516600090815260016020908152604080832033845290915290205460ff165b6107be5760405162461bcd60e51b815260206004820152603c60248201527f455243313135355061636b656442616c616e636523736166654261746368547260448201527f616e7366657246726f6d3a20494e56414c49445f4f50455241544f52000000006064820152608401610466565b6001600160a01b03841661083a5760405162461bcd60e51b815260206004820152603d60248201527f455243313135355061636b656442616c616e636523736166654261746368547260448201527f616e7366657246726f6d3a20494e56414c49445f524543495049454e540000006064820152608401610466565b61084685858585611253565b610854858585855a866115f2565b5050505050565b815181516060919081146108d75760405162461bcd60e51b815260206004820152603960248201527f455243313135355061636b656442616c616e63652362616c616e63654f66426160448201527f7463683a20494e56414c49445f41525241595f4c454e475448000000000000006064820152608401610466565b6000806108fd856000815181106108f0576108f0612b87565b6020026020010151610e7d565b9150915060008060008860008151811061091957610919612b87565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000848152602001908152602001600020549050600083905060008567ffffffffffffffff81111561097557610975612b9d565b60405190808252806020026020018201604052801561099e578160200160208202803683370190505b5090506109ab8385610efa565b816000815181106109be576109be612b87565b602090810291909101015260015b86811015610ae0576109e98982815181106108f0576108f0612b87565b90965094508286141580610a4d5750898181518110610a0a57610a0a612b87565b60200260200101516001600160a01b03168a600183610a299190612a98565b81518110610a3957610a39612b87565b60200260200101516001600160a01b031614155b15610aa7576000808b8381518110610a6757610a67612b87565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008781526020019081526020016000205493508592505b610ab18486610efa565b828281518110610ac357610ac3612b87565b602090810291909101015280610ad881612b16565b9150506109cc565b5098975050505050505050565b60065460ff16610b3f5760405162461bcd60e51b815260206004820152601660248201527f436f6e7472616374206973206e6f7420616374697665000000000000000000006044820152606401610466565b6040516bffffffffffffffffffffffff193360601b1660208201526034810183905260548101849052600090607401604051602081830303815290604052805190602001209050610b9360045483836105c1565b610bdf5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420416c6c6f776c697374656400000000000000000000000000000000006044820152606401610466565b6000600581610bf06101008861297a565b8152602001908152602001600020549050600061010086610c119190612b31565b6001901b905081811615610c675760405162461bcd60e51b815260206004820152601460248201527f44726f7020616c726561647920636c61696d65640000000000000000000000006044820152606401610466565b81811760056000610c7a6101008a61297a565b8152602081019190915260400160002055610c953386611732565b505050505050565b6002546001600160a01b03163314610cf75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b610d016000611941565b565b6002546001600160a01b03163314610d5d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b806004541415610daf5760405162461bcd60e51b815260206004820152601d60248201527f6d65726b656c526f6f7420616c7265616479206265696e67207365742e0000006044820152606401610466565b600455565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60065460ff16610e725760405162461bcd60e51b815260206004820152601660248201527f436f6e7472616374206973206e6f7420616374697665000000000000000000006044820152606401610466565b61052f3383836119a0565b600080610e8d602061010061297a565b610e97908461297a565b9150610ea6602061010061297a565b610eb09084612b31565b9050915091565b600080600581610ec96101008661297a565b8152602001908152602001600020549050600061010084610eea9190612b31565b6001901b91909116159392505050565b600080610f0d6001640100000000612a98565b90506000610f1c846020612a79565b9490941c169392505050565b336001600160a01b0386161480610f6257506001600160a01b038516600090815260016020908152604080832033845290915290205460ff165b610fd45760405162461bcd60e51b815260206004820152603760248201527f455243313135355061636b656442616c616e636523736166655472616e73666560448201527f7246726f6d3a20494e56414c49445f4f50455241544f520000000000000000006064820152608401610466565b6001600160a01b0384166110505760405162461bcd60e51b815260206004820152603860248201527f455243313135355061636b656442616c616e636523736166655472616e73666560448201527f7246726f6d3a20494e56414c49445f524543495049454e5400000000000000006064820152608401610466565b61105c858585856119fb565b610854858585855a86611a66565b6002546001600160a01b031633146110c45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b6001600160a01b0381166111295760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610466565b61113281611941565b50565b6060816111595750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611183578061116d81612b16565b915061117c9050600a8361297a565b915061115d565b60008167ffffffffffffffff81111561119e5761119e612b9d565b6040519080825280601f01601f1916602001820160405280156111c8576020820181803683370190505b5090505b841561124b576111dd600183612a98565b91506111ea600a86612b31565b6111f5906030612962565b60f81b81838151811061120a5761120a612b87565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611244600a8661297a565b94506111cc565b949350505050565b8151815181146112d65760405162461bcd60e51b815260206004820152604260248201527f455243313135355061636b656442616c616e6365235f7361666542617463685460448201527f72616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e476064820152610a8960f31b608482015260a401610466565b836001600160a01b0316856001600160a01b0316141580156112f85750600081115b156114c457600080611316856000815181106108f0576108f0612b87565b6001600160a01b038916600090815260208181526040808320858452909152812054875193955091935091611367919084908890859061135857611358612b87565b60200260200101516001611b98565b6001600160a01b038816600090815260208181526040808320878452909152812054875192935090916113b691908590899085906113a7576113a7612b87565b60200260200101516000611b98565b90508360015b8681101561147f576113d98982815181106108f0576108f0612b87565b909650945081861461143b576001600160a01b038b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61145284868a848151811061135857611358612b87565b935061146b83868a84815181106113a7576113a7612b87565b92508061147781612b16565b9150506113bc565b50506001600160a01b03808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550611594565b60005b81811015611592578281815181106114e1576114e1612b87565b602002602001015161150c878684815181106114ff576114ff612b87565b602002602001015161038a565b10156115805760405162461bcd60e51b815260206004820152603660248201527f455243313135355061636b656442616c616e6365235f7361666542617463685460448201527f72616e7366657246726f6d3a20554e444552464c4f57000000000000000000006064820152608401610466565b8061158a81612b16565b9150506114c7565b505b836001600160a01b0316856001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516115e39291906128cc565b60405180910390a45050505050565b6001600160a01b0385163b15610c95576000856001600160a01b031663bc197c8184338a8989886040518763ffffffff1660e01b8152600401611639959493929190612818565b602060405180830381600088803b15801561165357600080fd5b5087f1158015611667573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061168c91906125e2565b90506001600160e01b0319811663bc197c8160e01b146117295760405162461bcd60e51b815260206004820152604c60248201527f455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433160448201527f313535426174636852656365697665643a20494e56414c49445f4f4e5f52454360648201526b454956455f4d45535341474560a01b608482015260a401610466565b50505050505050565b80600114156117585761052f826000600160405180602001604052806000815250611e61565b806002141561177e5761052f826000600260405180602001604052806000815250611e61565b6040805160028082526060820183526000926020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090508260051415611854576001826000815181106117e1576117e1612b87565b602090810291909101015260028260018151811061180157611801612b87565b602002602001018181525050600a8160008151811061182257611822612b87565b602002602001018181525050600a8160018151811061184357611843612b87565b602002602001018181525050611920565b60008260008151811061186957611869612b87565b602090810291909101015260018260018151811061188957611889612b87565b60200260200101818152505082600314156118d4576002816000815181106118b3576118b3612b87565b60200260200101818152505060018160018151811061184357611843612b87565b8260041415611920576004816000815181106118f2576118f2612b87565b60200260200101818152505060028160018151811061191357611913612b87565b6020026020010181815250505b61193b84838360405180602001604052806000815250611ec6565b50505050565b600280546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6119ad83838360016120bf565b60408051838152602081018390526000916001600160a01b0386169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050565b611a0884838360016120bf565b611a1583838360006120bf565b60408051838152602081018390526001600160a01b03808616929087169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050565b6001600160a01b0385163b15610c95576000856001600160a01b031663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401611aad959493929190612876565b602060405180830381600088803b158015611ac757600080fd5b5087f1158015611adb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611b0091906125e2565b90506001600160e01b0319811663f23a6e6160e01b146117295760405162461bcd60e51b815260206004820152604760248201527f455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433160448201527f31353552656365697665643a20494e56414c49445f4f4e5f524543454956455f6064820152664d45535341474560c81b608482015260a401610466565b600080611ba6856020612a79565b90506000611bba6001640100000000612a98565b90506000846001811115611bd057611bd0612b71565b1415611cd657611be285831b88612962565b925086831015611c4f5760405162461bcd60e51b815260206004820152603260248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527142696e56616c75653a204f564552464c4f5760701b6064820152608401610466565b611c5b602060026129d1565b611c698689851c8416612962565b10611cd15760405162461bcd60e51b815260206004820152603260248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527142696e56616c75653a204f564552464c4f5760701b6064820152608401610466565b611e57565b6001846001811115611cea57611cea612b71565b1415611ddb57611cfc85831b88612a98565b925086831115611d6a5760405162461bcd60e51b815260206004820152603360248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527242696e56616c75653a20554e444552464c4f5760681b6064820152608401610466565b84818389901c161015611cd15760405162461bcd60e51b815260206004820152603360248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527242696e56616c75653a20554e444552464c4f5760681b6064820152608401610466565b60405162461bcd60e51b815260206004820152604560248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527f42696e56616c75653a20494e56414c49445f42494e5f57524954455f4f50455260648201526420aa24a7a760d91b608482015260a401610466565b5050949350505050565b611e6e84848460006120bf565b60408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461193b60008585855a86611a66565b8151835114611f3d5760405162461bcd60e51b815260206004820152603e60248201527f455243313135354d696e744275726e5061636b656442616c616e6365235f626160448201527f7463684d696e743a20494e56414c49445f4152524159535f4c454e47544800006064820152608401610466565b82511561205857600080611f5d856000815181106108f0576108f0612b87565b6001600160a01b038816600090815260208181526040808320858452909152812054875193955091935091611f9f91908490889085906113a7576113a7612b87565b86519091508360015b8281101561202c57611fc58982815181106108f0576108f0612b87565b9096509450818614612001576001600160a01b038a16600090815260208181526040808320948352939052828120949094558584529220549184905b61201884868a84815181106113a7576113a7612b87565b93508061202481612b16565b915050611fa8565b5050506001600160a01b0387166000908152602081815260408083209583529490529290922091909155505b836001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516120a89291906128cc565b60405180910390a461193b60008585855a866115f2565b6000806120cb85610e7d565b6001600160a01b03881660009081526020818152604080832085845290915290205491935091506120fe90828686611b98565b6001600160a01b03909616600090815260208181526040808320948352939052919091209490945550505050565b82805461213890612adb565b90600052602060002090601f01602090048101928261215a57600085556121a0565b82601f1061217357805160ff19168380011785556121a0565b828001600101855582156121a0579182015b828111156121a0578251825591602001919060010190612185565b506121ac9291506121b0565b5090565b5b808211156121ac57600081556001016121b1565b600067ffffffffffffffff8311156121df576121df612b9d565b6121f2601f8401601f191660200161290d565b905082815283838301111561220657600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461223457600080fd5b919050565b600082601f83011261224a57600080fd5b8135602061225f61225a8361293e565b61290d565b80838252828201915082860187848660051b890101111561227f57600080fd5b60005b8581101561229e57813584529284019290840190600101612282565b5090979650505050505050565b600082601f8301126122bc57600080fd5b6122cb838335602085016121c5565b9392505050565b6000602082840312156122e457600080fd5b6122cb8261221d565b6000806040838503121561230057600080fd5b6123098361221d565b91506123176020840161221d565b90509250929050565b600080600080600060a0868803121561233857600080fd5b6123418661221d565b945061234f6020870161221d565b9350604086013567ffffffffffffffff8082111561236c57600080fd5b61237889838a01612239565b9450606088013591508082111561238e57600080fd5b61239a89838a01612239565b935060808801359150808211156123b057600080fd5b506123bd888289016122ab565b9150509295509295909350565b600080600080600060a086880312156123e257600080fd5b6123eb8661221d565b94506123f96020870161221d565b93506040860135925060608601359150608086013567ffffffffffffffff81111561242357600080fd5b6123bd888289016122ab565b6000806040838503121561244257600080fd5b61244b8361221d565b91506020830135801515811461246057600080fd5b809150509250929050565b6000806040838503121561247e57600080fd5b6124878361221d565b946020939093013593505050565b600080604083850312156124a857600080fd5b823567ffffffffffffffff808211156124c057600080fd5b818501915085601f8301126124d457600080fd5b813560206124e461225a8361293e565b8083825282820191508286018a848660051b890101111561250457600080fd5b600096505b8487101561252e5761251a8161221d565b835260019690960195918301918301612509565b509650508601359250508082111561254557600080fd5b5061255285828601612239565b9150509250929050565b60006020828403121561256e57600080fd5b5035919050565b60008060006060848603121561258a57600080fd5b83359250602084013567ffffffffffffffff8111156125a857600080fd5b6125b486828701612239565b925050604084013590509250925092565b6000602082840312156125d757600080fd5b81356122cb81612bb3565b6000602082840312156125f457600080fd5b81516122cb81612bb3565b60006020828403121561261157600080fd5b813567ffffffffffffffff81111561262857600080fd5b8201601f8101841361263957600080fd5b61124b848235602084016121c5565b6000806040838503121561265b57600080fd5b50508035926020909101359150565b60008060006060848603121561267f57600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156126a457600080fd5b6126b086828701612239565b9150509250925092565b600081518084526020808501945080840160005b838110156126ea578151875295820195908201906001016126ce565b509495945050505050565b6000815180845261270d816020860160208601612aaf565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061273b57607f831692505b602080841082141561275d57634e487b7160e01b600052602260045260246000fd5b8180156127715760018114612782576127af565b60ff198616895284890196506127af565b60008881526020902060005b868110156127a75781548b82015290850190830161278e565b505084890196505b50505050505092915050565b600082516127cd818460208701612aaf565b9190910192915050565b60006122cb8284612721565b60006127ef8285612721565b83516127ff818360208801612aaf565b64173539b7b760d91b9101908152600501949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261284460a08301866126ba565b828103606084015261285681866126ba565b9050828103608084015261286a81856126f5565b98975050505050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526128ae60a08301846126f5565b979650505050505050565b6020815260006122cb60208301846126ba565b6040815260006128df60408301856126ba565b82810360208401526128f181856126ba565b95945050505050565b6020815260006122cb60208301846126f5565b604051601f8201601f1916810167ffffffffffffffff8111828210171561293657612936612b9d565b604052919050565b600067ffffffffffffffff82111561295857612958612b9d565b5060051b60200190565b6000821982111561297557612975612b45565b500190565b60008261298957612989612b5b565b500490565b600181815b808511156129c95781600019048211156129af576129af612b45565b808516156129bc57918102915b93841c9390800290612993565b509250929050565b60006122cb83836000826129e7575060016103ce565b816129f4575060006103ce565b8160018114612a0a5760028114612a1457612a30565b60019150506103ce565b60ff841115612a2557612a25612b45565b50506001821b6103ce565b5060208310610133831016604e8410600b8410161715612a53575081810a6103ce565b612a5d838361298e565b8060001904821115612a7157612a71612b45565b029392505050565b6000816000190483118215151615612a9357612a93612b45565b500290565b600082821015612aaa57612aaa612b45565b500390565b60005b83811015612aca578181015183820152602001612ab2565b8381111561193b5750506000910152565b600181811c90821680612aef57607f821691505b60208210811415612b1057634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612b2a57612b2a612b45565b5060010190565b600082612b4057612b40612b5b565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461113257600080fdfea26469706673582212207d36b5ea4d758aa3f6ae660136764486e68fa3aa8944f4595bdc3444dd70472764736f6c63430008070033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061017c5760003560e01c806365aad4fd116100e3578063db90e83c1161008c578063eaec5f8111610066578063eaec5f8114610351578063f242432a14610364578063f2fde38b1461037757600080fd5b8063db90e83c146102da578063ddc5ba1b14610302578063e985e9c51461031557600080fd5b80638da5cb5b116100bd5780638da5cb5b14610299578063a22cb465146102b4578063b390c0ab146102c757600080fd5b806365aad4fd1461026b578063715018a61461027e5780637cb647591461028657600080fd5b80630e89341c116101455780632eb2c2d61161011f5780632eb2c2d61461022f5780632eb4a7ab146102425780634e1273f41461024b57600080fd5b80630e89341c1461020757806322f3e2d41461021a57806329c68dc11461022757600080fd5b8062fdd58e1461018157806301ffc9a7146101a757806302fe5305146101ca57806306fdde03146101df5780630a02831c146101f4575b600080fd5b61019461018f36600461246b565b61038a565b6040519081526020015b60405180910390f35b6101ba6101b53660046125c5565b6103d4565b604051901515815260200161019e565b6101dd6101d83660046125ff565b610410565b005b6101e7610533565b60405161019e91906128fa565b6101ba610202366004612575565b6105c1565b6101e761021536600461255c565b610670565b6006546101ba9060ff1681565b6101dd6106a4565b6101dd61023d366004612320565b610712565b61019460045481565b61025e610259366004612495565b61085b565b60405161019e91906128b9565b6101dd61027936600461266a565b610aed565b6101dd610c9d565b6101dd61029436600461255c565b610d03565b6002546040516001600160a01b03909116815260200161019e565b6101dd6102c236600461242f565b610db4565b6101dd6102d5366004612648565b610e20565b6102ed6102e836600461255c565b610e7d565b6040805192835260208301919091520161019e565b6101ba61031036600461255c565b610eb7565b6101ba6103233660046122ed565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61019461035f366004612648565b610efa565b6101dd6103723660046123ca565b610f28565b6101dd6103853660046122d2565b61106a565b600080600061039884610e7d565b6001600160a01b03871660009081526020818152604080832085845290915290205491935091506103c99082610efa565b925050505b92915050565b60006001600160e01b03198216636cdb3d1360e11b14156103f757506001919050565b6301ffc9a760e01b6001600160e01b03198316146103ce565b6002546001600160a01b0316331461046f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b8060405160200161048091906127bb565b6040516020818303038152906040528051906020012060036040516020016104a891906127d7565b60405160208183030381529060405280519060200120141561051c5760405162461bcd60e51b815260206004820152602760248201527f6261736555524920697320616c7265616479207468652076616c75652062656960448201526637339039b2ba1760c91b6064820152608401610466565b805161052f90600390602084019061212c565b5050565b6007805461054090612adb565b80601f016020809104026020016040519081016040528092919081815260200182805461056c90612adb565b80156105b95780601f1061058e576101008083540402835291602001916105b9565b820191906000526020600020905b81548152906001019060200180831161059c57829003601f168201915b505050505081565b600081815b84518110156106655760008582815181106105e3576105e3612b87565b60200260200101519050808311610625576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250610652565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061065d81612b16565b9150506105c6565b509093149392505050565b6060600361067d83611135565b60405160200161068e9291906127e3565b6040516020818303038152906040529050919050565b6002546001600160a01b031633146106fe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b6006805460ff19811660ff90911615179055565b336001600160a01b038616148061074c57506001600160a01b038516600090815260016020908152604080832033845290915290205460ff165b6107be5760405162461bcd60e51b815260206004820152603c60248201527f455243313135355061636b656442616c616e636523736166654261746368547260448201527f616e7366657246726f6d3a20494e56414c49445f4f50455241544f52000000006064820152608401610466565b6001600160a01b03841661083a5760405162461bcd60e51b815260206004820152603d60248201527f455243313135355061636b656442616c616e636523736166654261746368547260448201527f616e7366657246726f6d3a20494e56414c49445f524543495049454e540000006064820152608401610466565b61084685858585611253565b610854858585855a866115f2565b5050505050565b815181516060919081146108d75760405162461bcd60e51b815260206004820152603960248201527f455243313135355061636b656442616c616e63652362616c616e63654f66426160448201527f7463683a20494e56414c49445f41525241595f4c454e475448000000000000006064820152608401610466565b6000806108fd856000815181106108f0576108f0612b87565b6020026020010151610e7d565b9150915060008060008860008151811061091957610919612b87565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000848152602001908152602001600020549050600083905060008567ffffffffffffffff81111561097557610975612b9d565b60405190808252806020026020018201604052801561099e578160200160208202803683370190505b5090506109ab8385610efa565b816000815181106109be576109be612b87565b602090810291909101015260015b86811015610ae0576109e98982815181106108f0576108f0612b87565b90965094508286141580610a4d5750898181518110610a0a57610a0a612b87565b60200260200101516001600160a01b03168a600183610a299190612a98565b81518110610a3957610a39612b87565b60200260200101516001600160a01b031614155b15610aa7576000808b8381518110610a6757610a67612b87565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008781526020019081526020016000205493508592505b610ab18486610efa565b828281518110610ac357610ac3612b87565b602090810291909101015280610ad881612b16565b9150506109cc565b5098975050505050505050565b60065460ff16610b3f5760405162461bcd60e51b815260206004820152601660248201527f436f6e7472616374206973206e6f7420616374697665000000000000000000006044820152606401610466565b6040516bffffffffffffffffffffffff193360601b1660208201526034810183905260548101849052600090607401604051602081830303815290604052805190602001209050610b9360045483836105c1565b610bdf5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420416c6c6f776c697374656400000000000000000000000000000000006044820152606401610466565b6000600581610bf06101008861297a565b8152602001908152602001600020549050600061010086610c119190612b31565b6001901b905081811615610c675760405162461bcd60e51b815260206004820152601460248201527f44726f7020616c726561647920636c61696d65640000000000000000000000006044820152606401610466565b81811760056000610c7a6101008a61297a565b8152602081019190915260400160002055610c953386611732565b505050505050565b6002546001600160a01b03163314610cf75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b610d016000611941565b565b6002546001600160a01b03163314610d5d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b806004541415610daf5760405162461bcd60e51b815260206004820152601d60248201527f6d65726b656c526f6f7420616c7265616479206265696e67207365742e0000006044820152606401610466565b600455565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60065460ff16610e725760405162461bcd60e51b815260206004820152601660248201527f436f6e7472616374206973206e6f7420616374697665000000000000000000006044820152606401610466565b61052f3383836119a0565b600080610e8d602061010061297a565b610e97908461297a565b9150610ea6602061010061297a565b610eb09084612b31565b9050915091565b600080600581610ec96101008661297a565b8152602001908152602001600020549050600061010084610eea9190612b31565b6001901b91909116159392505050565b600080610f0d6001640100000000612a98565b90506000610f1c846020612a79565b9490941c169392505050565b336001600160a01b0386161480610f6257506001600160a01b038516600090815260016020908152604080832033845290915290205460ff165b610fd45760405162461bcd60e51b815260206004820152603760248201527f455243313135355061636b656442616c616e636523736166655472616e73666560448201527f7246726f6d3a20494e56414c49445f4f50455241544f520000000000000000006064820152608401610466565b6001600160a01b0384166110505760405162461bcd60e51b815260206004820152603860248201527f455243313135355061636b656442616c616e636523736166655472616e73666560448201527f7246726f6d3a20494e56414c49445f524543495049454e5400000000000000006064820152608401610466565b61105c858585856119fb565b610854858585855a86611a66565b6002546001600160a01b031633146110c45760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610466565b6001600160a01b0381166111295760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610466565b61113281611941565b50565b6060816111595750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611183578061116d81612b16565b915061117c9050600a8361297a565b915061115d565b60008167ffffffffffffffff81111561119e5761119e612b9d565b6040519080825280601f01601f1916602001820160405280156111c8576020820181803683370190505b5090505b841561124b576111dd600183612a98565b91506111ea600a86612b31565b6111f5906030612962565b60f81b81838151811061120a5761120a612b87565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611244600a8661297a565b94506111cc565b949350505050565b8151815181146112d65760405162461bcd60e51b815260206004820152604260248201527f455243313135355061636b656442616c616e6365235f7361666542617463685460448201527f72616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e476064820152610a8960f31b608482015260a401610466565b836001600160a01b0316856001600160a01b0316141580156112f85750600081115b156114c457600080611316856000815181106108f0576108f0612b87565b6001600160a01b038916600090815260208181526040808320858452909152812054875193955091935091611367919084908890859061135857611358612b87565b60200260200101516001611b98565b6001600160a01b038816600090815260208181526040808320878452909152812054875192935090916113b691908590899085906113a7576113a7612b87565b60200260200101516000611b98565b90508360015b8681101561147f576113d98982815181106108f0576108f0612b87565b909650945081861461143b576001600160a01b038b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61145284868a848151811061135857611358612b87565b935061146b83868a84815181106113a7576113a7612b87565b92508061147781612b16565b9150506113bc565b50506001600160a01b03808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550611594565b60005b81811015611592578281815181106114e1576114e1612b87565b602002602001015161150c878684815181106114ff576114ff612b87565b602002602001015161038a565b10156115805760405162461bcd60e51b815260206004820152603660248201527f455243313135355061636b656442616c616e6365235f7361666542617463685460448201527f72616e7366657246726f6d3a20554e444552464c4f57000000000000000000006064820152608401610466565b8061158a81612b16565b9150506114c7565b505b836001600160a01b0316856001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516115e39291906128cc565b60405180910390a45050505050565b6001600160a01b0385163b15610c95576000856001600160a01b031663bc197c8184338a8989886040518763ffffffff1660e01b8152600401611639959493929190612818565b602060405180830381600088803b15801561165357600080fd5b5087f1158015611667573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061168c91906125e2565b90506001600160e01b0319811663bc197c8160e01b146117295760405162461bcd60e51b815260206004820152604c60248201527f455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433160448201527f313535426174636852656365697665643a20494e56414c49445f4f4e5f52454360648201526b454956455f4d45535341474560a01b608482015260a401610466565b50505050505050565b80600114156117585761052f826000600160405180602001604052806000815250611e61565b806002141561177e5761052f826000600260405180602001604052806000815250611e61565b6040805160028082526060820183526000926020830190803683375050604080516002808252606082018352939450600093909250906020830190803683370190505090508260051415611854576001826000815181106117e1576117e1612b87565b602090810291909101015260028260018151811061180157611801612b87565b602002602001018181525050600a8160008151811061182257611822612b87565b602002602001018181525050600a8160018151811061184357611843612b87565b602002602001018181525050611920565b60008260008151811061186957611869612b87565b602090810291909101015260018260018151811061188957611889612b87565b60200260200101818152505082600314156118d4576002816000815181106118b3576118b3612b87565b60200260200101818152505060018160018151811061184357611843612b87565b8260041415611920576004816000815181106118f2576118f2612b87565b60200260200101818152505060028160018151811061191357611913612b87565b6020026020010181815250505b61193b84838360405180602001604052806000815250611ec6565b50505050565b600280546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6119ad83838360016120bf565b60408051838152602081018390526000916001600160a01b0386169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050565b611a0884838360016120bf565b611a1583838360006120bf565b60408051838152602081018390526001600160a01b03808616929087169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050565b6001600160a01b0385163b15610c95576000856001600160a01b031663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401611aad959493929190612876565b602060405180830381600088803b158015611ac757600080fd5b5087f1158015611adb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611b0091906125e2565b90506001600160e01b0319811663f23a6e6160e01b146117295760405162461bcd60e51b815260206004820152604760248201527f455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433160448201527f31353552656365697665643a20494e56414c49445f4f4e5f524543454956455f6064820152664d45535341474560c81b608482015260a401610466565b600080611ba6856020612a79565b90506000611bba6001640100000000612a98565b90506000846001811115611bd057611bd0612b71565b1415611cd657611be285831b88612962565b925086831015611c4f5760405162461bcd60e51b815260206004820152603260248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527142696e56616c75653a204f564552464c4f5760701b6064820152608401610466565b611c5b602060026129d1565b611c698689851c8416612962565b10611cd15760405162461bcd60e51b815260206004820152603260248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527142696e56616c75653a204f564552464c4f5760701b6064820152608401610466565b611e57565b6001846001811115611cea57611cea612b71565b1415611ddb57611cfc85831b88612a98565b925086831115611d6a5760405162461bcd60e51b815260206004820152603360248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527242696e56616c75653a20554e444552464c4f5760681b6064820152608401610466565b84818389901c161015611cd15760405162461bcd60e51b815260206004820152603360248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527242696e56616c75653a20554e444552464c4f5760681b6064820152608401610466565b60405162461bcd60e51b815260206004820152604560248201527f455243313135355061636b656442616c616e6365235f7669657755706461746560448201527f42696e56616c75653a20494e56414c49445f42494e5f57524954455f4f50455260648201526420aa24a7a760d91b608482015260a401610466565b5050949350505050565b611e6e84848460006120bf565b60408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461193b60008585855a86611a66565b8151835114611f3d5760405162461bcd60e51b815260206004820152603e60248201527f455243313135354d696e744275726e5061636b656442616c616e6365235f626160448201527f7463684d696e743a20494e56414c49445f4152524159535f4c454e47544800006064820152608401610466565b82511561205857600080611f5d856000815181106108f0576108f0612b87565b6001600160a01b038816600090815260208181526040808320858452909152812054875193955091935091611f9f91908490889085906113a7576113a7612b87565b86519091508360015b8281101561202c57611fc58982815181106108f0576108f0612b87565b9096509450818614612001576001600160a01b038a16600090815260208181526040808320948352939052828120949094558584529220549184905b61201884868a84815181106113a7576113a7612b87565b93508061202481612b16565b915050611fa8565b5050506001600160a01b0387166000908152602081815260408083209583529490529290922091909155505b836001600160a01b031660006001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb86866040516120a89291906128cc565b60405180910390a461193b60008585855a866115f2565b6000806120cb85610e7d565b6001600160a01b03881660009081526020818152604080832085845290915290205491935091506120fe90828686611b98565b6001600160a01b03909616600090815260208181526040808320948352939052919091209490945550505050565b82805461213890612adb565b90600052602060002090601f01602090048101928261215a57600085556121a0565b82601f1061217357805160ff19168380011785556121a0565b828001600101855582156121a0579182015b828111156121a0578251825591602001919060010190612185565b506121ac9291506121b0565b5090565b5b808211156121ac57600081556001016121b1565b600067ffffffffffffffff8311156121df576121df612b9d565b6121f2601f8401601f191660200161290d565b905082815283838301111561220657600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461223457600080fd5b919050565b600082601f83011261224a57600080fd5b8135602061225f61225a8361293e565b61290d565b80838252828201915082860187848660051b890101111561227f57600080fd5b60005b8581101561229e57813584529284019290840190600101612282565b5090979650505050505050565b600082601f8301126122bc57600080fd5b6122cb838335602085016121c5565b9392505050565b6000602082840312156122e457600080fd5b6122cb8261221d565b6000806040838503121561230057600080fd5b6123098361221d565b91506123176020840161221d565b90509250929050565b600080600080600060a0868803121561233857600080fd5b6123418661221d565b945061234f6020870161221d565b9350604086013567ffffffffffffffff8082111561236c57600080fd5b61237889838a01612239565b9450606088013591508082111561238e57600080fd5b61239a89838a01612239565b935060808801359150808211156123b057600080fd5b506123bd888289016122ab565b9150509295509295909350565b600080600080600060a086880312156123e257600080fd5b6123eb8661221d565b94506123f96020870161221d565b93506040860135925060608601359150608086013567ffffffffffffffff81111561242357600080fd5b6123bd888289016122ab565b6000806040838503121561244257600080fd5b61244b8361221d565b91506020830135801515811461246057600080fd5b809150509250929050565b6000806040838503121561247e57600080fd5b6124878361221d565b946020939093013593505050565b600080604083850312156124a857600080fd5b823567ffffffffffffffff808211156124c057600080fd5b818501915085601f8301126124d457600080fd5b813560206124e461225a8361293e565b8083825282820191508286018a848660051b890101111561250457600080fd5b600096505b8487101561252e5761251a8161221d565b835260019690960195918301918301612509565b509650508601359250508082111561254557600080fd5b5061255285828601612239565b9150509250929050565b60006020828403121561256e57600080fd5b5035919050565b60008060006060848603121561258a57600080fd5b83359250602084013567ffffffffffffffff8111156125a857600080fd5b6125b486828701612239565b925050604084013590509250925092565b6000602082840312156125d757600080fd5b81356122cb81612bb3565b6000602082840312156125f457600080fd5b81516122cb81612bb3565b60006020828403121561261157600080fd5b813567ffffffffffffffff81111561262857600080fd5b8201601f8101841361263957600080fd5b61124b848235602084016121c5565b6000806040838503121561265b57600080fd5b50508035926020909101359150565b60008060006060848603121561267f57600080fd5b8335925060208401359150604084013567ffffffffffffffff8111156126a457600080fd5b6126b086828701612239565b9150509250925092565b600081518084526020808501945080840160005b838110156126ea578151875295820195908201906001016126ce565b509495945050505050565b6000815180845261270d816020860160208601612aaf565b601f01601f19169290920160200192915050565b8054600090600181811c908083168061273b57607f831692505b602080841082141561275d57634e487b7160e01b600052602260045260246000fd5b8180156127715760018114612782576127af565b60ff198616895284890196506127af565b60008881526020902060005b868110156127a75781548b82015290850190830161278e565b505084890196505b50505050505092915050565b600082516127cd818460208701612aaf565b9190910192915050565b60006122cb8284612721565b60006127ef8285612721565b83516127ff818360208801612aaf565b64173539b7b760d91b9101908152600501949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261284460a08301866126ba565b828103606084015261285681866126ba565b9050828103608084015261286a81856126f5565b98975050505050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526128ae60a08301846126f5565b979650505050505050565b6020815260006122cb60208301846126ba565b6040815260006128df60408301856126ba565b82810360208401526128f181856126ba565b95945050505050565b6020815260006122cb60208301846126f5565b604051601f8201601f1916810167ffffffffffffffff8111828210171561293657612936612b9d565b604052919050565b600067ffffffffffffffff82111561295857612958612b9d565b5060051b60200190565b6000821982111561297557612975612b45565b500190565b60008261298957612989612b5b565b500490565b600181815b808511156129c95781600019048211156129af576129af612b45565b808516156129bc57918102915b93841c9390800290612993565b509250929050565b60006122cb83836000826129e7575060016103ce565b816129f4575060006103ce565b8160018114612a0a5760028114612a1457612a30565b60019150506103ce565b60ff841115612a2557612a25612b45565b50506001821b6103ce565b5060208310610133831016604e8410600b8410161715612a53575081810a6103ce565b612a5d838361298e565b8060001904821115612a7157612a71612b45565b029392505050565b6000816000190483118215151615612a9357612a93612b45565b500290565b600082821015612aaa57612aaa612b45565b500390565b60005b83811015612aca578181015183820152602001612ab2565b8381111561193b5750506000910152565b600181811c90821680612aef57607f821691505b60208210811415612b1057634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612b2a57612b2a612b45565b5060010190565b600082612b4057612b40612b5b565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461113257600080fdfea26469706673582212207d36b5ea4d758aa3f6ae660136764486e68fa3aa8944f4595bdc3444dd70472764736f6c63430008070033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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