ETH Price: $2,307.86 (+0.03%)

Kokoswap NFT (KOKONFT)
 

Overview

TokenID

3

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
KokoswapNFT

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Multiple files format)

File 15 of 18: KokoswapNFT.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./Counters.sol";
import "./Ownable.sol";

import "./IKokoswap.sol";

contract KokoswapNFT is ERC721, IKokoswap,Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    
    mapping(string => uint8) hashes;
    mapping(uint256 => Artwork) private artworks;
    mapping(address => uint8) private creators;

    address public nftMarketContract;


    constructor() ERC721("Kokoswap NFT", "KOKONFT") {}


    function mintNFT(address recipient, string memory metadata, string memory artwork,  uint256 royalty ) public override returns (uint256) {
        require(hashes[metadata] != 1);
        require(hashes[artwork] != 1);
        require(creators[msg.sender] == 1, "KokoswapNFT: be a creator");
        require(royalty <= 50);

        hashes[metadata] = 1;
        hashes[artwork] = 1;
      
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        artworks[newItemId] = Artwork(block.timestamp, msg.sender, artwork, metadata, royalty);
        _mint(recipient, newItemId);
       // _setTokenURI(newItemId, tokenURI);
        emit Mint(recipient, newItemId, artwork);
        return newItemId;

    }



  function mintAndApproveNFT(address recipient, string memory metadata, string memory artwork,  uint256 royalty ) public override returns (uint256) {
        
        require(hashes[metadata] != 1);
        require(hashes[artwork] != 1);
        require(creators[msg.sender] == 1, "KokoswapNFT: be a creator");
        require(royalty <= 50);

        hashes[metadata] = 1;
        hashes[artwork] = 1;
      
        _tokenIds.increment();
        uint256 newItemId = _tokenIds.current();
        artworks[newItemId] = Artwork(block.timestamp, msg.sender, artwork, metadata, royalty);
        _mint(recipient, newItemId);

        emit Mint(recipient, newItemId, artwork);
        _approve(nftMarketContract, newItemId);

        return newItemId;

    }



    function burnNFT(uint256 tokenId) public override returns(bool){
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        Artwork memory artwork = artworks[tokenId];

        delete artworks[tokenId];
        delete hashes[artwork.metadata];
        delete hashes[artwork.artwork];

       _burn(tokenId);

       return true;

    }

    function getArtwork(uint256 tokenId) public view override returns (Artwork memory){
        require( _exists(tokenId), "ERC721: approved query for nonexistent token" );
        return artworks[tokenId];
    }

    function isCreator(address creator) public view override returns(bool){
        return creators[creator] == 1;
    }


    function addCreator(address creator) public override onlyOwner returns(bool){
        require(creators[creator] != 1, "KokoswapNFT: creator already exist");
        creators[creator] = 1;
        return true;
    }
    function removeCreator(address creator)  public  override onlyOwner returns(bool){
        require(creators[creator] == 1, "KokoswapNFT: creator doesn't exist");
        creators[creator] = 0;
        return true;
    }
    
    function setNftMarketContract(address marketContract) public  override onlyOwner returns(bool){
       nftMarketContract = marketContract;
        return true;
    }

    

  }

File 1 of 18: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

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

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

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

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

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

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

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

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

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

pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 3 of 18: Counters.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

File 4 of 18: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 5 of 18: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol";
import "./Address.sol";
import "./Context.sol";
import "./Strings.sol";
import "./ERC165.sol";

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

File 6 of 18: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 7 of 18: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 8 of 18: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 9 of 18: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 10 of 18: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

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

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

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

File 11 of 18: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 12 of 18: IKokoswap.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IKokoswap {

    struct Artwork {
        uint256 date;
        address creator;
        string artwork;
        string metadata;
        uint256 royalty;
    }



    function mintNFT( address recipient, string memory metadata,  string memory artwork,  uint256 royalty) external returns (uint256);
    function mintAndApproveNFT( address recipient, string memory metadata,  string memory artwork,  uint256 royalty) external returns (uint256);

    function burnNFT(uint256 tokenId)  external  returns(bool);

    function getArtwork(uint256 tokenId) external view returns (Artwork memory);
  
    function isCreator(address creator)  external view returns(bool);


    function addCreator(address creator)  external returns(bool);    
    function removeCreator(address creator)  external returns(bool);

    function setNftMarketContract(address marketContract) external  returns(bool);


     event Mint(address indexed to, uint256  tokenId, string artwork);


}

File 13 of 18: IMarket.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IMarket {

   enum CURRENCY{ ETH, TOKEN}

    struct Auction {
        bool active;
        address seller;
        address owner;
        uint256 value;
        uint256 endTime;
        CURRENCY currency;
    }



    function listOnAuction(uint256 _tokenId, uint256 _price, CURRENCY currency, uint256 _days) external returns (Auction memory);

    function bid(uint256 _tokenId,uint256 _price) external payable returns (Auction memory);

    function claimNft(uint256 _tokenId) external returns (uint256);

    function withdraw(address _address, uint256 _value, CURRENCY currency) external ;

    function getAuction(uint256 _tokenId) external view returns (Auction memory);

    
   function setTokenAddress(address erc721contract, address erc20contract) external ;

   // function setERC721TokenAddress(address _address) external ;

//    function setERC20TokenAddress(address _address) external ;

    function setFee(uint256 fee, uint256 tokenFee) external;

    function setNextBidPercentage(uint256 nextBidPercent) external;



    event ListOnAuction(address indexed owner, uint256  tokenId,uint256 price, uint256 endTime, CURRENCY currency);

    event Bid(address  bidder, uint256 indexed tokenId, uint256 value, CURRENCY currency);

    event ClaimNft(address collector, uint256 indexed tokenId, uint256 value);
}

File 14 of 18: KokoswapMarket.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ERC721.sol";
import "./Counters.sol";
import "./SafeMath.sol";
import "./Ownable.sol";

import "./IMarket.sol";
import "./KokoswapNFT.sol";
import "./IERC20.sol";


contract KokoswapMarket is IMarket,Ownable {

    uint256 public constant AUCTION_TIME = 259200; //3 days
    uint256 public constant LAST_BIDDER_RESET_TIME = 900;

    uint256 public FEE = 15;
    uint256 public TOKEN_FEE = 15;
    uint256 public NEXT_BID_PERCENTAGE = 5;
    
    address public ERC20_TOKEN_ADDRESS;
    address public ERC721_TOKEN_ADDRESS;

    mapping(uint256 => Auction) private auctionList;

    constructor() {}

    function listOnAuction(uint256 tokenId, uint256 price, CURRENCY currency, uint256 _days ) public override returns (Auction memory) {
        require(KokoswapNFT(ERC721_TOKEN_ADDRESS).ownerOf(tokenId) == msg.sender, "EA");
         require(!auctionList[tokenId].active, "ES" );

        Auction memory newAuction = Auction(true, msg.sender, address(0), price, _days + block.timestamp, currency );
        auctionList[tokenId] = newAuction;

        KokoswapNFT(ERC721_TOKEN_ADDRESS).transferFrom(msg.sender, address(this), tokenId);

        emit ListOnAuction(msg.sender, tokenId, price, _days + block.timestamp, currency);

        return newAuction;
    }

    function bid(uint256 _tokenId, uint256 _price) public payable override returns(Auction memory){
        Auction memory auctionItem = auctionList[_tokenId];
        require(auctionItem.active, "ES");

        if(block.timestamp > auctionItem.endTime){
            if(auctionItem.owner != address(0)){
                revert("ET");
            }
            auctionItem.endTime = AUCTION_TIME + block.timestamp;
        }

        uint256 bidValueMust = auctionItem.value + (auctionItem.value * NEXT_BID_PERCENTAGE / 100);
        if(auctionItem.currency == CURRENCY.ETH){
            require( bidValueMust <= msg.value, "EV" );
            if(auctionItem.owner != address(0)) {
                payable(auctionItem.owner).transfer(auctionItem.value);
            }
                auctionItem.value = msg.value;
        }else{
            require( bidValueMust <= _price, "EV" );
            require(IERC20(ERC20_TOKEN_ADDRESS).allowance(msg.sender, address(this)) >= _price, "EA");
            IERC20(ERC20_TOKEN_ADDRESS).transferFrom(msg.sender, address(this), _price);
            if(auctionItem.owner != address(0)) {
                IERC20(ERC20_TOKEN_ADDRESS).transfer(auctionItem.owner,auctionItem.value);
            }
            auctionItem.value = _price;
        }
        
        auctionItem.owner = msg.sender;

        if (auctionItem.endTime - block.timestamp < LAST_BIDDER_RESET_TIME) {
            auctionItem.endTime = LAST_BIDDER_RESET_TIME + block.timestamp;
        }

        auctionList[_tokenId] = auctionItem;
        emit Bid(msg.sender, _tokenId, auctionItem.value,  auctionItem.currency);
        return auctionList[_tokenId];
    }


    function claimNft(uint256 _tokenId) public override returns(uint256) {
        Auction memory auctionItem = auctionList[_tokenId];
        require(auctionItem.active, "ES");
        require(block.timestamp > auctionItem.endTime, "ET");
        require(auctionItem.seller == msg.sender || auctionItem.owner == msg.sender, "EA");

        if (auctionItem.owner == address(0)) {
            KokoswapNFT(ERC721_TOKEN_ADDRESS).transferFrom(address(this), auctionItem.seller, _tokenId);
        } else {
            KokoswapNFT(ERC721_TOKEN_ADDRESS).transferFrom(address(this), auctionItem.owner, _tokenId);

            KokoswapNFT.Artwork memory artwork = KokoswapNFT(ERC721_TOKEN_ADDRESS).getArtwork(_tokenId);
            uint256 royalityValue = (auctionItem.value * artwork.royalty) / 100;
            
            if(auctionItem.currency == CURRENCY.ETH){
                uint256 serviceFee = (auctionItem.value * FEE) / 100;
                uint256 value = auctionItem.value - (serviceFee + royalityValue);
                payable(auctionItem.seller).transfer(value);
                if(royalityValue > 0){
                    payable(artwork.creator).transfer(royalityValue);
                }
                
            }else{
                uint256 serviceFee = (auctionItem.value * TOKEN_FEE) / 100;
                uint256 value = auctionItem.value - (serviceFee + royalityValue);
                IERC20(ERC20_TOKEN_ADDRESS).transfer(auctionItem.seller,value);
                if(royalityValue > 0){
                    IERC20(ERC20_TOKEN_ADDRESS).transfer(artwork.creator,royalityValue);
                }
            }
        }

        delete auctionList[_tokenId];
        emit ClaimNft(auctionItem.owner, _tokenId, auctionItem.value);
        return _tokenId;
       
    }

    

    function getAuction(uint256 _tokenId) public view override returns (Auction memory) {
        return auctionList[_tokenId];
    }


    function setTokenAddress(address erc721contract, address erc20contract ) public override onlyOwner {
        ERC721_TOKEN_ADDRESS = erc721contract;
        ERC20_TOKEN_ADDRESS = erc20contract;

    }


    function setFee(uint256 fee, uint256 tokenFee) public override onlyOwner {
        FEE = fee;
        TOKEN_FEE = tokenFee;
    }

    function setNextBidPercentage(uint256 nextBidPercent) public override onlyOwner {
        NEXT_BID_PERCENTAGE = nextBidPercent;
    }


    function withdraw(address _address, uint256 _value, CURRENCY currency) public override onlyOwner {
        if(currency == CURRENCY.ETH){
            payable(_address).transfer(_value);
        }else{
           IERC20(ERC20_TOKEN_ADDRESS).transfer(_address,_value);
        }
    }

     function transferAnyERC20Token(address _address, uint tokens) public onlyOwner returns (bool success) {
        return IERC20(_address).transfer(owner(), tokens);
    }

  }

File 16 of 18: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        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 18 of 18: Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

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

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

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

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

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"artwork","type":"string"}],"name":"Mint","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":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"addCreator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getArtwork","outputs":[{"components":[{"internalType":"uint256","name":"date","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"string","name":"artwork","type":"string"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"uint256","name":"royalty","type":"uint256"}],"internalType":"struct IKokoswap.Artwork","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"isCreator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"string","name":"artwork","type":"string"},{"internalType":"uint256","name":"royalty","type":"uint256"}],"name":"mintAndApproveNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"string","name":"metadata","type":"string"},{"internalType":"string","name":"artwork","type":"string"},{"internalType":"uint256","name":"royalty","type":"uint256"}],"name":"mintNFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftMarketContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"}],"name":"removeCreator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketContract","type":"address"}],"name":"setNftMarketContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604080518082018252600c81526b12dbdadbdcddd85c0813919560a21b60208083019182528351808501909452600784526612d3d2d3d3919560ca1b9084015281519192916200006591600091620000e8565b5080516200007b906001906020840190620000e8565b505050600062000090620000e460201b60201c565b600680546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350620001cb565b3390565b828054620000f6906200018e565b90600052602060002090601f0160209004810192826200011a576000855562000165565b82601f106200013557805160ff191683800117855562000165565b8280016001018555821562000165579182015b828111156200016557825182559160200191906001019062000148565b506200017392915062000177565b5090565b5b8082111562000173576000815560010162000178565b600281046001821680620001a357607f821691505b60208210811415620001c557634e487b7160e01b600052602260045260246000fd5b50919050565b6125b780620001db6000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063b88d4fde11610097578063cdd1e9ba11610071578063cdd1e9ba1461031c578063e985e9c51461032f578063efd4606514610342578063f2fde38b1461035557610173565b8063b88d4fde146102e3578063bd6018bb146102f6578063c87b56dd1461030957610173565b80636352211e1461029257806370a08231146102a5578063715018a6146102b85780638da5cb5b146102c057806395d89b41146102c8578063a22cb465146102d057610173565b806323b872dd1161013057806323b872dd146102135780632890e0d7146102265780633b9dce051461023957806342842e0e1461024c5780634979684c1461025f57806351f8fefe1461027f57610173565b806301ffc9a71461017857806306fdde03146101a1578063081812fc146101b6578063095ea7b3146101d6578063167ddf6e146101eb5780631a7438091461020b575b600080fd5b61018b610186366004611d1b565b610368565b6040516101989190611e33565b60405180910390f35b6101a96103b0565b6040516101989190611e3e565b6101c96101c4366004611d53565b610442565b6040516101989190611de2565b6101e96101e4366004611cf2565b61048e565b005b6101fe6101f9366004611d53565b610526565b60405161019891906123c2565b6101c96106c2565b6101e9610221366004611b8b565b6106d1565b61018b610234366004611d53565b610709565b61018b610247366004611b3f565b61094e565b6101e961025a366004611b8b565b6109f4565b61027261026d366004611c79565b610a0f565b604051610198919061242e565b61027261028d366004611c79565b610c46565b6101c96102a0366004611d53565b610e65565b6102726102b3366004611b3f565b610e9a565b6101e9610ede565b6101c9610f67565b6101a9610f76565b6101e96102de366004611c3f565b610f85565b6101e96102f1366004611bc6565b611053565b61018b610304366004611b3f565b61108c565b6101a9610317366004611d53565b61112d565b61018b61032a366004611b3f565b6111b0565b61018b61033d366004611b59565b611216565b61018b610350366004611b3f565b611244565b6101e9610363366004611b3f565b611265565b60006001600160e01b031982166380ac58cd60e01b148061039957506001600160e01b03198216635b5e139f60e01b145b806103a857506103a882611326565b90505b919050565b6060600080546103bf906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546103eb906124bf565b80156104385780601f1061040d57610100808354040283529160200191610438565b820191906000526020600020905b81548152906001019060200180831161041b57829003601f168201915b5050505050905090565b600061044d8261133f565b6104725760405162461bcd60e51b81526004016104699061214e565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061049982610e65565b9050806001600160a01b0316836001600160a01b031614156104cd5760405162461bcd60e51b815260040161046990612267565b806001600160a01b03166104df61135c565b6001600160a01b031614806104fb57506104fb8161033d61135c565b6105175760405162461bcd60e51b815260040161046990612029565b6105218383611360565b505050565b61052e611989565b6105378261133f565b6105535760405162461bcd60e51b81526004016104699061214e565b600082815260096020908152604091829020825160a0810184528154815260018201546001600160a01b031692810192909252600281018054929391929184019161059d906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546105c9906124bf565b80156106165780601f106105eb57610100808354040283529160200191610616565b820191906000526020600020905b8154815290600101906020018083116105f957829003601f168201915b5050505050815260200160038201805461062f906124bf565b80601f016020809104026020016040519081016040528092919081815260200182805461065b906124bf565b80156106a85780601f1061067d576101008083540402835291602001916106a8565b820191906000526020600020905b81548152906001019060200180831161068b57829003601f168201915b505050505081526020016004820154815250509050919050565b600b546001600160a01b031681565b6106e26106dc61135c565b826113ce565b6106fe5760405162461bcd60e51b8152600401610469906122a8565b61052183838361144b565b600061071c61071661135c565b836113ce565b6107385760405162461bcd60e51b8152600401610469906122f9565b6000828152600960209081526040808320815160a0810183528154815260018201546001600160a01b031693810193909352600281018054919284019161077e906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546107aa906124bf565b80156107f75780601f106107cc576101008083540402835291602001916107f7565b820191906000526020600020905b8154815290600101906020018083116107da57829003601f168201915b50505050508152602001600382018054610810906124bf565b80601f016020809104026020016040519081016040528092919081815260200182805461083c906124bf565b80156108895780601f1061085e57610100808354040283529160200191610889565b820191906000526020600020905b81548152906001019060200180831161086c57829003601f168201915b50505091835250506004919091015460209182015260008581526009909152604081208181556001810180546001600160a01b03191690559192506108d160028301826119c1565b6108df6003830160006119c1565b60048201600090555050600881606001516040516108fd9190611d97565b90815260408051918290036020018220805460ff191690558201516008916109259190611d97565b908152604051908190036020019020805460ff1916905561094583611578565b50600192915050565b600061095861135c565b6001600160a01b0316610969610f67565b6001600160a01b03161461098f5760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0382166000908152600a602052604090205460ff16600114156109cb5760405162461bcd60e51b815260040161046990612380565b506001600160a01b03166000908152600a60205260409020805460ff1916600190811790915590565b61052183838360405180602001604052806000815250611053565b6000600884604051610a219190611d97565b9081526040519081900360200190205460ff1660011415610a4157600080fd5b600883604051610a519190611d97565b9081526040519081900360200190205460ff1660011415610a7157600080fd5b336000908152600a602052604090205460ff16600114610aa35760405162461bcd60e51b815260040161046990612349565b6032821115610ab157600080fd5b6001600885604051610ac39190611d97565b908152602001604051809103902060006101000a81548160ff021916908360ff1602179055506001600884604051610afb9190611d97565b908152604051908190036020019020805460ff9290921660ff19909216919091179055610b28600761161f565b6000610b346007611628565b6040805160a081018252428152336020808301918252828401898152606084018b905260808401899052600086815260098352949094208351815591516001830180546001600160a01b0319166001600160a01b039092169190911790559251805194955091939092610bae926002850192910190611a00565b5060608201518051610bca916003840191602090910190611a00565b5060808201518160040155905050610be2868261162c565b856001600160a01b03167f85a66b9141978db9980f7e0ce3b468cebf4f7999f32b23091c5c03e798b1ba7a8286604051610c1d929190612437565b60405180910390a2600b54610c3b906001600160a01b031682611360565b90505b949350505050565b6000600884604051610c589190611d97565b9081526040519081900360200190205460ff1660011415610c7857600080fd5b600883604051610c889190611d97565b9081526040519081900360200190205460ff1660011415610ca857600080fd5b336000908152600a602052604090205460ff16600114610cda5760405162461bcd60e51b815260040161046990612349565b6032821115610ce857600080fd5b6001600885604051610cfa9190611d97565b908152602001604051809103902060006101000a81548160ff021916908360ff1602179055506001600884604051610d329190611d97565b908152604051908190036020019020805460ff9290921660ff19909216919091179055610d5f600761161f565b6000610d6b6007611628565b6040805160a081018252428152336020808301918252828401898152606084018b905260808401899052600086815260098352949094208351815591516001830180546001600160a01b0319166001600160a01b039092169190911790559251805194955091939092610de5926002850192910190611a00565b5060608201518051610e01916003840191602090910190611a00565b5060808201518160040155905050610e19868261162c565b856001600160a01b03167f85a66b9141978db9980f7e0ce3b468cebf4f7999f32b23091c5c03e798b1ba7a8286604051610e54929190612437565b60405180910390a295945050505050565b6000818152600260205260408120546001600160a01b0316806103a85760405162461bcd60e51b8152600401610469906120d0565b60006001600160a01b038216610ec25760405162461bcd60e51b815260040161046990612086565b506001600160a01b031660009081526003602052604090205490565b610ee661135c565b6001600160a01b0316610ef7610f67565b6001600160a01b031614610f1d5760405162461bcd60e51b81526004016104699061219a565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b6006546001600160a01b031690565b6060600180546103bf906124bf565b610f8d61135c565b6001600160a01b0316826001600160a01b03161415610fbe5760405162461bcd60e51b815260040161046990611f64565b8060056000610fcb61135c565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561100f61135c565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110479190611e33565b60405180910390a35050565b61105e61071661135c565b61107a5760405162461bcd60e51b8152600401610469906122a8565b6110868484848461170b565b50505050565b600061109661135c565b6001600160a01b03166110a7610f67565b6001600160a01b0316146110cd5760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0382166000908152600a602052604090205460ff166001146111085760405162461bcd60e51b815260040161046990611fe7565b506001600160a01b03166000908152600a60205260409020805460ff19169055600190565b60606111388261133f565b6111545760405162461bcd60e51b815260040161046990612218565b600061115e61173e565b9050600081511161117e57604051806020016040528060008152506111a9565b8061118884611750565b604051602001611199929190611db3565b6040516020818303038152906040525b9392505050565b60006111ba61135c565b6001600160a01b03166111cb610f67565b6001600160a01b0316146111f15760405162461bcd60e51b81526004016104699061219a565b50600b80546001600160a01b0383166001600160a01b03199091161790556001919050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6001600160a01b03166000908152600a602052604090205460ff1660011490565b61126d61135c565b6001600160a01b031661127e610f67565b6001600160a01b0316146112a45760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0381166112ca5760405162461bcd60e51b815260040161046990611ea3565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061139582610e65565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006113d98261133f565b6113f55760405162461bcd60e51b815260040161046990611f9b565b600061140083610e65565b9050806001600160a01b0316846001600160a01b0316148061143b5750836001600160a01b031661143084610442565b6001600160a01b0316145b80610c3e5750610c3e8185611216565b826001600160a01b031661145e82610e65565b6001600160a01b0316146114845760405162461bcd60e51b8152600401610469906121cf565b6001600160a01b0382166114aa5760405162461bcd60e51b815260040161046990611f20565b6114b5838383610521565b6114c0600082611360565b6001600160a01b03831660009081526003602052604081208054600192906114e990849061247c565b90915550506001600160a01b0382166000908152600360205260408120805460019290611517908490612450565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061158382610e65565b905061159181600084610521565b61159c600083611360565b6001600160a01b03811660009081526003602052604081208054600192906115c590849061247c565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b80546001019055565b5490565b6001600160a01b0382166116525760405162461bcd60e51b815260040161046990612119565b61165b8161133f565b156116785760405162461bcd60e51b815260040161046990611ee9565b61168460008383610521565b6001600160a01b03821660009081526003602052604081208054600192906116ad908490612450565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61171684848461144b565b6117228484848461186b565b6110865760405162461bcd60e51b815260040161046990611e51565b60408051602081019091526000815290565b60608161177557506040805180820190915260018152600360fc1b60208201526103ab565b8160005b811561179f5780611789816124fa565b91506117989050600a83612468565b9150611779565b60008167ffffffffffffffff8111156117c857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156117f2576020820181803683370190505b5090505b8415610c3e5761180760018361247c565b9150611814600a86612515565b61181f906030612450565b60f81b81838151811061184257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611864600a86612468565b94506117f6565b600061187f846001600160a01b0316611983565b1561197b57836001600160a01b031663150b7a0261189b61135c565b8786866040518563ffffffff1660e01b81526004016118bd9493929190611df6565b602060405180830381600087803b1580156118d757600080fd5b505af1925050508015611907575060408051601f3d908101601f1916820190925261190491810190611d37565b60015b611961573d808015611935576040519150601f19603f3d011682016040523d82523d6000602084013e61193a565b606091505b5080516119595760405162461bcd60e51b815260040161046990611e51565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610c3e565b506001610c3e565b3b151590565b6040518060a001604052806000815260200160006001600160a01b031681526020016060815260200160608152602001600081525090565b5080546119cd906124bf565b6000825580601f106119df57506119fd565b601f0160209004906000526020600020908101906119fd9190611a84565b50565b828054611a0c906124bf565b90600052602060002090601f016020900481019282611a2e5760008555611a74565b82601f10611a4757805160ff1916838001178555611a74565b82800160010185558215611a74579182015b82811115611a74578251825591602001919060010190611a59565b50611a80929150611a84565b5090565b5b80821115611a805760008155600101611a85565b600067ffffffffffffffff80841115611ab457611ab4612555565b604051601f8501601f191681016020018281118282101715611ad857611ad8612555565b604052848152915081838501861015611af057600080fd5b8484602083013760006020868301015250509392505050565b80356001600160a01b03811681146103ab57600080fd5b600082601f830112611b30578081fd5b6111a983833560208501611a99565b600060208284031215611b50578081fd5b6111a982611b09565b60008060408385031215611b6b578081fd5b611b7483611b09565b9150611b8260208401611b09565b90509250929050565b600080600060608486031215611b9f578081fd5b611ba884611b09565b9250611bb660208501611b09565b9150604084013590509250925092565b60008060008060808587031215611bdb578081fd5b611be485611b09565b9350611bf260208601611b09565b925060408501359150606085013567ffffffffffffffff811115611c14578182fd5b8501601f81018713611c24578182fd5b611c3387823560208401611a99565b91505092959194509250565b60008060408385031215611c51578182fd5b611c5a83611b09565b915060208301358015158114611c6e578182fd5b809150509250929050565b60008060008060808587031215611c8e578384fd5b611c9785611b09565b9350602085013567ffffffffffffffff80821115611cb3578485fd5b611cbf88838901611b20565b94506040870135915080821115611cd4578384fd5b50611ce187828801611b20565b949793965093946060013593505050565b60008060408385031215611d04578182fd5b611d0d83611b09565b946020939093013593505050565b600060208284031215611d2c578081fd5b81356111a98161256b565b600060208284031215611d48578081fd5b81516111a98161256b565b600060208284031215611d64578081fd5b5035919050565b60008151808452611d83816020860160208601612493565b601f01601f19169290920160200192915050565b60008251611da9818460208701612493565b9190910192915050565b60008351611dc5818460208801612493565b835190830190611dd9818360208801612493565b01949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611e2990830184611d6b565b9695505050505050565b901515815260200190565b6000602082526111a96020830184611d6b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526022908201527f4b6f6b6f737761704e46543a2063726561746f7220646f65736e2774206578696040820152611cdd60f21b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b60208082526019908201527f4b6f6b6f737761704e46543a20626520612063726561746f7200000000000000604082015260600190565b60208082526022908201527f4b6f6b6f737761704e46543a2063726561746f7220616c7265616479206578696040820152611cdd60f21b606082015260800190565b6000602082528251602083015260018060a01b036020840151166040830152604083015160a060608401526123fa60c0840182611d6b565b90506060840151601f198483030160808501526124178282611d6b565b915050608084015160a08401528091505092915050565b90815260200190565b600083825260406020830152610c3e6040830184611d6b565b6000821982111561246357612463612529565b500190565b6000826124775761247761253f565b500490565b60008282101561248e5761248e612529565b500390565b60005b838110156124ae578181015183820152602001612496565b838111156110865750506000910152565b6002810460018216806124d357607f821691505b602082108114156124f457634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561250e5761250e612529565b5060010190565b6000826125245761252461253f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146119fd57600080fdfea2646970667358221220f9ca35254400a10b24f2dd787a6780542846510dfbb9e3523655310717a6bf7b64736f6c63430008000033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101735760003560e01c80636352211e116100de578063b88d4fde11610097578063cdd1e9ba11610071578063cdd1e9ba1461031c578063e985e9c51461032f578063efd4606514610342578063f2fde38b1461035557610173565b8063b88d4fde146102e3578063bd6018bb146102f6578063c87b56dd1461030957610173565b80636352211e1461029257806370a08231146102a5578063715018a6146102b85780638da5cb5b146102c057806395d89b41146102c8578063a22cb465146102d057610173565b806323b872dd1161013057806323b872dd146102135780632890e0d7146102265780633b9dce051461023957806342842e0e1461024c5780634979684c1461025f57806351f8fefe1461027f57610173565b806301ffc9a71461017857806306fdde03146101a1578063081812fc146101b6578063095ea7b3146101d6578063167ddf6e146101eb5780631a7438091461020b575b600080fd5b61018b610186366004611d1b565b610368565b6040516101989190611e33565b60405180910390f35b6101a96103b0565b6040516101989190611e3e565b6101c96101c4366004611d53565b610442565b6040516101989190611de2565b6101e96101e4366004611cf2565b61048e565b005b6101fe6101f9366004611d53565b610526565b60405161019891906123c2565b6101c96106c2565b6101e9610221366004611b8b565b6106d1565b61018b610234366004611d53565b610709565b61018b610247366004611b3f565b61094e565b6101e961025a366004611b8b565b6109f4565b61027261026d366004611c79565b610a0f565b604051610198919061242e565b61027261028d366004611c79565b610c46565b6101c96102a0366004611d53565b610e65565b6102726102b3366004611b3f565b610e9a565b6101e9610ede565b6101c9610f67565b6101a9610f76565b6101e96102de366004611c3f565b610f85565b6101e96102f1366004611bc6565b611053565b61018b610304366004611b3f565b61108c565b6101a9610317366004611d53565b61112d565b61018b61032a366004611b3f565b6111b0565b61018b61033d366004611b59565b611216565b61018b610350366004611b3f565b611244565b6101e9610363366004611b3f565b611265565b60006001600160e01b031982166380ac58cd60e01b148061039957506001600160e01b03198216635b5e139f60e01b145b806103a857506103a882611326565b90505b919050565b6060600080546103bf906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546103eb906124bf565b80156104385780601f1061040d57610100808354040283529160200191610438565b820191906000526020600020905b81548152906001019060200180831161041b57829003601f168201915b5050505050905090565b600061044d8261133f565b6104725760405162461bcd60e51b81526004016104699061214e565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061049982610e65565b9050806001600160a01b0316836001600160a01b031614156104cd5760405162461bcd60e51b815260040161046990612267565b806001600160a01b03166104df61135c565b6001600160a01b031614806104fb57506104fb8161033d61135c565b6105175760405162461bcd60e51b815260040161046990612029565b6105218383611360565b505050565b61052e611989565b6105378261133f565b6105535760405162461bcd60e51b81526004016104699061214e565b600082815260096020908152604091829020825160a0810184528154815260018201546001600160a01b031692810192909252600281018054929391929184019161059d906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546105c9906124bf565b80156106165780601f106105eb57610100808354040283529160200191610616565b820191906000526020600020905b8154815290600101906020018083116105f957829003601f168201915b5050505050815260200160038201805461062f906124bf565b80601f016020809104026020016040519081016040528092919081815260200182805461065b906124bf565b80156106a85780601f1061067d576101008083540402835291602001916106a8565b820191906000526020600020905b81548152906001019060200180831161068b57829003601f168201915b505050505081526020016004820154815250509050919050565b600b546001600160a01b031681565b6106e26106dc61135c565b826113ce565b6106fe5760405162461bcd60e51b8152600401610469906122a8565b61052183838361144b565b600061071c61071661135c565b836113ce565b6107385760405162461bcd60e51b8152600401610469906122f9565b6000828152600960209081526040808320815160a0810183528154815260018201546001600160a01b031693810193909352600281018054919284019161077e906124bf565b80601f01602080910402602001604051908101604052809291908181526020018280546107aa906124bf565b80156107f75780601f106107cc576101008083540402835291602001916107f7565b820191906000526020600020905b8154815290600101906020018083116107da57829003601f168201915b50505050508152602001600382018054610810906124bf565b80601f016020809104026020016040519081016040528092919081815260200182805461083c906124bf565b80156108895780601f1061085e57610100808354040283529160200191610889565b820191906000526020600020905b81548152906001019060200180831161086c57829003601f168201915b50505091835250506004919091015460209182015260008581526009909152604081208181556001810180546001600160a01b03191690559192506108d160028301826119c1565b6108df6003830160006119c1565b60048201600090555050600881606001516040516108fd9190611d97565b90815260408051918290036020018220805460ff191690558201516008916109259190611d97565b908152604051908190036020019020805460ff1916905561094583611578565b50600192915050565b600061095861135c565b6001600160a01b0316610969610f67565b6001600160a01b03161461098f5760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0382166000908152600a602052604090205460ff16600114156109cb5760405162461bcd60e51b815260040161046990612380565b506001600160a01b03166000908152600a60205260409020805460ff1916600190811790915590565b61052183838360405180602001604052806000815250611053565b6000600884604051610a219190611d97565b9081526040519081900360200190205460ff1660011415610a4157600080fd5b600883604051610a519190611d97565b9081526040519081900360200190205460ff1660011415610a7157600080fd5b336000908152600a602052604090205460ff16600114610aa35760405162461bcd60e51b815260040161046990612349565b6032821115610ab157600080fd5b6001600885604051610ac39190611d97565b908152602001604051809103902060006101000a81548160ff021916908360ff1602179055506001600884604051610afb9190611d97565b908152604051908190036020019020805460ff9290921660ff19909216919091179055610b28600761161f565b6000610b346007611628565b6040805160a081018252428152336020808301918252828401898152606084018b905260808401899052600086815260098352949094208351815591516001830180546001600160a01b0319166001600160a01b039092169190911790559251805194955091939092610bae926002850192910190611a00565b5060608201518051610bca916003840191602090910190611a00565b5060808201518160040155905050610be2868261162c565b856001600160a01b03167f85a66b9141978db9980f7e0ce3b468cebf4f7999f32b23091c5c03e798b1ba7a8286604051610c1d929190612437565b60405180910390a2600b54610c3b906001600160a01b031682611360565b90505b949350505050565b6000600884604051610c589190611d97565b9081526040519081900360200190205460ff1660011415610c7857600080fd5b600883604051610c889190611d97565b9081526040519081900360200190205460ff1660011415610ca857600080fd5b336000908152600a602052604090205460ff16600114610cda5760405162461bcd60e51b815260040161046990612349565b6032821115610ce857600080fd5b6001600885604051610cfa9190611d97565b908152602001604051809103902060006101000a81548160ff021916908360ff1602179055506001600884604051610d329190611d97565b908152604051908190036020019020805460ff9290921660ff19909216919091179055610d5f600761161f565b6000610d6b6007611628565b6040805160a081018252428152336020808301918252828401898152606084018b905260808401899052600086815260098352949094208351815591516001830180546001600160a01b0319166001600160a01b039092169190911790559251805194955091939092610de5926002850192910190611a00565b5060608201518051610e01916003840191602090910190611a00565b5060808201518160040155905050610e19868261162c565b856001600160a01b03167f85a66b9141978db9980f7e0ce3b468cebf4f7999f32b23091c5c03e798b1ba7a8286604051610e54929190612437565b60405180910390a295945050505050565b6000818152600260205260408120546001600160a01b0316806103a85760405162461bcd60e51b8152600401610469906120d0565b60006001600160a01b038216610ec25760405162461bcd60e51b815260040161046990612086565b506001600160a01b031660009081526003602052604090205490565b610ee661135c565b6001600160a01b0316610ef7610f67565b6001600160a01b031614610f1d5760405162461bcd60e51b81526004016104699061219a565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b6006546001600160a01b031690565b6060600180546103bf906124bf565b610f8d61135c565b6001600160a01b0316826001600160a01b03161415610fbe5760405162461bcd60e51b815260040161046990611f64565b8060056000610fcb61135c565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561100f61135c565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110479190611e33565b60405180910390a35050565b61105e61071661135c565b61107a5760405162461bcd60e51b8152600401610469906122a8565b6110868484848461170b565b50505050565b600061109661135c565b6001600160a01b03166110a7610f67565b6001600160a01b0316146110cd5760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0382166000908152600a602052604090205460ff166001146111085760405162461bcd60e51b815260040161046990611fe7565b506001600160a01b03166000908152600a60205260409020805460ff19169055600190565b60606111388261133f565b6111545760405162461bcd60e51b815260040161046990612218565b600061115e61173e565b9050600081511161117e57604051806020016040528060008152506111a9565b8061118884611750565b604051602001611199929190611db3565b6040516020818303038152906040525b9392505050565b60006111ba61135c565b6001600160a01b03166111cb610f67565b6001600160a01b0316146111f15760405162461bcd60e51b81526004016104699061219a565b50600b80546001600160a01b0383166001600160a01b03199091161790556001919050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6001600160a01b03166000908152600a602052604090205460ff1660011490565b61126d61135c565b6001600160a01b031661127e610f67565b6001600160a01b0316146112a45760405162461bcd60e51b81526004016104699061219a565b6001600160a01b0381166112ca5760405162461bcd60e51b815260040161046990611ea3565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061139582610e65565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006113d98261133f565b6113f55760405162461bcd60e51b815260040161046990611f9b565b600061140083610e65565b9050806001600160a01b0316846001600160a01b0316148061143b5750836001600160a01b031661143084610442565b6001600160a01b0316145b80610c3e5750610c3e8185611216565b826001600160a01b031661145e82610e65565b6001600160a01b0316146114845760405162461bcd60e51b8152600401610469906121cf565b6001600160a01b0382166114aa5760405162461bcd60e51b815260040161046990611f20565b6114b5838383610521565b6114c0600082611360565b6001600160a01b03831660009081526003602052604081208054600192906114e990849061247c565b90915550506001600160a01b0382166000908152600360205260408120805460019290611517908490612450565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061158382610e65565b905061159181600084610521565b61159c600083611360565b6001600160a01b03811660009081526003602052604081208054600192906115c590849061247c565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b80546001019055565b5490565b6001600160a01b0382166116525760405162461bcd60e51b815260040161046990612119565b61165b8161133f565b156116785760405162461bcd60e51b815260040161046990611ee9565b61168460008383610521565b6001600160a01b03821660009081526003602052604081208054600192906116ad908490612450565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61171684848461144b565b6117228484848461186b565b6110865760405162461bcd60e51b815260040161046990611e51565b60408051602081019091526000815290565b60608161177557506040805180820190915260018152600360fc1b60208201526103ab565b8160005b811561179f5780611789816124fa565b91506117989050600a83612468565b9150611779565b60008167ffffffffffffffff8111156117c857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156117f2576020820181803683370190505b5090505b8415610c3e5761180760018361247c565b9150611814600a86612515565b61181f906030612450565b60f81b81838151811061184257634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611864600a86612468565b94506117f6565b600061187f846001600160a01b0316611983565b1561197b57836001600160a01b031663150b7a0261189b61135c565b8786866040518563ffffffff1660e01b81526004016118bd9493929190611df6565b602060405180830381600087803b1580156118d757600080fd5b505af1925050508015611907575060408051601f3d908101601f1916820190925261190491810190611d37565b60015b611961573d808015611935576040519150601f19603f3d011682016040523d82523d6000602084013e61193a565b606091505b5080516119595760405162461bcd60e51b815260040161046990611e51565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610c3e565b506001610c3e565b3b151590565b6040518060a001604052806000815260200160006001600160a01b031681526020016060815260200160608152602001600081525090565b5080546119cd906124bf565b6000825580601f106119df57506119fd565b601f0160209004906000526020600020908101906119fd9190611a84565b50565b828054611a0c906124bf565b90600052602060002090601f016020900481019282611a2e5760008555611a74565b82601f10611a4757805160ff1916838001178555611a74565b82800160010185558215611a74579182015b82811115611a74578251825591602001919060010190611a59565b50611a80929150611a84565b5090565b5b80821115611a805760008155600101611a85565b600067ffffffffffffffff80841115611ab457611ab4612555565b604051601f8501601f191681016020018281118282101715611ad857611ad8612555565b604052848152915081838501861015611af057600080fd5b8484602083013760006020868301015250509392505050565b80356001600160a01b03811681146103ab57600080fd5b600082601f830112611b30578081fd5b6111a983833560208501611a99565b600060208284031215611b50578081fd5b6111a982611b09565b60008060408385031215611b6b578081fd5b611b7483611b09565b9150611b8260208401611b09565b90509250929050565b600080600060608486031215611b9f578081fd5b611ba884611b09565b9250611bb660208501611b09565b9150604084013590509250925092565b60008060008060808587031215611bdb578081fd5b611be485611b09565b9350611bf260208601611b09565b925060408501359150606085013567ffffffffffffffff811115611c14578182fd5b8501601f81018713611c24578182fd5b611c3387823560208401611a99565b91505092959194509250565b60008060408385031215611c51578182fd5b611c5a83611b09565b915060208301358015158114611c6e578182fd5b809150509250929050565b60008060008060808587031215611c8e578384fd5b611c9785611b09565b9350602085013567ffffffffffffffff80821115611cb3578485fd5b611cbf88838901611b20565b94506040870135915080821115611cd4578384fd5b50611ce187828801611b20565b949793965093946060013593505050565b60008060408385031215611d04578182fd5b611d0d83611b09565b946020939093013593505050565b600060208284031215611d2c578081fd5b81356111a98161256b565b600060208284031215611d48578081fd5b81516111a98161256b565b600060208284031215611d64578081fd5b5035919050565b60008151808452611d83816020860160208601612493565b601f01601f19169290920160200192915050565b60008251611da9818460208701612493565b9190910192915050565b60008351611dc5818460208801612493565b835190830190611dd9818360208801612493565b01949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611e2990830184611d6b565b9695505050505050565b901515815260200190565b6000602082526111a96020830184611d6b565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526022908201527f4b6f6b6f737761704e46543a2063726561746f7220646f65736e2774206578696040820152611cdd60f21b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b60208082526019908201527f4b6f6b6f737761704e46543a20626520612063726561746f7200000000000000604082015260600190565b60208082526022908201527f4b6f6b6f737761704e46543a2063726561746f7220616c7265616479206578696040820152611cdd60f21b606082015260800190565b6000602082528251602083015260018060a01b036020840151166040830152604083015160a060608401526123fa60c0840182611d6b565b90506060840151601f198483030160808501526124178282611d6b565b915050608084015160a08401528091505092915050565b90815260200190565b600083825260406020830152610c3e6040830184611d6b565b6000821982111561246357612463612529565b500190565b6000826124775761247761253f565b500490565b60008282101561248e5761248e612529565b500390565b60005b838110156124ae578181015183820152602001612496565b838111156110865750506000910152565b6002810460018216806124d357607f821691505b602082108114156124f457634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561250e5761250e612529565b5060010190565b6000826125245761252461253f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146119fd57600080fdfea2646970667358221220f9ca35254400a10b24f2dd787a6780542846510dfbb9e3523655310717a6bf7b64736f6c63430008000033

Deployed Bytecode Sourcemap

158:3234:14:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1522:292:4;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2454:100;;;:::i;:::-;;;;;;;:::i;3921:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3451:404::-;;;;;;:::i;:::-;;:::i;:::-;;2431:208:14;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;436:32::-;;;:::i;4811:305:4:-;;;;;;:::i;:::-;;:::i;2029:396:14:-;;;;;;:::i;:::-;;:::i;2768:214::-;;;;;;:::i;:::-;;:::i;5187:151:4:-;;;;;;:::i;:::-;;:::i;1268:753:14:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;533:729::-;;;;;;:::i;:::-;;:::i;2148:239:4:-;;;;;;:::i;:::-;;:::i;1878:208::-;;;;;;:::i;:::-;;:::i;1746:148:15:-;;;:::i;1095:87::-;;;:::i;2623:104:4:-;;;:::i;4214:295::-;;;;;;:::i;:::-;;:::i;5409:285::-;;;;;;:::i;:::-;;:::i;2987:219:14:-;;;;;;:::i;:::-;;:::i;2798:360:4:-;;;;;;:::i;:::-;;:::i;3216:165:14:-;;;;;;:::i;:::-;;:::i;4580:164:4:-;;;;;;:::i;:::-;;:::i;2645:116:14:-;;;;;;:::i;:::-;;:::i;2049:244:15:-;;;;;;:::i;:::-;;:::i;1522:292:4:-;1624:4;-1:-1:-1;;;;;;1648:40:4;;-1:-1:-1;;;1648:40:4;;:105;;-1:-1:-1;;;;;;;1705:48:4;;-1:-1:-1;;;1705:48:4;1648:105;:158;;;;1770:36;1794:11;1770:23;:36::i;:::-;1641:165;;1522:292;;;;:::o;2454:100::-;2508:13;2541:5;2534:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2454:100;:::o;3921:221::-;3997:7;4025:16;4033:7;4025;:16::i;:::-;4017:73;;;;-1:-1:-1;;;4017:73:4;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;4110:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;4110:24:4;;3921:221::o;3451:404::-;3532:13;3548:23;3563:7;3548:14;:23::i;:::-;3532:39;;3596:5;-1:-1:-1;;;;;3590:11:4;:2;-1:-1:-1;;;;;3590:11:4;;;3582:57;;;;-1:-1:-1;;;3582:57:4;;;;;;;:::i;:::-;3676:5;-1:-1:-1;;;;;3660:21:4;:12;:10;:12::i;:::-;-1:-1:-1;;;;;3660:21:4;;:69;;;;3685:44;3709:5;3716:12;:10;:12::i;3685:44::-;3652:161;;;;-1:-1:-1;;;3652:161:4;;;;;;;:::i;:::-;3826:21;3835:2;3839:7;3826:8;:21::i;:::-;3451:404;;;:::o;2431:208:14:-;2498:14;;:::i;:::-;2532:16;2540:7;2532;:16::i;:::-;2523:75;;;;-1:-1:-1;;;2523:75:14;;;;;;;:::i;:::-;2615:17;;;;:8;:17;;;;;;;;;2608:24;;;;;;;;;;;;;;;-1:-1:-1;;;;;2608:24:14;;;;;;;;;;;;;;;2615:17;;2608:24;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2431:208;;;:::o;436:32::-;;;-1:-1:-1;;;;;436:32:14;;:::o;4811:305:4:-;4972:41;4991:12;:10;:12::i;:::-;5005:7;4972:18;:41::i;:::-;4964:103;;;;-1:-1:-1;;;4964:103:4;;;;;;;:::i;:::-;5080:28;5090:4;5096:2;5100:7;5080:9;:28::i;2029:396:14:-;2087:4;2110:41;2129:12;:10;:12::i;:::-;2143:7;2110:18;:41::i;:::-;2102:102;;;;-1:-1:-1;;;2102:102:14;;;;;;;:::i;:::-;2214:22;2239:17;;;:8;:17;;;;;;;;2214:42;;;;;;;;;;;;;;;-1:-1:-1;;;;;2214:42:14;;;;;;;;;;;;;2239:17;;2214:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2214:42:14;;;-1:-1:-1;;2214:42:14;;;;;;;;;;;-1:-1:-1;2274:17:14;;;:8;:17;;;;;;2267:24;;;;;;;;-1:-1:-1;;;;;;2267:24:14;;;2214:42;;-1:-1:-1;2267:24:14;;;;-1:-1:-1;2267:24:14;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;2308:6;2315:7;:16;;;2308:24;;;;;;:::i;:::-;;;;;;;;;;;;;;;2301:31;;-1:-1:-1;;2301:31:14;;;2356:15;;;2349:6;;:23;;2356:15;2349:23;:::i;:::-;;;;;;;;;;;;;;2342:30;;-1:-1:-1;;2342:30:14;;;2382:14;2388:7;2382:5;:14::i;:::-;-1:-1:-1;2413:4:14;;2029:396;-1:-1:-1;;2029:396:14:o;2768:214::-;2839:4;1326:12:15;:10;:12::i;:::-;-1:-1:-1;;;;;1315:23:15;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1315:23:15;;1307:68;;;;-1:-1:-1;;;1307:68:15;;;;;;;:::i;:::-;-1:-1:-1;;;;;2862:17:14;::::1;;::::0;;;:8:::1;:17;::::0;;;;;::::1;;::::0;:22:::1;;2854:69;;;;-1:-1:-1::0;;;2854:69:14::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;2933:17:14::1;;::::0;;;:8:::1;:17;::::0;;;;:21;;-1:-1:-1;;2933:21:14::1;2953:1;2933:21:::0;;::::1;::::0;;;2953:1;2768:214::o;5187:151:4:-;5291:39;5308:4;5314:2;5318:7;5291:39;;;;;;;;;;;;:16;:39::i;1268:753:14:-;1405:7;1441:6;1448:8;1441:16;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:21;;1433:30;;;;;;1481:6;1488:7;1481:15;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:20;;1473:29;;;;;;1529:10;1520:20;;;;:8;:20;;;;;;;;;:25;1512:63;;;;-1:-1:-1;;;1512:63:14;;;;;;;:::i;:::-;1604:2;1593:7;:13;;1585:22;;;;;;1637:1;1618:6;1625:8;1618:16;;;;;;:::i;:::-;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;1666:1;1648:6;1655:7;1648:15;;;;;;:::i;:::-;;;;;;;;;;;;;;:19;;;;;;;-1:-1:-1;;1648:19:14;;;;;;;;;1684:21;:9;:19;:21::i;:::-;1715:17;1735:19;:9;:17;:19::i;:::-;1786:64;;;;;;;;1794:15;1786:64;;1811:10;1786:64;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1764:19:14;;;:8;:19;;;;;;:86;;;;;;;;;;;-1:-1:-1;;;;;;1764:86:14;-1:-1:-1;;;;;1764:86:14;;;;;;;;;;;;;:19;;-1:-1:-1;1786:64:14;;1764:19;;:86;;;;;;;;;;:::i;:::-;-1:-1:-1;1764:86:14;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1860:27;1866:9;1877;1860:5;:27::i;:::-;1908:9;-1:-1:-1;;;;;1903:35:14;;1919:9;1930:7;1903:35;;;;;;;:::i;:::-;;;;;;;;1957:17;;1948:38;;-1:-1:-1;;;;;1957:17:14;1976:9;1948:8;:38::i;:::-;2004:9;-1:-1:-1;1268:753:14;;;;;;;:::o;533:729::-;660:7;687:6;694:8;687:16;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:21;;679:30;;;;;;727:6;734:7;727:15;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:20;;719:29;;;;;;775:10;766:20;;;;:8;:20;;;;;;;;;:25;758:63;;;;-1:-1:-1;;;758:63:14;;;;;;;:::i;:::-;850:2;839:7;:13;;831:22;;;;;;883:1;864:6;871:8;864:16;;;;;;:::i;:::-;;;;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;912:1;894:6;901:7;894:15;;;;;;:::i;:::-;;;;;;;;;;;;;;:19;;;;;;;-1:-1:-1;;894:19:14;;;;;;;;;930:21;:9;:19;:21::i;:::-;961:17;981:19;:9;:17;:19::i;:::-;1032:64;;;;;;;;1040:15;1032:64;;1057:10;1032:64;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1010:19:14;;;:8;:19;;;;;;:86;;;;;;;;;;;-1:-1:-1;;;;;;1010:86:14;-1:-1:-1;;;;;1010:86:14;;;;;;;;;;;;;:19;;-1:-1:-1;1032:64:14;;1010:19;;:86;;;;;;;;;;:::i;:::-;-1:-1:-1;1010:86:14;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1106:27;1112:9;1123;1106:5;:27::i;:::-;1198:9;-1:-1:-1;;;;;1193:35:14;;1209:9;1220:7;1193:35;;;;;;;:::i;:::-;;;;;;;;1245:9;533:729;-1:-1:-1;;;;;533:729:14:o;2148:239:4:-;2220:7;2256:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2256:16:4;2291:19;2283:73;;;;-1:-1:-1;;;2283:73:4;;;;;;;:::i;1878:208::-;1950:7;-1:-1:-1;;;;;1978:19:4;;1970:74;;;;-1:-1:-1;;;1970:74:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;;2062:16:4;;;;;:9;:16;;;;;;;1878:208::o;1746:148:15:-;1326:12;:10;:12::i;:::-;-1:-1:-1;;;;;1315:23:15;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1315:23:15;;1307:68;;;;-1:-1:-1;;;1307:68:15;;;;;;;:::i;:::-;1837:6:::1;::::0;1816:40:::1;::::0;1853:1:::1;::::0;-1:-1:-1;;;;;1837:6:15::1;::::0;1816:40:::1;::::0;1853:1;;1816:40:::1;1867:6;:19:::0;;-1:-1:-1;;;;;;1867:19:15::1;::::0;;1746:148::o;1095:87::-;1168:6;;-1:-1:-1;;;;;1168:6:15;1095:87;:::o;2623:104:4:-;2679:13;2712:7;2705:14;;;;;:::i;4214:295::-;4329:12;:10;:12::i;:::-;-1:-1:-1;;;;;4317:24:4;:8;-1:-1:-1;;;;;4317:24:4;;;4309:62;;;;-1:-1:-1;;;4309:62:4;;;;;;;:::i;:::-;4429:8;4384:18;:32;4403:12;:10;:12::i;:::-;-1:-1:-1;;;;;4384:32:4;;;;;;;;;;;;;;;;;-1:-1:-1;4384:32:4;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;4384:53:4;;;;;;;;;;;4468:12;:10;:12::i;:::-;-1:-1:-1;;;;;4453:48:4;;4492:8;4453:48;;;;;;:::i;:::-;;;;;;;;4214:295;;:::o;5409:285::-;5541:41;5560:12;:10;:12::i;5541:41::-;5533:103;;;;-1:-1:-1;;;5533:103:4;;;;;;;:::i;:::-;5647:39;5661:4;5667:2;5671:7;5680:5;5647:13;:39::i;:::-;5409:285;;;;:::o;2987:219:14:-;3063:4;1326:12:15;:10;:12::i;:::-;-1:-1:-1;;;;;1315:23:15;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1315:23:15;;1307:68;;;;-1:-1:-1;;;1307:68:15;;;;;;;:::i;:::-;-1:-1:-1;;;;;3086:17:14;::::1;;::::0;;;:8:::1;:17;::::0;;;;;::::1;;::::0;:22:::1;3078:69;;;;-1:-1:-1::0;;;3078:69:14::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;3157:17:14::1;3177:1;3157:17:::0;;;:8:::1;:17;::::0;;;;:21;;-1:-1:-1;;3157:21:14::1;::::0;;-1:-1:-1;;2987:219:14:o;2798:360:4:-;2871:13;2905:16;2913:7;2905;:16::i;:::-;2897:76;;;;-1:-1:-1;;;2897:76:4;;;;;;;:::i;:::-;2986:21;3010:10;:8;:10::i;:::-;2986:34;;3062:1;3044:7;3038:21;:25;:112;;;;;;;;;;;;;;;;;3103:7;3112:18;:7;:16;:18::i;:::-;3086:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3038:112;3031:119;2798:360;-1:-1:-1;;;2798:360:4:o;3216:165:14:-;3305:4;1326:12:15;:10;:12::i;:::-;-1:-1:-1;;;;;1315:23:15;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1315:23:15;;1307:68;;;;-1:-1:-1;;;1307:68:15;;;;;;;:::i;:::-;-1:-1:-1;3319:17:14::1;:34:::0;;-1:-1:-1;;;;;3319:34:14;::::1;-1:-1:-1::0;;;;;;3319:34:14;;::::1;;::::0;;;3216:165;;;:::o;4580:164:4:-;-1:-1:-1;;;;;4701:25:4;;;4677:4;4701:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4580:164::o;2645:116:14:-;-1:-1:-1;;;;;2732:17:14;2710:4;2732:17;;;:8;:17;;;;;;;;;:22;;2645:116::o;2049:244:15:-;1326:12;:10;:12::i;:::-;-1:-1:-1;;;;;1315:23:15;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1315:23:15;;1307:68;;;;-1:-1:-1;;;1307:68:15;;;;;;;:::i;:::-;-1:-1:-1;;;;;2138:22:15;::::1;2130:73;;;;-1:-1:-1::0;;;2130:73:15::1;;;;;;;:::i;:::-;2240:6;::::0;2219:38:::1;::::0;-1:-1:-1;;;;;2219:38:15;;::::1;::::0;2240:6:::1;::::0;2219:38:::1;::::0;2240:6:::1;::::0;2219:38:::1;2268:6;:17:::0;;-1:-1:-1;;;;;;2268:17:15::1;-1:-1:-1::0;;;;;2268:17:15;;;::::1;::::0;;;::::1;::::0;;2049:244::o;787:157:3:-;-1:-1:-1;;;;;;896:40:3;;-1:-1:-1;;;896:40:3;787:157;;;:::o;7161:127:4:-;7226:4;7250:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7250:16:4;:30;;;7161:127::o;601:98:1:-;681:10;601:98;:::o;11045:174:4:-;11120:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;11120:29:4;-1:-1:-1;;;;;11120:29:4;;;;;;;;:24;;11174:23;11120:24;11174:14;:23::i;:::-;-1:-1:-1;;;;;11165:46:4;;;;;;;;;;;11045:174;;:::o;7455:355::-;7548:4;7573:16;7581:7;7573;:16::i;:::-;7565:73;;;;-1:-1:-1;;;7565:73:4;;;;;;;:::i;:::-;7649:13;7665:23;7680:7;7665:14;:23::i;:::-;7649:39;;7718:5;-1:-1:-1;;;;;7707:16:4;:7;-1:-1:-1;;;;;7707:16:4;;:51;;;;7751:7;-1:-1:-1;;;;;7727:31:4;:20;7739:7;7727:11;:20::i;:::-;-1:-1:-1;;;;;7727:31:4;;7707:51;:94;;;;7762:39;7786:5;7793:7;7762:23;:39::i;10383:544::-;10508:4;-1:-1:-1;;;;;10481:31:4;:23;10496:7;10481:14;:23::i;:::-;-1:-1:-1;;;;;10481:31:4;;10473:85;;;;-1:-1:-1;;;10473:85:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;10577:16:4;;10569:65;;;;-1:-1:-1;;;10569:65:4;;;;;;;:::i;:::-;10647:39;10668:4;10674:2;10678:7;10647:20;:39::i;:::-;10751:29;10768:1;10772:7;10751:8;:29::i;:::-;-1:-1:-1;;;;;10793:15:4;;;;;;:9;:15;;;;;:20;;10812:1;;10793:15;:20;;10812:1;;10793:20;:::i;:::-;;;;-1:-1:-1;;;;;;;10824:13:4;;;;;;:9;:13;;;;;:18;;10841:1;;10824:13;:18;;10841:1;;10824:18;:::i;:::-;;;;-1:-1:-1;;10853:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10853:21:4;-1:-1:-1;;;;;10853:21:4;;;;;;;;;10892:27;;10853:16;;10892:27;;;;;;;10383:544;;;:::o;9686:360::-;9746:13;9762:23;9777:7;9762:14;:23::i;:::-;9746:39;;9798:48;9819:5;9834:1;9838:7;9798:20;:48::i;:::-;9887:29;9904:1;9908:7;9887:8;:29::i;:::-;-1:-1:-1;;;;;9929:16:4;;;;;;:9;:16;;;;;:21;;9949:1;;9929:16;:21;;9949:1;;9929:21;:::i;:::-;;;;-1:-1:-1;;9968:16:4;;;;:7;:16;;;;;;9961:23;;-1:-1:-1;;;;;;9961:23:4;;;10002:36;9976:7;;9968:16;-1:-1:-1;;;;;10002:36:4;;;;;9968:16;;10002:36;9686:360;;:::o;915:127:2:-;1004:19;;1022:1;1004:19;;;915:127::o;793:114::-;885:14;;793:114::o;9075:382:4:-;-1:-1:-1;;;;;9155:16:4;;9147:61;;;;-1:-1:-1;;;9147:61:4;;;;;;;:::i;:::-;9228:16;9236:7;9228;:16::i;:::-;9227:17;9219:58;;;;-1:-1:-1;;;9219:58:4;;;;;;;:::i;:::-;9290:45;9319:1;9323:2;9327:7;9290:20;:45::i;:::-;-1:-1:-1;;;;;9348:13:4;;;;;;:9;:13;;;;;:18;;9365:1;;9348:13;:18;;9365:1;;9348:18;:::i;:::-;;;;-1:-1:-1;;9377:16:4;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9377:21:4;-1:-1:-1;;;;;9377:21:4;;;;;;;;9416:33;;9377:16;;;9416:33;;9377:16;;9416:33;9075:382;;:::o;6576:272::-;6690:28;6700:4;6706:2;6710:7;6690:9;:28::i;:::-;6737:48;6760:4;6766:2;6770:7;6779:5;6737:22;:48::i;:::-;6729:111;;;;-1:-1:-1;;;6729:111:4;;;;;;;:::i;3295:94::-;3372:9;;;;;;;;;-1:-1:-1;3372:9:4;;3295:94;:::o;284:723:17:-;340:13;561:10;557:53;;-1:-1:-1;588:10:17;;;;;;;;;;;;-1:-1:-1;;;588:10:17;;;;;;557:53;635:5;620:12;676:78;683:9;;676:78;;709:8;;;;:::i;:::-;;-1:-1:-1;732:10:17;;-1:-1:-1;740:2:17;732:10;;:::i;:::-;;;676:78;;;764:19;796:6;786:17;;;;;;-1:-1:-1;;;786:17:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;786:17:17;;764:39;;814:154;821:10;;814:154;;848:11;858:1;848:11;;:::i;:::-;;-1:-1:-1;917:10:17;925:2;917:5;:10;:::i;:::-;904:24;;:2;:24;:::i;:::-;891:39;;874:6;881;874:14;;;;;;-1:-1:-1;;;874:14:17;;;;;;;;;;;;:56;-1:-1:-1;;;;;874:56:17;;;;;;;;-1:-1:-1;945:11:17;954:2;945:11;;:::i;:::-;;;814:154;;11784:843:4;11905:4;11931:15;:2;-1:-1:-1;;;;;11931:13:4;;:15::i;:::-;11927:693;;;11983:2;-1:-1:-1;;;;;11967:36:4;;12004:12;:10;:12::i;:::-;12018:4;12024:7;12033:5;11967:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11967:72:4;;;;;;;;-1:-1:-1;;11967:72:4;;;;;;;;;;;;:::i;:::-;;;11963:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12213:13:4;;12209:341;;12256:60;;-1:-1:-1;;;12256:60:4;;;;;;;:::i;12209:341::-;12500:6;12494:13;12485:6;12481:2;12477:15;12470:38;11963:602;-1:-1:-1;;;;;;12090:55:4;-1:-1:-1;;;12090:55:4;;-1:-1:-1;12083:62:4;;11927:693;-1:-1:-1;12604:4:4;12597:11;;743:422:0;1110:20;1149:8;;;743:422::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:607:18;;110:18;151:2;143:6;140:14;137:2;;;157:18;;:::i;:::-;206:2;200:9;279:2;256:17;;-1:-1:-1;;252:31:18;240:44;;286:4;236:55;306:18;;;326:22;;;303:46;300:2;;;352:18;;:::i;:::-;388:2;381:22;436;;;421:6;-1:-1:-1;421:6:18;473:16;;;470:25;-1:-1:-1;467:2:18;;;508:1;505;498:12;467:2;558:6;553:3;546:4;538:6;534:17;521:44;613:1;606:4;597:6;589;585:19;581:30;574:41;;;90:531;;;;;:::o;626:175::-;696:20;;-1:-1:-1;;;;;745:31:18;;735:42;;725:2;;791:1;788;781:12;806:233;;904:3;897:4;889:6;885:17;881:27;871:2;;926:5;919;912:20;871:2;952:81;1029:3;1020:6;1007:20;1000:4;992:6;988:17;952:81;:::i;1044:198::-;;1156:2;1144:9;1135:7;1131:23;1127:32;1124:2;;;1177:6;1169;1162:22;1124:2;1205:31;1226:9;1205:31;:::i;1247:274::-;;;1376:2;1364:9;1355:7;1351:23;1347:32;1344:2;;;1397:6;1389;1382:22;1344:2;1425:31;1446:9;1425:31;:::i;:::-;1415:41;;1475:40;1511:2;1500:9;1496:18;1475:40;:::i;:::-;1465:50;;1334:187;;;;;:::o;1526:342::-;;;;1672:2;1660:9;1651:7;1647:23;1643:32;1640:2;;;1693:6;1685;1678:22;1640:2;1721:31;1742:9;1721:31;:::i;:::-;1711:41;;1771:40;1807:2;1796:9;1792:18;1771:40;:::i;:::-;1761:50;;1858:2;1847:9;1843:18;1830:32;1820:42;;1630:238;;;;;:::o;1873:702::-;;;;;2045:3;2033:9;2024:7;2020:23;2016:33;2013:2;;;2067:6;2059;2052:22;2013:2;2095:31;2116:9;2095:31;:::i;:::-;2085:41;;2145:40;2181:2;2170:9;2166:18;2145:40;:::i;:::-;2135:50;;2232:2;2221:9;2217:18;2204:32;2194:42;;2287:2;2276:9;2272:18;2259:32;2314:18;2306:6;2303:30;2300:2;;;2351:6;2343;2336:22;2300:2;2379:22;;2432:4;2424:13;;2420:27;-1:-1:-1;2410:2:18;;2466:6;2458;2451:22;2410:2;2494:75;2561:7;2556:2;2543:16;2538:2;2534;2530:11;2494:75;:::i;:::-;2484:85;;;2003:572;;;;;;;:::o;2580:369::-;;;2706:2;2694:9;2685:7;2681:23;2677:32;2674:2;;;2727:6;2719;2712:22;2674:2;2755:31;2776:9;2755:31;:::i;:::-;2745:41;;2836:2;2825:9;2821:18;2808:32;2883:5;2876:13;2869:21;2862:5;2859:32;2849:2;;2910:6;2902;2895:22;2849:2;2938:5;2928:15;;;2664:285;;;;;:::o;2954:722::-;;;;;3137:3;3125:9;3116:7;3112:23;3108:33;3105:2;;;3159:6;3151;3144:22;3105:2;3187:31;3208:9;3187:31;:::i;:::-;3177:41;;3269:2;3258:9;3254:18;3241:32;3292:18;3333:2;3325:6;3322:14;3319:2;;;3354:6;3346;3339:22;3319:2;3382:52;3426:7;3417:6;3406:9;3402:22;3382:52;:::i;:::-;3372:62;;3487:2;3476:9;3472:18;3459:32;3443:48;;3516:2;3506:8;3503:16;3500:2;;;3537:6;3529;3522:22;3500:2;;3565:54;3611:7;3600:8;3589:9;3585:24;3565:54;:::i;:::-;3095:581;;;;-1:-1:-1;3555:64:18;;3666:2;3651:18;3638:32;;-1:-1:-1;;;3095:581:18:o;3681:266::-;;;3810:2;3798:9;3789:7;3785:23;3781:32;3778:2;;;3831:6;3823;3816:22;3778:2;3859:31;3880:9;3859:31;:::i;:::-;3849:41;3937:2;3922:18;;;;3909:32;;-1:-1:-1;;;3768:179:18:o;3952:257::-;;4063:2;4051:9;4042:7;4038:23;4034:32;4031:2;;;4084:6;4076;4069:22;4031:2;4128:9;4115:23;4147:32;4173:5;4147:32;:::i;4214:261::-;;4336:2;4324:9;4315:7;4311:23;4307:32;4304:2;;;4357:6;4349;4342:22;4304:2;4394:9;4388:16;4413:32;4439:5;4413:32;:::i;4480:190::-;;4592:2;4580:9;4571:7;4567:23;4563:32;4560:2;;;4613:6;4605;4598:22;4560:2;-1:-1:-1;4641:23:18;;4550:120;-1:-1:-1;4550:120:18:o;4675:259::-;;4756:5;4750:12;4783:6;4778:3;4771:19;4799:63;4855:6;4848:4;4843:3;4839:14;4832:4;4825:5;4821:16;4799:63;:::i;:::-;4916:2;4895:15;-1:-1:-1;;4891:29:18;4882:39;;;;4923:4;4878:50;;4726:208;-1:-1:-1;;4726:208:18:o;4939:276::-;;5108:6;5102:13;5124:53;5170:6;5165:3;5158:4;5150:6;5146:17;5124:53;:::i;:::-;5193:16;;;;;5078:137;-1:-1:-1;;5078:137:18:o;5220:470::-;;5437:6;5431:13;5453:53;5499:6;5494:3;5487:4;5479:6;5475:17;5453:53;:::i;:::-;5569:13;;5528:16;;;;5591:57;5569:13;5528:16;5625:4;5613:17;;5591:57;:::i;:::-;5664:20;;5407:283;-1:-1:-1;;;;5407:283:18:o;5695:203::-;-1:-1:-1;;;;;5859:32:18;;;;5841:51;;5829:2;5814:18;;5796:102::o;5903:490::-;-1:-1:-1;;;;;6172:15:18;;;6154:34;;6224:15;;6219:2;6204:18;;6197:43;6271:2;6256:18;;6249:34;;;6319:3;6314:2;6299:18;;6292:31;;;5903:490;;6340:47;;6367:19;;6359:6;6340:47;:::i;:::-;6332:55;6106:287;-1:-1:-1;;;;;;6106:287:18:o;6398:187::-;6563:14;;6556:22;6538:41;;6526:2;6511:18;;6493:92::o;6590:221::-;;6739:2;6728:9;6721:21;6759:46;6801:2;6790:9;6786:18;6778:6;6759:46;:::i;6816:414::-;7018:2;7000:21;;;7057:2;7037:18;;;7030:30;7096:34;7091:2;7076:18;;7069:62;-1:-1:-1;;;7162:2:18;7147:18;;7140:48;7220:3;7205:19;;6990:240::o;7235:402::-;7437:2;7419:21;;;7476:2;7456:18;;;7449:30;7515:34;7510:2;7495:18;;7488:62;-1:-1:-1;;;7581:2:18;7566:18;;7559:36;7627:3;7612:19;;7409:228::o;7642:352::-;7844:2;7826:21;;;7883:2;7863:18;;;7856:30;7922;7917:2;7902:18;;7895:58;7985:2;7970:18;;7816:178::o;7999:400::-;8201:2;8183:21;;;8240:2;8220:18;;;8213:30;8279:34;8274:2;8259:18;;8252:62;-1:-1:-1;;;8345:2:18;8330:18;;8323:34;8389:3;8374:19;;8173:226::o;8404:349::-;8606:2;8588:21;;;8645:2;8625:18;;;8618:30;8684:27;8679:2;8664:18;;8657:55;8744:2;8729:18;;8578:175::o;8758:408::-;8960:2;8942:21;;;8999:2;8979:18;;;8972:30;9038:34;9033:2;9018:18;;9011:62;-1:-1:-1;;;9104:2:18;9089:18;;9082:42;9156:3;9141:19;;8932:234::o;9171:398::-;9373:2;9355:21;;;9412:2;9392:18;;;9385:30;9451:34;9446:2;9431:18;;9424:62;-1:-1:-1;;;9517:2:18;9502:18;;9495:32;9559:3;9544:19;;9345:224::o;9574:420::-;9776:2;9758:21;;;9815:2;9795:18;;;9788:30;9854:34;9849:2;9834:18;;9827:62;9925:26;9920:2;9905:18;;9898:54;9984:3;9969:19;;9748:246::o;9999:406::-;10201:2;10183:21;;;10240:2;10220:18;;;10213:30;10279:34;10274:2;10259:18;;10252:62;-1:-1:-1;;;10345:2:18;10330:18;;10323:40;10395:3;10380:19;;10173:232::o;10410:405::-;10612:2;10594:21;;;10651:2;10631:18;;;10624:30;10690:34;10685:2;10670:18;;10663:62;-1:-1:-1;;;10756:2:18;10741:18;;10734:39;10805:3;10790:19;;10584:231::o;10820:356::-;11022:2;11004:21;;;11041:18;;;11034:30;11100:34;11095:2;11080:18;;11073:62;11167:2;11152:18;;10994:182::o;11181:408::-;11383:2;11365:21;;;11422:2;11402:18;;;11395:30;11461:34;11456:2;11441:18;;11434:62;-1:-1:-1;;;11527:2:18;11512:18;;11505:42;11579:3;11564:19;;11355:234::o;11594:356::-;11796:2;11778:21;;;11815:18;;;11808:30;11874:34;11869:2;11854:18;;11847:62;11941:2;11926:18;;11768:182::o;11955:405::-;12157:2;12139:21;;;12196:2;12176:18;;;12169:30;12235:34;12230:2;12215:18;;12208:62;-1:-1:-1;;;12301:2:18;12286:18;;12279:39;12350:3;12335:19;;12129:231::o;12365:411::-;12567:2;12549:21;;;12606:2;12586:18;;;12579:30;12645:34;12640:2;12625:18;;12618:62;-1:-1:-1;;;12711:2:18;12696:18;;12689:45;12766:3;12751:19;;12539:237::o;12781:397::-;12983:2;12965:21;;;13022:2;13002:18;;;12995:30;13061:34;13056:2;13041:18;;13034:62;-1:-1:-1;;;13127:2:18;13112:18;;13105:31;13168:3;13153:19;;12955:223::o;13183:413::-;13385:2;13367:21;;;13424:2;13404:18;;;13397:30;13463:34;13458:2;13443:18;;13436:62;-1:-1:-1;;;13529:2:18;13514:18;;13507:47;13586:3;13571:19;;13357:239::o;13601:412::-;13803:2;13785:21;;;13842:2;13822:18;;;13815:30;13881:34;13876:2;13861:18;;13854:62;-1:-1:-1;;;13947:2:18;13932:18;;13925:46;14003:3;13988:19;;13775:238::o;14018:349::-;14220:2;14202:21;;;14259:2;14239:18;;;14232:30;14298:27;14293:2;14278:18;;14271:55;14358:2;14343:18;;14192:175::o;14372:398::-;14574:2;14556:21;;;14613:2;14593:18;;;14586:30;14652:34;14647:2;14632:18;;14625:62;-1:-1:-1;;;14718:2:18;14703:18;;14696:32;14760:3;14745:19;;14546:224::o;14775:768::-;;14954:2;14943:9;14936:21;14999:6;14993:13;14988:2;14977:9;14973:18;14966:41;15088:1;15084;15079:3;15075:11;15071:19;15065:2;15057:6;15053:15;15047:22;15043:48;15038:2;15027:9;15023:18;15016:76;15139:2;15131:6;15127:15;15121:22;15179:4;15174:2;15163:9;15159:18;15152:32;15207:53;15255:3;15244:9;15240:19;15226:12;15207:53;:::i;:::-;15193:67;;15309:2;15301:6;15297:15;15291:22;15382:2;15378:7;15366:9;15358:6;15354:22;15350:36;15344:3;15333:9;15329:19;15322:65;15410:42;15445:6;15429:14;15410:42;:::i;:::-;15396:56;;;15508:3;15500:6;15496:16;15490:23;15483:4;15472:9;15468:20;15461:53;15531:6;15523:14;;;14926:617;;;;:::o;15548:177::-;15694:25;;;15682:2;15667:18;;15649:76::o;15730:292::-;;15907:6;15896:9;15889:25;15950:2;15945;15934:9;15930:18;15923:30;15970:46;16012:2;16001:9;15997:18;15989:6;15970:46;:::i;16027:128::-;;16098:1;16094:6;16091:1;16088:13;16085:2;;;16104:18;;:::i;:::-;-1:-1:-1;16140:9:18;;16075:80::o;16160:120::-;;16226:1;16216:2;;16231:18;;:::i;:::-;-1:-1:-1;16265:9:18;;16206:74::o;16285:125::-;;16353:1;16350;16347:8;16344:2;;;16358:18;;:::i;:::-;-1:-1:-1;16395:9:18;;16334:76::o;16415:258::-;16487:1;16497:113;16511:6;16508:1;16505:13;16497:113;;;16587:11;;;16581:18;16568:11;;;16561:39;16533:2;16526:10;16497:113;;;16628:6;16625:1;16622:13;16619:2;;;-1:-1:-1;;16663:1:18;16645:16;;16638:27;16468:205::o;16678:380::-;16763:1;16753:12;;16810:1;16800:12;;;16821:2;;16875:4;16867:6;16863:17;16853:27;;16821:2;16928;16920:6;16917:14;16897:18;16894:38;16891:2;;;16974:10;16969:3;16965:20;16962:1;16955:31;17009:4;17006:1;16999:15;17037:4;17034:1;17027:15;16891:2;;16733:325;;;:::o;17063:135::-;;-1:-1:-1;;17123:17:18;;17120:2;;;17143:18;;:::i;:::-;-1:-1:-1;17190:1:18;17179:13;;17110:88::o;17203:112::-;;17261:1;17251:2;;17266:18;;:::i;:::-;-1:-1:-1;17300:9:18;;17241:74::o;17320:127::-;17381:10;17376:3;17372:20;17369:1;17362:31;17412:4;17409:1;17402:15;17436:4;17433:1;17426:15;17452:127;17513:10;17508:3;17504:20;17501:1;17494:31;17544:4;17541:1;17534:15;17568:4;17565:1;17558:15;17584:127;17645:10;17640:3;17636:20;17633:1;17626:31;17676:4;17673:1;17666:15;17700:4;17697:1;17690:15;17716:133;-1:-1:-1;;;;;;17792:32:18;;17782:43;;17772:2;;17839:1;17836;17829:12

Swarm Source

ipfs://f9ca35254400a10b24f2dd787a6780542846510dfbb9e3523655310717a6bf7b
Loading...
Loading
Loading...
Loading
[ 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.