ETH Price: $3,501.44 (+2.11%)
Gas: 2 Gwei

Contract

0xaB8A9981E16839c5b99ec947899dF823e1d62717
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...154008992022-08-24 4:45:46695 days ago1661316346IN
0xaB8A9981...3e1d62717
0 ETH0.0002861810.04728403
0x60806040151363282022-07-13 20:09:08737 days ago1657742948IN
 Create: LandToken
0 ETH0.14558340

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LandToken

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, MIT license
File 1 of 25 : LandToken.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "hardhat/console.sol";

import { ERC165 } from "@solidstate/contracts/introspection/ERC165.sol";
import { IERC721 } from "@solidstate/contracts/token/ERC721/IERC721.sol";
//import { ERC1155NSBase, ERC1155NSBaseStorage } from "../token/ERC1155NS/base/ERC1155NSBase.sol";

import { OpenSeaProxyRegistry, LibOpenSeaProxy } from "../vendor/OpenSea/OpenSeaProxyRegistry.sol";
import { OpenSeaProxyStorage } from "../vendor/OpenSea/OpenSeaProxyStorage.sol";

import { MintRequest, MintManyRequest, SegmentCount } from "./LandTypes.sol";
import { LandInternal } from "./LandInternal.sol";

import { LandStorage } from "./LandStorage.sol";
import { LandPriceStorage } from "./LandPriceStorage.sol";

contract LandToken is LandInternal, ERC165 {
	function isApprovedForAll(address _owner, address operator) public view override returns (bool) {
		return _isApprovedForAll(_owner, operator);
	}

	function versionRecipient() external view virtual override returns (string memory) {
		return "2.2.5";
	}

	function canMint(MintRequest memory request, bytes calldata signature)
		public
		view
		mintActive
		onlyEOA
		returns (bool isValid)
	{
		require(_verifyMint(_hashMint(request), signature), "canMint: invalid signature");
		require(_msgSender() == request.to, "canMint: not buyer");
		// note: the timestamp is not exact, so do not rely on this for sub-block precision
		// note: https://docs.soliditylang.org/en/v0.8.14/cheatsheet.html?highlight=timestamp#global-variables
		// slither-disable-next-line timestamp
		// solhint-disable-next-line not-rely-on-time
		require(request.deadline > block.timestamp, "canMint: signature expired");
		return true;
	}

	function canMintMany(MintManyRequest memory request, bytes calldata signature)
		public
		view
		mintActive
		onlyEOA
		returns (bool isValid)
	{
		require(_verifyMint(_hashMintMany(request), signature), "canMintMany: invalid signature");
		require(_msgSender() == request.to, "canMintMany: not buyer");
		// slither-disable-next-line timestamp
		// solhint-disable-next-line not-rely-on-time
		require(request.deadline > block.timestamp, "canMintMany: signature expired");
		require(request.zones.length <= LandStorage._getZoneIndex(), "canMintMany: wrong index");
		return true;
	}

	/**
	 * Mint in a specific zone for a count
	 */
	function mint(MintRequest memory request, bytes calldata signature) external payable {
		require(canMint(request, signature), "mint: invalid");

		uint256 price = LandPriceStorage._getPrice(request.segmentId);
		require(msg.value == price * request.count, "mint: wrong price");

		_mintInternal(request);
	}

	/**
	 * mint using the discount price
	 */
	function mintDiscount(MintRequest memory request, bytes calldata signature) external payable {
		require(canMint(request, signature), "mintDiscount: invalid");
		require(_discountAllowed(_msgSender(), request.zoneId), "mintDiscount: invalid zone");

		uint256 price = LandPriceStorage._getDiscountPrice(request.zoneId, request.segmentId);
		require(msg.value == price * request.count, "mintDiscount: wrong price");

		_mintInternal(request);
	}

	/**
	 * Mint many. Expects an ordered array of zones & segment count quantities
	 */
	function mintMany(MintManyRequest memory request, bytes calldata signature) external payable {
		require(canMintMany(request, signature), "mintMany: invalid");

		SegmentCount memory segment = _getSegmentCounts(request);
		require(msg.value == _getCost(segment), "mintMany: wrong price");

		_mintManyInternal(request);
	}

	/**
	 * Mint many using the discount price where possible.
	 */
	function mintManyDiscount(MintManyRequest memory request, bytes calldata signature)
		external
		payable
	{
		require(canMintMany(request, signature), "mintManyDiscount: invalid");
		require(msg.value == _getCostDiscount(_msgSender(), request), "mintManyDiscount: wrong price");

		_mintManyInternal(request);
	}
}

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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

File 4 of 25 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

File 5 of 25 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165 } from './IERC165.sol';
import { ERC165Storage } from './ERC165Storage.sol';

/**
 * @title ERC165 implementation
 */
abstract contract ERC165 is IERC165 {
    using ERC165Storage for ERC165Storage.Layout;

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return ERC165Storage.layout().isSupportedInterface(interfaceId);
    }
}

File 6 of 25 : ERC165Storage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library ERC165Storage {
    struct Layout {
        mapping(bytes4 => bool) supportedInterfaces;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC165');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }

    function isSupportedInterface(Layout storage l, bytes4 interfaceId)
        internal
        view
        returns (bool)
    {
        return l.supportedInterfaces[interfaceId];
    }

    function setSupportedInterface(
        Layout storage l,
        bytes4 interfaceId,
        bool status
    ) internal {
        require(interfaceId != 0xffffffff, 'ERC165: invalid interface id');
        l.supportedInterfaces[interfaceId] = status;
    }
}

File 7 of 25 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title ERC165 interface registration interface
 * @dev see https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 {
    /**
     * @notice query whether contract has registered support for given interface
     * @param interfaceId interface id
     * @return bool whether interface is supported
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 8 of 25 : IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC1155Internal } from './IERC1155Internal.sol';
import { IERC165 } from '../../introspection/IERC165.sol';

/**
 * @title ERC1155 interface
 * @dev see https://github.com/ethereum/EIPs/issues/1155
 */
interface IERC1155 is IERC1155Internal, IERC165 {
    /**
     * @notice query the balance of given token held by given address
     * @param account address to query
     * @param id token to query
     * @return token balance
     */
    function balanceOf(address account, uint256 id)
        external
        view
        returns (uint256);

    /**
     * @notice query the balances of given tokens held by given addresses
     * @param accounts addresss to query
     * @param ids tokens to query
     * @return token balances
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @notice query approval status of given operator with respect to given address
     * @param account address to query for approval granted
     * @param operator address to query for approval received
     * @return whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(address account, address operator)
        external
        view
        returns (bool);

    /**
     * @notice grant approval to or revoke approval from given operator to spend held tokens
     * @param operator address whose approval status to update
     * @param status whether operator should be considered approved
     */
    function setApprovalForAll(address operator, bool status) external;

    /**
     * @notice transfer tokens between given addresses, checking for ERC1155Receiver implementation if applicable
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param id token ID
     * @param amount quantity of tokens to transfer
     * @param data data payload
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable
     * @param from sender of tokens
     * @param to receiver of tokens
     * @param ids list of token IDs
     * @param amounts list of quantities of tokens to transfer
     * @param data data payload
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 9 of 25 : IERC1155Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165 } from '../../introspection/IERC165.sol';

/**
 * @title Partial ERC1155 interface needed by internal functions
 */
interface IERC1155Internal {
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );

    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    event ApprovalForAll(
        address indexed account,
        address indexed operator,
        bool approved
    );
}

File 10 of 25 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165 } from '../../introspection/IERC165.sol';

/**
 * @title ERC1155 transfer receiver interface
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @notice validate receipt of ERC1155 transfer
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param id token ID received
     * @param value quantity of tokens received
     * @param data data payload
     * @return function's own selector if transfer is accepted
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @notice validate receipt of ERC1155 batch transfer
     * @param operator executor of transfer
     * @param from sender of tokens
     * @param ids token IDs received
     * @param values quantities of tokens received
     * @param data data payload
     * @return function's own selector if transfer is accepted
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 11 of 25 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165 } from '../../introspection/IERC165.sol';
import { IERC721Internal } from './IERC721Internal.sol';

/**
 * @title ERC721 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721 is IERC721Internal, IERC165 {
    /**
     * @notice query the balance of given address
     * @return balance quantity of tokens held
     */
    function balanceOf(address account) external view returns (uint256 balance);

    /**
     * @notice query the owner of given token
     * @param tokenId token to query
     * @return owner token owner
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     * @param data data payload
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice grant approval to given account to spend token
     * @param operator address to be approved
     * @param tokenId token to approve
     */
    function approve(address operator, uint256 tokenId) external payable;

    /**
     * @notice get approval status for given token
     * @param tokenId token to query
     * @return operator address approved to spend token
     */
    function getApproved(uint256 tokenId)
        external
        view
        returns (address operator);

    /**
     * @notice grant approval to or revoke approval from given account to spend all tokens held by sender
     * @param operator address to be approved
     * @param status approval status
     */
    function setApprovalForAll(address operator, bool status) external;

    /**
     * @notice query approval status of given operator with respect to given address
     * @param account address to query for approval granted
     * @param operator address to query for approval received
     * @return status whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(address account, address operator)
        external
        view
        returns (bool status);
}

File 12 of 25 : IERC721Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Partial ERC721 interface needed by internal functions
 */
interface IERC721Internal {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

    event Approval(
        address indexed owner,
        address indexed operator,
        uint256 indexed tokenId
    );

    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );
}

File 13 of 25 : LandInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "hardhat/console.sol";

import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { IERC721 } from "@solidstate/contracts/token/ERC721/IERC721.sol";

import { ERC1155NSBase } from "../token/ERC1155NS/base/ERC1155NSBase.sol";
import { ERC1155NSBaseStorage } from "../token/ERC1155NS/base/ERC1155NSBaseStorage.sol";

import { OpenSeaProxyRegistry, LibOpenSeaProxy } from "../vendor/OpenSea/OpenSeaProxyRegistry.sol";
import { OpenSeaProxyStorage } from "../vendor/OpenSea/OpenSeaProxyStorage.sol";

import { LandPriceStorage, SegmentPrice } from "./LandPriceStorage.sol";
import { LandStorage, Category, Segment, Zone } from "./LandStorage.sol";
import { MintRequest, MintManyRequest, MintState, SegmentCount } from "./LandTypes.sol";

abstract contract LandInternal is ERC1155NSBase {
	// only allow if mint is active
	modifier mintActive() {
		MintState state = MintState(LandStorage.layout().mintState);
		require(state == MintState.OPEN || state == MintState.PRESALE, "mintActive: not active");
		_;
	}

	// only allow externally owned accounts
	modifier onlyEOA() {
		require(tx.origin == msg.sender, "onlyEOA: caller is contract");
		_;
	}

	// determine if the user is allowed the discounted price for a specific zone
	function _discountAllowed(address to, uint8 zoneId) internal view returns (bool) {
		if (!LandPriceStorage._isDiscountable(zoneId)) {
			return false;
		}

		// ensure they own a lion
		if (
			zoneId == LandStorage._getIndexLionLands() &&
			IERC721(LandStorage.layout().lions).balanceOf(to) > 0
		) {
			return true;
		}
		return false;
	}

	function _isApprovedForAll(address _owner, address operator) public view returns (bool) {
		address proxy1155 = OpenSeaProxyStorage.layout().os1155Proxy;
		if (LibOpenSeaProxy._isApprovedForAll(proxy1155, _owner, operator)) {
			return true;
		}

		address proxy721 = OpenSeaProxyStorage.layout().os721Proxy;
		if (LibOpenSeaProxy._isApprovedForAll(proxy721, _owner, operator)) {
			return true;
		}

		if (LandStorage.layout().proxies[operator]) {
			return true;
		}
		return super.isApprovedForAll(_owner, operator);
	}

	// mint internally
	function _mintInternal(MintRequest memory request) internal {
		Zone memory zone = LandStorage._getZone(request.zoneId);
		Segment memory segment = LandStorage._getSegment(zone, request.segmentId);

		_mintSegment(request.count, segment);

		// update the storage
		LandStorage._addCount(request.zoneId, request.segmentId, request.count);
	}

	// mint many internally for a mint request
	function _mintManyInternal(MintManyRequest memory request) internal {
		for (uint8 i = 0; i < request.zones.length; i++) {
			uint8 zoneId = i + 1;
			SegmentCount memory segmentRequest = request.zones[i];
			_mintSegments(zoneId, segmentRequest);
		}
	}

	// mint all of the sgments in the segment count
	function _mintSegments(uint8 zoneId, SegmentCount memory count) internal {
		Zone memory zone = LandStorage._getZone(zoneId);

		if (count.countOne > 0) {
			_mintSegment(count.countOne, zone.one);
			LandStorage._addCount(zoneId, uint8(Category.ONExONE), count.countOne);
		}

		if (count.countTwo > 0) {
			_mintSegment(count.countTwo, zone.two);
			LandStorage._addCount(zoneId, uint8(Category.TWOxTWO), count.countTwo);
		}

		if (count.countThree > 0) {
			_mintSegment(count.countThree, zone.three);
			LandStorage._addCount(zoneId, uint8(Category.THREExTHREE), count.countThree);
		}

		if (count.countFour > 0) {
			_mintSegment(count.countFour, zone.four);
			LandStorage._addCount(zoneId, uint8(Category.SIXxSIX), count.countFour);
		}
	}

	// mint a specific segment
	function _mintSegment(uint16 amount, Segment memory segment) internal {
		require(amount > 0, "invalid amount");
		require(segment.count + amount <= segment.max, "sold out");

		uint64 start = segment.startIndex + segment.count;
		uint64 end = start + amount;

		_mintAsERC721(start, end);
	}

	// mint as an ERC721
	function _mintAsERC721(uint64 start, uint64 end) internal {
		unchecked {
			for (start; start < end; ) {
				// Since this is treated like a 721, the only valid assignment is 1
				// and since we don't allow smart contracts
				// we can just update the storage slot directly
				ERC1155NSBaseStorage.layout().balances[start][_msgSender()] = 1;
				emit TransferSingle(_msgSender(), address(0), _msgSender(), start, 1);
				start++;
			}
		}
	}

	// get the combined counts of each type for all requested segments
	function _getSegmentCounts(MintManyRequest memory request)
		internal
		pure
		returns (SegmentCount memory segment)
	{
		for (uint8 i = 0; i < request.zones.length; i++) {
			SegmentCount memory segmentRequest = request.zones[i];
			segment.countOne += segmentRequest.countOne;
			segment.countTwo += segmentRequest.countTwo;
			segment.countThree += segmentRequest.countThree;
			segment.countFour += segmentRequest.countFour;
		}
		return segment;
	}

	// get the cost for a segment (it may be the combined segment)
	function _getCost(SegmentCount memory segment) internal view returns (uint256) {
		SegmentPrice memory price = LandPriceStorage._getPrice();
		return _getCost(segment, price);
	}

	function _getCost(SegmentCount memory segment, SegmentPrice memory price)
		internal
		pure
		returns (uint256)
	{
		return
			(uint256(price.one) * segment.countOne) +
			(uint256(price.two) * segment.countTwo) +
			(uint256(price.three) * segment.countThree) +
			(uint256(price.four) * segment.countFour);
	}

	// get the discounted cost for a user and their request
	function _getCostDiscount(address to, MintManyRequest memory request)
		internal
		view
		returns (uint256)
	{
		SegmentPrice memory price = LandPriceStorage._getPrice();

		uint256 cost = 0;
		for (uint8 i = 0; i < request.zones.length; i++) {
			uint8 zoneId = i + 1;
			if (_discountAllowed(to, zoneId)) {
				// get the cost discount for a zoneId and a specific segment count request
				SegmentPrice memory discountPrice = LandPriceStorage._getDiscountPrice(zoneId);
				cost += _getCost(request.zones[i], discountPrice);
			} else {
				cost += _getCost((request.zones[i]), price);
			}
		}
		return cost;
	}

	// hash mint many using EIP-191. loops through the request hasing the previous iteration
	function _hashMintMany(MintManyRequest memory request) internal pure returns (bytes32) {
		bytes32 keccakHash = keccak256(abi.encodePacked(request.to, request.deadline));
		for (uint8 i = 0; i < request.zones.length; i++) {
			uint8 zoneId = i + 1;
			SegmentCount memory segmentRequest = request.zones[i];
			keccakHash = keccak256(
				abi.encodePacked(
					keccakHash,
					zoneId,
					segmentRequest.countOne,
					segmentRequest.countTwo,
					segmentRequest.countThree,
					segmentRequest.countFour
				)
			);
		}

		return ECDSA.toEthSignedMessageHash(keccakHash);
	}

	function _hashMint(MintRequest memory request) internal pure returns (bytes32) {
		return
			ECDSA.toEthSignedMessageHash(
				keccak256(
					abi.encodePacked(
						request.to,
						request.deadline,
						request.zoneId,
						request.segmentId,
						request.count
					)
				)
			);
	}

	function _verifyMint(bytes32 digest, bytes memory signature) internal view returns (bool) {
		return LandStorage.layout().signer == ECDSA.recover(digest, signature);
	}
}

File 14 of 25 : LandPriceStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { Category, SegmentPrice } from "./LandTypes.sol";

library LandPriceStorage {
	struct Layout {
		SegmentPrice price;
		mapping(uint8 => SegmentPrice) discountPrices;
	}

	bytes32 internal constant STORAGE_SLOT =
		keccak256("co.sportsmetaverse.contracts.storage.LandPriceStorage");

	function layout() internal pure returns (Layout storage l) {
		bytes32 slot = STORAGE_SLOT;
		assembly {
			l.slot := slot
		}
	}

	// Getters

	function _getDiscountPrice(uint8 zoneId) internal view returns (SegmentPrice storage) {
		return layout().discountPrices[zoneId];
	}

	function _getDiscountPrice(uint8 zoneId, uint8 category) internal view returns (uint64) {
		SegmentPrice memory price = layout().discountPrices[zoneId];
		return _getPrice(price, category);
	}

	function _getPrice() internal view returns (SegmentPrice storage) {
		return layout().price;
	}

	function _getPrice(uint8 category) internal view returns (uint64) {
		SegmentPrice storage price = layout().price;
		return _getPrice(price, category);
	}

	function _getPrice(SegmentPrice memory price, uint8 category) internal pure returns (uint64) {
		if (Category(category) == Category.ONExONE) {
			return price.one;
		}
		if (Category(category) == Category.TWOxTWO) {
			return price.two;
		}
		if (Category(category) == Category.THREExTHREE) {
			return price.three;
		}
		if (Category(category) == Category.SIXxSIX) {
			return price.four;
		}
		revert("_getPrice: wrong category");
	}

	// determine if a specific zone is discountable
	function _isDiscountable(uint8 zoneId) internal view returns (bool) {
		return
			layout().discountPrices[zoneId].one != 0 &&
			layout().discountPrices[zoneId].two != 0 &&
			layout().discountPrices[zoneId].three != 0 &&
			layout().discountPrices[zoneId].four != 0;
	}

	// Setters

	function _setDiscountPrice(uint8 zoneId, SegmentPrice memory price) internal {
		layout().discountPrices[zoneId] = price;
	}

	function _setPrice(SegmentPrice memory price) internal {
		layout().price = price;
	}
}

File 15 of 25 : LandStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { Category, Segment, Zone } from "./LandTypes.sol";

library LandStorage {
	struct Layout {
		uint8 mintState;
		address signer;
		address icons;
		address lions;
		uint8 zoneIndex;
		mapping(uint8 => Zone) zones;
		mapping(address => bool) proxies;
	}

	bytes32 internal constant STORAGE_SLOT =
		keccak256("co.sportsmetaverse.contracts.storage.LandStorage");

	function layout() internal pure returns (Layout storage l) {
		bytes32 slot = STORAGE_SLOT;
		// slither-disable-next-line timestamp
		// solhint-disable-next-line no-inline-assembly
		assembly {
			l.slot := slot
		}
	}

	// Adders

	// add the count of minted inventory to the zone segment
	function _addCount(
		uint8 zoneId,
		uint8 segmentId,
		uint16 count
	) internal {
		Zone storage zone = LandStorage.layout().zones[zoneId];
		Category category = Category(segmentId);

		if (category == Category.ONExONE) {
			zone.one.count += count;
		} else if (category == Category.TWOxTWO) {
			zone.two.count += count;
		} else if (category == Category.THREExTHREE) {
			zone.three.count += count;
		} else if (category == Category.SIXxSIX) {
			zone.four.count += count;
		}
	}

	function _addInventory(
		Zone storage zone,
		uint8 segmentId,
		uint16 count
	) internal {
		Category category = Category(segmentId);

		if (category == Category.ONExONE) {
			zone.one.max += count;
		} else if (category == Category.TWOxTWO) {
			zone.two.max += count;
		} else if (category == Category.THREExTHREE) {
			zone.three.max += count;
		} else if (category == Category.SIXxSIX) {
			zone.four.max += count;
		}
	}

	function _removeInventory(
		Zone storage zone,
		uint8 segmentId,
		uint16 count
	) internal {
		Category category = Category(segmentId);

		if (category == Category.ONExONE) {
			zone.one.max -= count;
		} else if (category == Category.TWOxTWO) {
			zone.two.max -= count;
		} else if (category == Category.THREExTHREE) {
			zone.three.max -= count;
		} else if (category == Category.SIXxSIX) {
			zone.four.max -= count;
		}
	}

	// add a new zone
	function _addZone(Zone memory zone) internal {
		uint8 index = _getZoneIndex();
		index += 1;
		_setZone(index, zone);
		_setZoneIndex(index);
	}

	// Getters

	// TODO: resolve the indicies in a way that does not
	// require a contract upgrade to add a named zone
	function _getIndexSportsCity() internal pure returns (uint8) {
		return 1;
	}

	function _getIndexLionLands() internal pure returns (uint8) {
		return 2;
	}

	// get a segment for a zoneId and segmentId
	function _getSegment(uint8 zoneId, uint8 segmentId)
		internal
		view
		returns (Segment memory segment)
	{
		Zone memory zone = _getZone(zoneId);
		return _getSegment(zone, segmentId);
	}

	// get a segment for a zone and segmentId
	function _getSegment(Zone memory zone, uint8 segmentId)
		internal
		pure
		returns (Segment memory segment)
	{
		Category category = Category(segmentId);
		if (category == Category.ONExONE) {
			return zone.one;
		}
		if (category == Category.TWOxTWO) {
			return zone.two;
		}
		if (category == Category.THREExTHREE) {
			return zone.three;
		}
		if (category == Category.SIXxSIX) {
			return zone.four;
		}
		revert("_getCategory: wrong category");
	}

	function _getSigner() internal view returns (address) {
		return layout().signer;
	}

	// get the current index of zones
	function _getZoneIndex() internal view returns (uint8) {
		return layout().zoneIndex;
	}

	// get a zone from storage
	function _getZone(uint8 zoneId) internal view returns (Zone storage) {
		return LandStorage.layout().zones[zoneId];
	}

	// Setters

	// set maximum available inventory
	// note setting to the current count effectively makes none available.
	function _setInventory(
		Zone storage zone,
		uint16 maxOne,
		uint16 maxTwo,
		uint16 maxThree,
		uint16 maxFour
	) internal {
		zone.one.max = maxOne;
		zone.two.max = maxTwo;
		zone.three.max = maxThree;
		zone.four.max = maxFour;
	}

	// set an approved proxy
	function _setProxy(address proxy, bool enabled) internal {
		layout().proxies[proxy] = enabled;
	}

	// set the account that can sign tgransactions
	function _setSigner(address signer) internal {
		layout().signer = signer;
	}

	function _setZone(uint8 zoneId, Zone memory zone) internal {
		layout().zones[zoneId] = zone;
	}

	function _setZoneIndex(uint8 index) internal {
		layout().zoneIndex = index;
	}

	function _isValidInventory(Segment memory segment, uint16 maxCount) internal pure returns (bool) {
		require(maxCount >= segment.count, "_isValidInventory: invalid");
		require(
			maxCount <= segment.endIndex - segment.startIndex - segment.count,
			"_isValidInventory: too much"
		);

		return true;
	}

	function _isValidSegment(Segment memory last, Segment memory incoming)
		internal
		pure
		returns (bool)
	{
		require(incoming.count == 0, "_isValidSegment: wrong count");
		require(incoming.startIndex == last.endIndex, "_isValidSegment: wrong start");
		require(incoming.startIndex <= incoming.endIndex, "_isValidSegment: wrong end");
		require(incoming.max <= incoming.endIndex - incoming.startIndex, "_isValidSegment: wrong max");
		return true;
	}
}

File 16 of 25 : LandTypes.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// Enums

enum MintState {
	CLOSED,
	PRESALE,
	OPEN
}

// item category
enum Category {
	UNKNOWN,
	ONExONE,
	TWOxTWO,
	THREExTHREE,
	SIXxSIX
}

// Data Types

// defines the valid range of token id's of a segment
struct Segment {
	uint16 count; // count of tokens minted in the segment
	uint16 max; // max available for the segment (make sure it doesnt overflow)
	uint24 startIndex; // starting index of the segment
	uint24 endIndex; // end index of the segment
}

// price per type
struct SegmentPrice {
	uint64 one; // 1x1
	uint64 two; // 2x2
	uint64 three; // 3x3
	uint64 four; // 6x6
}

// a zone is a specific area of land
struct Zone {
	Segment one; // 1x1
	Segment two; // 2x2
	Segment three; // 3x3
	Segment four; // 6x6
}

// Init Args

// initialization args for the proxy
struct LandInitArgs {
	address signer;
	address lions;
	address icons;
	SegmentPrice price;
	SegmentPrice lionsDiscountPrice;
	Zone zoneOne; // City
	Zone zoneTwo; // Lion
}

// requests

// request to mint a single item
struct MintRequest {
	address to;
	uint64 deadline; // block.timestamp
	uint8 zoneId;
	uint8 segmentId;
	uint16 count;
}

// request to mint many different types
// expects the SegmentCount array to be in index order
struct MintManyRequest {
	address to;
	uint64 deadline;
	SegmentCount[] zones;
}

// requested amount for a specific segment
struct SegmentCount {
	uint16 countOne; // 1x1
	uint16 countTwo; // 2x2
	uint16 countThree; // 3x3
	uint16 countFour; // 6x6
}

File 17 of 25 : ERC1155NSBase.sol
// SPDX-License-Identifier: MIT
// solhint-disable reason-string

pragma solidity ^0.8.0;

import { IERC1155 } from "@solidstate/contracts/token/ERC1155/IERC1155.sol";
import { IERC1155Receiver } from "@solidstate/contracts/token/ERC1155/IERC1155Receiver.sol";
import { ERC1155NSBaseInternal, ERC1155NSBaseStorage } from "./ERC1155NSBaseInternal.sol";

/**
 * @title Base ERC1155 contract
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 * and solid state, but uses _msgSender() so that contracts are supported
 */
abstract contract ERC1155NSBase is IERC1155, ERC1155NSBaseInternal {
	/**
	 * @inheritdoc IERC1155
	 */
	function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
		return _balanceOf(account, id);
	}

	/**
	 * @inheritdoc IERC1155
	 */
	function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
		public
		view
		virtual
		override
		returns (uint256[] memory)
	{
		require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

		mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155NSBaseStorage
			.layout()
			.balances;

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

		unchecked {
			for (uint256 i = 0; i < accounts.length; i++) {
				require(accounts[i] != address(0), "ERC1155: batch balance query for the zero address");
				batchBalances[i] = balances[ids[i]][accounts[i]];
			}
		}

		return batchBalances;
	}

	/**
	 * @inheritdoc IERC1155
	 */
	function isApprovedForAll(address account, address operator)
		public
		view
		virtual
		override
		returns (bool)
	{
		return ERC1155NSBaseStorage.layout().operatorApprovals[account][operator];
	}

	/**
	 * @inheritdoc IERC1155
	 */
	function setApprovalForAll(address operator, bool status) public virtual override {
		_setApprovalForAll(_msgSender(), operator, status);
	}

	/**
	 * @inheritdoc IERC1155
	 */
	function safeTransferFrom(
		address from,
		address to,
		uint256 id,
		uint256 amount,
		bytes memory data
	) public virtual override {
		require(
			from == _msgSender() || isApprovedForAll(from, _msgSender()),
			"ERC1155: caller is not owner nor approved"
		);
		_safeTransfer(_msgSender(), from, to, id, amount, data);
	}

	/**
	 * @inheritdoc IERC1155
	 */
	function safeBatchTransferFrom(
		address from,
		address to,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) public virtual override {
		require(
			from == _msgSender() || isApprovedForAll(from, _msgSender()),
			"ERC1155: caller is not owner nor approved"
		);
		_safeTransferBatch(_msgSender(), from, to, ids, amounts, data);
	}
}

File 18 of 25 : ERC1155NSBaseInternal.sol
// SPDX-License-Identifier: MIT
// solhint-disable reason-string

pragma solidity ^0.8.0;

import { Address } from "@openzeppelin/contracts/utils/Address.sol";

import { IERC1155Receiver } from "@solidstate/contracts/token/ERC1155/IERC1155Receiver.sol";
import { IERC1155Internal } from "@solidstate/contracts/token/ERC1155/IERC1155Internal.sol";

import { ERC2771Recipient } from "../../../vendor/ERC2771/ERC2771Recipient.sol";

import { ERC1155NSBaseStorage } from "./ERC1155NSBaseStorage.sol";

/**
 * @title Base ERC1155 internal functions
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
abstract contract ERC1155NSBaseInternal is ERC2771Recipient, IERC1155Internal {
	using Address for address;

	/**
	 * @notice query the balance of given token held by given address
	 * @param account address to query
	 * @param id token to query
	 * @return token balance
	 */
	function _balanceOf(address account, uint256 id) internal view virtual returns (uint256) {
		require(account != address(0), "ERC1155: balance query for the zero address");
		return ERC1155NSBaseStorage.layout().balances[id][account];
	}

	/**
	 * @notice transfer tokens between given addresses
	 * @dev ERC1155Receiver implementation is not checked
	 * @param operator executor of transfer
	 * @param from sender of tokens
	 * @param to receiver of tokens
	 * @param id token ID
	 * @param amount quantity of tokens to transfer
	 * @param data data payload
	 */
	function _transfer(
		address operator,
		address from,
		address to,
		uint256 id,
		uint256 amount,
		bytes memory data
	) internal virtual {
		require(to != address(0), "ERC1155: transfer to the zero address");

		uint256[] memory ids = _asSingletonArray(id);
		uint256[] memory amounts = _asSingletonArray(amount);

		_beforeTokenTransfer(
			operator,
			from,
			to,
			_asSingletonArray(id),
			_asSingletonArray(amount),
			data
		);

		mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155NSBaseStorage
			.layout()
			.balances;

		unchecked {
			uint256 fromBalance = balances[id][from];
			require(fromBalance >= amount, "ERC1155: insufficient balances for transfer");
			balances[id][from] = fromBalance - amount;
		}

		balances[id][to] += amount;

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

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

	/**
	 * @notice transfer tokens between given addresses
	 * @param operator executor of transfer
	 * @param sender sender of tokens
	 * @param recipient receiver of tokens
	 * @param id token ID
	 * @param amount quantity of tokens to transfer
	 * @param data data payload
	 */
	function _safeTransfer(
		address operator,
		address sender,
		address recipient,
		uint256 id,
		uint256 amount,
		bytes memory data
	) internal virtual {
		_transfer(operator, sender, recipient, id, amount, data);

		_doSafeTransferAcceptanceCheck(operator, sender, recipient, id, amount, data);
	}

	/**
	 * @notice transfer batch of tokens between given addresses
	 * @dev ERC1155Receiver implementation is not checked
	 * @param operator executor of transfer
	 * @param from sender of tokens
	 * @param to receiver of tokens
	 * @param ids token IDs
	 * @param amounts quantities of tokens to transfer
	 * @param data data payload
	 */
	function _transferBatch(
		address operator,
		address from,
		address to,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) internal virtual {
		require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
		require(to != address(0), "ERC1155: transfer to the zero address");

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

		mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155NSBaseStorage
			.layout()
			.balances;

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

			unchecked {
				uint256 fromBalance = balances[id][from];

				require(fromBalance >= amount, "ERC1155: insufficient balances for transfer");

				balances[id][from] = fromBalance - amount;

				i++;
			}

			// balance increase cannot be unchecked because ERC1155Base neither tracks nor validates a totalSupply
			balances[id][to] += amount;
		}

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

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

	/**
	 * @notice transfer batch of tokens between given addresses
	 * @param operator executor of transfer
	 * @param sender sender of tokens
	 * @param recipient receiver of tokens
	 * @param ids token IDs
	 * @param amounts quantities of tokens to transfer
	 * @param data data payload
	 */
	function _safeTransferBatch(
		address operator,
		address sender,
		address recipient,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) internal virtual {
		_transferBatch(operator, sender, recipient, ids, amounts, data);

		_doSafeBatchTransferAcceptanceCheck(operator, sender, recipient, ids, amounts, data);
	}

	/**
	 * @notice mint given quantity of tokens for given address
	 * @dev ERC1155Receiver implementation is not checked
	 * @param to beneficiary of minting
	 * @param id token ID
	 * @param amount quantity of tokens to mint
	 * @param data data payload
	 */
	function _mint(
		address to,
		uint256 id,
		uint256 amount,
		bytes memory data
	) internal virtual {
		require(to != address(0), "ERC1155: mint to the zero address");

		address operator = _msgSender();
		uint256[] memory ids = _asSingletonArray(id);
		uint256[] memory amounts = _asSingletonArray(amount);

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

		_unsafeMint(operator, to, id, amount);

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

	/**
	 * @notice mint given quantity of tokens for given address
	 * @param account beneficiary of minting
	 * @param id token ID
	 * @param amount quantity of tokens to mint
	 * @param data data payload
	 */
	function _safeMint(
		address account,
		uint256 id,
		uint256 amount,
		bytes memory data
	) internal virtual {
		_mint(account, id, amount, data);

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

	/**
	 * Mint without any safety checks or other function calls
	 */
	function _unsafeMint(
		address operator,
		address to,
		uint256 id,
		uint256 amount
	) internal virtual {
		ERC1155NSBaseStorage.layout().balances[id][to] += amount;
		emit TransferSingle(operator, address(0), to, id, amount);
	}

	/**
	 * @notice mint batch of tokens for given address
	 * @dev ERC1155Receiver implementation is not checked
	 * @param to beneficiary of minting
	 * @param ids list of token IDs
	 * @param amounts list of quantities of tokens to mint
	 * @param data data payload
	 */
	function _mintBatch(
		address to,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) internal virtual {
		require(to != address(0), "ERC1155: mint to the zero address");
		require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

		address operator = _msgSender();

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

		_unsafeMintBatch(operator, to, ids, amounts);

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

	/**
	 * @notice mint batch of tokens for given address
	 * @param account beneficiary of minting
	 * @param ids list of token IDs
	 * @param amounts list of quantities of tokens to mint
	 * @param data data payload
	 */
	function _safeMintBatch(
		address account,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) internal virtual {
		_mintBatch(account, ids, amounts, data);

		_doSafeBatchTransferAcceptanceCheck(_msgSender(), address(0), account, ids, amounts, data);
	}

	/**
	 * Mint without any safety checks or other function calls
	 */
	function _unsafeMintBatch(
		address operator,
		address to,
		uint256[] memory ids,
		uint256[] memory amounts
	) internal virtual {
		mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155NSBaseStorage
			.layout()
			.balances;

		for (uint256 i = 0; i < ids.length; ) {
			balances[ids[i]][to] += amounts[i];
			unchecked {
				i++;
			}
		}

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

	/**
	 * @notice burn given quantity of tokens held by given address
	 * @param from holder of tokens to burn
	 * @param id token ID
	 * @param amount quantity of tokens to burn
	 */
	function _burn(
		address from,
		uint256 id,
		uint256 amount
	) internal virtual {
		require(from != address(0), "ERC1155: burn from the zero address");

		address operator = _msgSender();
		uint256[] memory ids = _asSingletonArray(id);
		uint256[] memory amounts = _asSingletonArray(amount);

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

		mapping(address => uint256) storage balances = ERC1155NSBaseStorage.layout().balances[id];

		uint256 fromBalance = balances[from];
		unchecked {
			require(fromBalance >= amount, "ERC1155: burn amount exceeds balances");
			balances[from] = fromBalance - amount;
		}

		emit TransferSingle(_msgSender(), from, address(0), id, amount);

		_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
	}

	/**
	 * @notice burn given batch of tokens held by given address
	 * @param from holder of tokens to burn
	 * @param ids token IDs
	 * @param amounts quantities of tokens to burn
	 */
	function _burnBatch(
		address from,
		uint256[] memory ids,
		uint256[] memory amounts
	) internal virtual {
		require(from != address(0), "ERC1155: burn from the zero address");
		require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

		address operator = _msgSender();

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

		mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155NSBaseStorage
			.layout()
			.balances;

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

			uint256 fromBalance = balances[id][from];
			require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
			unchecked {
				balances[id][from] = fromBalance - amount;
			}
		}

		emit TransferBatch(_msgSender(), from, address(0), ids, amounts);

		_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
	}

	/**
	 * @dev Approve `operator` to operate on all of `owner` tokens
	 *
	 * Emits a {ApprovalForAll} event.
	 */
	function _setApprovalForAll(
		address owner,
		address operator,
		bool status
	) internal virtual {
		require(_msgSender() != operator, "ERC1155: setting approval status for self");
		ERC1155NSBaseStorage.layout().operatorApprovals[owner][operator] = status;
		emit ApprovalForAll(owner, operator, status);
	}

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

	/**
	 * @notice ERC1155 hook, called before all transfers including mint and burn
	 * @dev function should be overridden and new implementation must call super
	 * @dev called for both single and batch transfers
	 * @param operator executor of transfer
	 * @param from sender of tokens
	 * @param to receiver of tokens
	 * @param ids token IDs
	 * @param amounts quantities of tokens to transfer
	 * @param data data payload
	 */
	function _beforeTokenTransfer(
		address operator,
		address from,
		address to,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) internal virtual {}

	/**
	 * @notice revert if applicable transfer recipient is not valid ERC1155Receiver
	 * @param operator executor of transfer
	 * @param from sender of tokens
	 * @param to receiver of tokens
	 * @param id token ID
	 * @param amount quantity of tokens to transfer
	 * @param data data payload
	 */
	function _doSafeTransferAcceptanceCheck(
		address operator,
		address from,
		address to,
		uint256 id,
		uint256 amount,
		bytes memory data
	) private {
		if (to.isContract()) {
			try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (
				bytes4 response
			) {
				require(
					response == IERC1155Receiver.onERC1155Received.selector,
					"ERC1155: ERC1155Receiver rejected tokens"
				);
			} catch Error(string memory reason) {
				revert(reason);
			} catch {
				revert("ERC1155: transfer to non ERC1155Receiver implementer");
			}
		}
	}

	/**
	 * @notice revert if applicable transfer recipient is not valid ERC1155Receiver
	 * @param operator executor of transfer
	 * @param from sender of tokens
	 * @param to receiver of tokens
	 * @param ids token IDs
	 * @param amounts quantities of tokens to transfer
	 * @param data data payload
	 */
	function _doSafeBatchTransferAcceptanceCheck(
		address operator,
		address from,
		address to,
		uint256[] memory ids,
		uint256[] memory amounts,
		bytes memory data
	) private {
		if (to.isContract()) {
			try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
				bytes4 response
			) {
				require(
					response == IERC1155Receiver.onERC1155BatchReceived.selector,
					"ERC1155: ERC1155Receiver rejected tokens"
				);
			} catch Error(string memory reason) {
				revert(reason);
			} catch {
				revert("ERC1155: transfer to non ERC1155Receiver implementer");
			}
		}
	}

	/**
	 * @notice wrap given element in array of length 1
	 * @param element element to wrap
	 * @return singleton array
	 */
	function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
		uint256[] memory array = new uint256[](1);
		array[0] = element;
		return array;
	}
}

File 19 of 25 : ERC1155NSBaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library ERC1155NSBaseStorage {
	struct Layout {
		mapping(uint256 => mapping(address => uint256)) balances;
		mapping(address => mapping(address => bool)) operatorApprovals;
	}

	bytes32 internal constant STORAGE_SLOT =
		keccak256("co.sportsmetaverse.contracts.storage.ERC1155NSBaseStorage");

	function layout() internal pure returns (Layout storage l) {
		bytes32 slot = STORAGE_SLOT;
		// slither-disable-next-line timestamp
		// solhint-disable-next-line no-inline-assembly
		assembly {
			l.slot := slot
		}
	}
}

File 20 of 25 : ERC2771Recipient.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC2771Recipient } from "./IERC2771Recipient.sol";
import { ERC2771RecipientStorage } from "./ERC2771RecipientStorage.sol";

/**
 * @title The ERC-2771 Recipient Base Abstract Class - Implementation
 *
 * @notice Note that this contract was called `BaseRelayRecipient` in the previous revision of the GSN.
 *
 * @notice A base contract to be inherited by any contract that want to receive relayed transactions.
 *
 * @notice A subclass must use `_msgSender()` instead of `msg.sender`.
 */
abstract contract ERC2771Recipient is IERC2771Recipient {
	/**
	 * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.
	 * @notice Method is not a required method to allow Recipients to trust multiple Forwarders. Not recommended yet.
	 * @return forwarder The address of the Forwarder contract that is being used.
	 */
	function getTrustedForwarder() public view virtual returns (address forwarder) {
		return ERC2771RecipientStorage.layout().trustedForwarder;
	}

	function _setTrustedForwarder(address _forwarder) internal {
		ERC2771RecipientStorage.layout().trustedForwarder = _forwarder;
	}

	/// @inheritdoc IERC2771Recipient
	function isTrustedForwarder(address forwarder) public view virtual override returns (bool) {
		return forwarder == ERC2771RecipientStorage.layout().trustedForwarder;
	}

	/// @inheritdoc IERC2771Recipient
	function _msgSender() internal view virtual override returns (address ret) {
		if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {
			// At this point we know that the sender is a trusted forwarder,
			// so we trust that the last bytes of msg.data are the verified sender address.
			// extract sender address from the end of msg.data
			assembly {
				ret := shr(96, calldataload(sub(calldatasize(), 20)))
			}
		} else {
			ret = msg.sender;
		}
	}

	/// @inheritdoc IERC2771Recipient
	function _msgData() internal view virtual override returns (bytes calldata ret) {
		if (msg.data.length >= 20 && isTrustedForwarder(msg.sender)) {
			return msg.data[0:msg.data.length - 20];
		} else {
			return msg.data;
		}
	}
}

File 21 of 25 : ERC2771RecipientStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library ERC2771RecipientStorage {
	struct Layout {
		/*
		 * Forwarder singleton we accept calls from
		 */
		address trustedForwarder;
	}

	bytes32 internal constant STORAGE_SLOT =
		keccak256("IERC2771Recipient.contracts.storage.ERC2771RecipientStorage");

	function layout() internal pure returns (Layout storage l) {
		bytes32 slot = STORAGE_SLOT;
		// slither-disable-next-line timestamp
		// solhint-disable-next-line no-inline-assembly
		assembly {
			l.slot := slot
		}
	}
}

File 22 of 25 : IERC2771Recipient.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title The ERC-2771 Recipient Base Abstract Class - Declarations
 *
 * @notice A contract must implement this interface in order to support relayed transaction.
 *
 * @notice It is recommended that your contract inherits from the ERC2771Recipient contract.
 */
abstract contract IERC2771Recipient {
	/**
	 * :warning: **Warning** :warning: The Forwarder can have a full control over your Recipient. Only trust verified Forwarder.
	 * @param forwarder The address of the Forwarder contract that is being used.
	 * @return isTrustedForwarder `true` if the Forwarder is trusted to forward relayed transactions by this Recipient.
	 */
	function isTrustedForwarder(address forwarder) public view virtual returns (bool);

	/**
	 * @notice Use this method the contract anywhere instead of msg.sender to support relayed transactions.
	 * @return sender The real sender of this call.
	 * For a call that came through the Forwarder the real sender is extracted from the last 20 bytes of the `msg.data`.
	 * Otherwise simply returns `msg.sender`.
	 */
	function _msgSender() internal view virtual returns (address);

	/**
	 * @notice Use this method in the contract instead of `msg.data` when difference matters (hashing, signature, etc.)
	 * @return data The real `msg.data` of this call.
	 * For a call that came through the Forwarder, the real sender address was appended as the last 20 bytes
	 * of the `msg.data` - so this method will strip those 20 bytes off.
	 * Otherwise (if the call was made directly and not through the forwarder) simply returns `msg.data`.
	 */
	function _msgData() internal view virtual returns (bytes calldata);

	/**
	 * @return version The SemVer string of this Recipient's version.
	 */
	function versionRecipient() external view virtual returns (string memory);
}

File 23 of 25 : OpenSeaProxyRegistry.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract OwnableDelegateProxy {}

contract OpenSeaProxyRegistry {
	mapping(address => OwnableDelegateProxy) public proxies;
}

library LibOpenSeaProxy {
	function _isApprovedForAll(
		address registry,
		address _owner,
		address operator
	) internal view returns (bool) {
		OpenSeaProxyRegistry proxyRegistry = OpenSeaProxyRegistry(registry);
		return
			address(proxyRegistry) != address(0) && address(proxyRegistry.proxies(_owner)) == operator;
	}
}

File 24 of 25 : OpenSeaProxyStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

struct OpenSeaProxyInitArgs {
	address os721Proxy;
	address os1155Proxy;
}

library OpenSeaProxyStorage {
	struct Layout {
		address os721Proxy;
		address os1155Proxy;
	}

	bytes32 internal constant STORAGE_SLOT = keccak256("com.opensea.contracts.storage.proxy");

	function layout() internal pure returns (Layout storage l) {
		bytes32 slot = STORAGE_SLOT;
		// slither-disable-next-line timestamp
		// solhint-disable-next-line no-inline-assembly
		assembly {
			l.slot := slot
		}
	}

	function _setProxies(OpenSeaProxyInitArgs memory init) internal {
		_setProxies(init.os721Proxy, init.os1155Proxy);
	}

	function _setProxies(address os721Proxy, address os1155Proxy) internal {
		layout().os721Proxy = os721Proxy;
		layout().os1155Proxy = os1155Proxy;
	}
}

File 25 of 25 : console.sol
// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 <0.9.0;

library console {
	address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);

	function _sendLogPayload(bytes memory payload) private view {
		uint256 payloadLength = payload.length;
		address consoleAddress = CONSOLE_ADDRESS;
		assembly {
			let payloadStart := add(payload, 32)
			let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
		}
	}

	function log() internal view {
		_sendLogPayload(abi.encodeWithSignature("log()"));
	}

	function logInt(int p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
	}

	function logUint(uint p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
	}

	function logString(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function logBool(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function logAddress(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function logBytes(bytes memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
	}

	function logBytes1(bytes1 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
	}

	function logBytes2(bytes2 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
	}

	function logBytes3(bytes3 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
	}

	function logBytes4(bytes4 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
	}

	function logBytes5(bytes5 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
	}

	function logBytes6(bytes6 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
	}

	function logBytes7(bytes7 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
	}

	function logBytes8(bytes8 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
	}

	function logBytes9(bytes9 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
	}

	function logBytes10(bytes10 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
	}

	function logBytes11(bytes11 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
	}

	function logBytes12(bytes12 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
	}

	function logBytes13(bytes13 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
	}

	function logBytes14(bytes14 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
	}

	function logBytes15(bytes15 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
	}

	function logBytes16(bytes16 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
	}

	function logBytes17(bytes17 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
	}

	function logBytes18(bytes18 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
	}

	function logBytes19(bytes19 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
	}

	function logBytes20(bytes20 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
	}

	function logBytes21(bytes21 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
	}

	function logBytes22(bytes22 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
	}

	function logBytes23(bytes23 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
	}

	function logBytes24(bytes24 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
	}

	function logBytes25(bytes25 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
	}

	function logBytes26(bytes26 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
	}

	function logBytes27(bytes27 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
	}

	function logBytes28(bytes28 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
	}

	function logBytes29(bytes29 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
	}

	function logBytes30(bytes30 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
	}

	function logBytes31(bytes31 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
	}

	function logBytes32(bytes32 p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
	}

	function log(uint p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
	}

	function log(string memory p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
	}

	function log(bool p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
	}

	function log(address p0) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
	}

	function log(uint p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
	}

	function log(uint p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
	}

	function log(uint p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
	}

	function log(uint p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
	}

	function log(string memory p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
	}

	function log(string memory p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
	}

	function log(string memory p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
	}

	function log(string memory p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
	}

	function log(bool p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
	}

	function log(bool p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
	}

	function log(bool p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
	}

	function log(bool p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
	}

	function log(address p0, uint p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
	}

	function log(address p0, string memory p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
	}

	function log(address p0, bool p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
	}

	function log(address p0, address p1) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
	}

	function log(uint p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
	}

	function log(uint p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
	}

	function log(uint p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
	}

	function log(uint p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
	}

	function log(uint p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
	}

	function log(uint p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
	}

	function log(uint p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
	}

	function log(uint p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
	}

	function log(uint p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
	}

	function log(uint p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
	}

	function log(uint p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
	}

	function log(uint p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
	}

	function log(uint p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
	}

	function log(string memory p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
	}

	function log(string memory p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
	}

	function log(string memory p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
	}

	function log(string memory p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
	}

	function log(string memory p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
	}

	function log(string memory p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
	}

	function log(string memory p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
	}

	function log(bool p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
	}

	function log(bool p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
	}

	function log(bool p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
	}

	function log(bool p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
	}

	function log(bool p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
	}

	function log(bool p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
	}

	function log(bool p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
	}

	function log(bool p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
	}

	function log(bool p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
	}

	function log(bool p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
	}

	function log(bool p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
	}

	function log(bool p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
	}

	function log(bool p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
	}

	function log(address p0, uint p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
	}

	function log(address p0, uint p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
	}

	function log(address p0, uint p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
	}

	function log(address p0, uint p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
	}

	function log(address p0, string memory p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
	}

	function log(address p0, string memory p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
	}

	function log(address p0, string memory p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
	}

	function log(address p0, string memory p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
	}

	function log(address p0, bool p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
	}

	function log(address p0, bool p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
	}

	function log(address p0, bool p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
	}

	function log(address p0, bool p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
	}

	function log(address p0, address p1, uint p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
	}

	function log(address p0, address p1, string memory p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
	}

	function log(address p0, address p1, bool p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
	}

	function log(address p0, address p1, address p2) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
	}

	function log(uint p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
	}

	function log(uint p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
	}

	function log(string memory p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
	}

	function log(bool p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, uint p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, string memory p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, bool p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, uint p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, string memory p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, bool p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, uint p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, string memory p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, bool p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
	}

	function log(address p0, address p1, address p2, address p3) internal view {
		_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
	}

}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"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":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"zoneId","type":"uint8"},{"internalType":"uint8","name":"segmentId","type":"uint8"},{"internalType":"uint16","name":"count","type":"uint16"}],"internalType":"struct MintRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"canMint","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"components":[{"internalType":"uint16","name":"countOne","type":"uint16"},{"internalType":"uint16","name":"countTwo","type":"uint16"},{"internalType":"uint16","name":"countThree","type":"uint16"},{"internalType":"uint16","name":"countFour","type":"uint16"}],"internalType":"struct SegmentCount[]","name":"zones","type":"tuple[]"}],"internalType":"struct MintManyRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"canMintMany","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTrustedForwarder","outputs":[{"internalType":"address","name":"forwarder","type":"address"}],"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":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"zoneId","type":"uint8"},{"internalType":"uint8","name":"segmentId","type":"uint8"},{"internalType":"uint16","name":"count","type":"uint16"}],"internalType":"struct MintRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"internalType":"uint8","name":"zoneId","type":"uint8"},{"internalType":"uint8","name":"segmentId","type":"uint8"},{"internalType":"uint16","name":"count","type":"uint16"}],"internalType":"struct MintRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintDiscount","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"components":[{"internalType":"uint16","name":"countOne","type":"uint16"},{"internalType":"uint16","name":"countTwo","type":"uint16"},{"internalType":"uint16","name":"countThree","type":"uint16"},{"internalType":"uint16","name":"countFour","type":"uint16"}],"internalType":"struct SegmentCount[]","name":"zones","type":"tuple[]"}],"internalType":"struct MintManyRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintMany","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint64","name":"deadline","type":"uint64"},{"components":[{"internalType":"uint16","name":"countOne","type":"uint16"},{"internalType":"uint16","name":"countTwo","type":"uint16"},{"internalType":"uint16","name":"countThree","type":"uint16"},{"internalType":"uint16","name":"countFour","type":"uint16"}],"internalType":"struct SegmentCount[]","name":"zones","type":"tuple[]"}],"internalType":"struct MintManyRequest","name":"request","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintManyDiscount","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"versionRecipient","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b5061412d806100206000396000f3fe60806040526004361061010d5760003560e01c80638d90f9f2116100a5578063a9889b8611610074578063e985e9c511610059578063e985e9c51461035e578063f242432a1461037e578063ff00b7e41461039e57600080fd5b8063a9889b8614610304578063ce1b815f1461031757600080fd5b80638d90f9f21461029e5780639f94f65a146102b1578063a22cb465146102c4578063a67540c8146102e457600080fd5b8063486ff0cd116100e1578063486ff0cd146101b75780634e1273f414610203578063572b6c05146102305780636ff3160c1461027e57600080fd5b8062fdd58e1461011257806301ffc9a7146101455780632d95fdb5146101755780632eb2c2d614610195575b600080fd5b34801561011e57600080fd5b5061013261012d3660046135a7565b6103b1565b6040519081526020015b60405180910390f35b34801561015157600080fd5b50610165610160366004613601565b6103c6565b604051901515815260200161013c565b34801561018157600080fd5b5061016561019036600461361e565b61041f565b3480156101a157600080fd5b506101b56101b0366004613802565b61054a565b005b3480156101c357600080fd5b50604080518082018252600581527f322e322e350000000000000000000000000000000000000000000000000000006020820152905161013c91906138fd565b34801561020f57600080fd5b5061022361021e366004613910565b61060b565b60405161013c9190613a18565b34801561023c57600080fd5b5061016561024b366004613a2b565b7fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546001600160a01b0390811691161490565b34801561028a57600080fd5b50610165610299366004613ac5565b610832565b6101b56102ac366004613ac5565b610a9e565b6101b56102bf366004613b97565b610b81565b3480156102d057600080fd5b506101b56102df366004613cf2565b610c45565b3480156102f057600080fd5b506101656102ff366004613b97565b610c5b565b6101b5610312366004613b97565b610f14565b34801561032357600080fd5b507fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546040516001600160a01b03909116815260200161013c565b34801561036a57600080fd5b5061016561037936600461361e565b610fd8565b34801561038a57600080fd5b506101b5610399366004613d25565b610fe4565b6101b56103ac366004613ac5565b611099565b60006103bd83836111d3565b90505b92915050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604081205460ff166103c0565b7f683ec2651084e88e7bf4ad71f4d5cb4433c260c38c3dcbb76caed0575152e6c8546000906001600160a01b0316610458818585611298565b156104675760019150506103c0565b7f683ec2651084e88e7bf4ad71f4d5cb4433c260c38c3dcbb76caed0575152e6c7546001600160a01b031661049d818686611298565b156104ad576001925050506103c0565b6001600160a01b03841660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd950190602052604090205460ff16156104f8576001925050506103c0565b6001600160a01b0380861660009081527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde12602090815260408083209388168352929052205460ff165b95945050505050565b610552611349565b6001600160a01b0316856001600160a01b03161480610578575061057885610379611349565b6105ef5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f766564000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6106046105fa611349565b86868686866113bb565b5050505050565b606081518351146106845760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016105e6565b82517fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde119060009067ffffffffffffffff8111156106c3576106c3613657565b6040519080825280602002602001820160405280156106ec578160200160208202803683370190505b50905060005b85518110156108295760006001600160a01b031686828151811061071857610718613d8e565b60200260200101516001600160a01b03160361079c5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527f20746865207a65726f206164647265737300000000000000000000000000000060648201526084016105e6565b8260008683815181106107b1576107b1613d8e565b6020026020010151815260200190815260200160002060008783815181106107db576107db613d8e565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061081657610816613d8e565b60209081029190910101526001016106f2565b50949350505050565b6000807f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5460ff16600281111561086b5761086b613dbd565b9050600281600281111561088157610881613dbd565b148061089e5750600181600281111561089c5761089c613dbd565b145b6108ea5760405162461bcd60e51b815260206004820152601660248201527f6d696e744163746976653a206e6f74206163746976650000000000000000000060448201526064016105e6565b3233146109395760405162461bcd60e51b815260206004820152601b60248201527f6f6e6c79454f413a2063616c6c657220697320636f6e7472616374000000000060448201526064016105e6565b610981610945866113df565b85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061152992505050565b6109cd5760405162461bcd60e51b815260206004820152601a60248201527f63616e4d696e743a20696e76616c6964207369676e617475726500000000000060448201526064016105e6565b84516001600160a01b03166109e0611349565b6001600160a01b031614610a365760405162461bcd60e51b815260206004820152601260248201527f63616e4d696e743a206e6f74206275796572000000000000000000000000000060448201526064016105e6565b42856020015167ffffffffffffffff1611610a935760405162461bcd60e51b815260206004820152601a60248201527f63616e4d696e743a207369676e6174757265206578706972656400000000000060448201526064016105e6565b506001949350505050565b610aa9838383610832565b610af55760405162461bcd60e51b815260206004820152600d60248201527f6d696e743a20696e76616c69640000000000000000000000000000000000000060448201526064016105e6565b6000610b048460600151611576565b67ffffffffffffffff169050836080015161ffff1681610b249190613e1b565b3414610b725760405162461bcd60e51b815260206004820152601160248201527f6d696e743a2077726f6e6720707269636500000000000000000000000000000060448201526064016105e6565b610b7b8461161a565b50505050565b610b8c838383610c5b565b610bd85760405162461bcd60e51b815260206004820152601960248201527f6d696e744d616e79446973636f756e743a20696e76616c69640000000000000060448201526064016105e6565b610be9610be3611349565b8461177c565b3414610c375760405162461bcd60e51b815260206004820152601d60248201527f6d696e744d616e79446973636f756e743a2077726f6e6720707269636500000060448201526064016105e6565b610c4083611962565b505050565b610c57610c50611349565b83836119c8565b5050565b6000807f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5460ff166002811115610c9457610c94613dbd565b90506002816002811115610caa57610caa613dbd565b1480610cc757506001816002811115610cc557610cc5613dbd565b145b610d135760405162461bcd60e51b815260206004820152601660248201527f6d696e744163746976653a206e6f74206163746976650000000000000000000060448201526064016105e6565b323314610d625760405162461bcd60e51b815260206004820152601b60248201527f6f6e6c79454f413a2063616c6c657220697320636f6e7472616374000000000060448201526064016105e6565b610d6e61094586611b01565b610dba5760405162461bcd60e51b815260206004820152601e60248201527f63616e4d696e744d616e793a20696e76616c6964207369676e6174757265000060448201526064016105e6565b84516001600160a01b0316610dcd611349565b6001600160a01b031614610e235760405162461bcd60e51b815260206004820152601660248201527f63616e4d696e744d616e793a206e6f742062757965720000000000000000000060448201526064016105e6565b42856020015167ffffffffffffffff1611610e805760405162461bcd60e51b815260206004820152601e60248201527f63616e4d696e744d616e793a207369676e61747572652065787069726564000060448201526064016105e6565b7f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018e5474010000000000000000000000000000000000000000900460ff1660ff168560400151511115610a935760405162461bcd60e51b815260206004820152601860248201527f63616e4d696e744d616e793a2077726f6e6720696e646578000000000000000060448201526064016105e6565b610f1f838383610c5b565b610f6b5760405162461bcd60e51b815260206004820152601160248201527f6d696e744d616e793a20696e76616c696400000000000000000000000000000060448201526064016105e6565b6000610f7684611cef565b9050610f8181611dd7565b3414610fcf5760405162461bcd60e51b815260206004820152601560248201527f6d696e744d616e793a2077726f6e67207072696365000000000000000000000060448201526064016105e6565b610b7b84611962565b60006103bd838361041f565b610fec611349565b6001600160a01b0316856001600160a01b03161480611012575061101285610379611349565b6110845760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f766564000000000000000000000000000000000000000000000060648201526084016105e6565b61060461108f611349565b8686868686611e72565b6110a4838383610832565b6110f05760405162461bcd60e51b815260206004820152601560248201527f6d696e74446973636f756e743a20696e76616c6964000000000000000000000060448201526064016105e6565b6111056110fb611349565b8460400151611e8e565b6111515760405162461bcd60e51b815260206004820152601a60248201527f6d696e74446973636f756e743a20696e76616c6964207a6f6e6500000000000060448201526064016105e6565b600061116584604001518560600151611f76565b67ffffffffffffffff169050836080015161ffff16816111859190613e1b565b3414610b725760405162461bcd60e51b815260206004820152601960248201527f6d696e74446973636f756e743a2077726f6e672070726963650000000000000060448201526064016105e6565b60006001600160a01b0383166112515760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084016105e6565b7fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde116000928352602090815260408084206001600160a01b0395909516845293905250205490565b6000836001600160a01b0381161580159061054157506040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152808516919083169063c455279190602401602060405180830381865afa158015611312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113369190613e58565b6001600160a01b03161495945050505050565b60006014361080159061138557507fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546001600160a01b031633145b156113b557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6113c986868686868661202b565b6113d78686868686866122d8565b505050505050565b60006103c0826000015183602001518460400151856060015186608001516040516020016114c995949392919060609590951b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016855260c09390931b7fffffffffffffffff00000000000000000000000000000000000000000000000016601485015260f891821b7fff00000000000000000000000000000000000000000000000000000000000000908116601c860152911b16601d83015260f01b7fffff00000000000000000000000000000000000000000000000000000000000016601e82015260200190565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b600061153583836124dc565b6001600160a01b03167f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5461010090046001600160a01b0316149392505050565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae805467ffffffffffffffff8082168452680100000000000000008204811660208501527001000000000000000000000000000000008204811694840194909452780100000000000000000000000000000000000000000000000090049092166060820152600091906116139084612500565b9392505050565b60408181015160ff1660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f6020908152828220835161010081018552815461ffff808216608080850191825262010000808504841660a087015262ffffff640100000000808704821660c089015267010000000000000096879004821660e08901529387528a518084018c52600189015480871682528381048716828c01528581048316828e01528790048216606080830191909152888b01919091528b518085018d5260028a015480881682528481048816828d01528681048416828f0152889004831681830152888d01528b519384018c526003909801548086168452918204909416978201979097529086048216978101979097529304909216848201528082019390935291830151611755908390612627565b905061176583608001518261273b565b610c40836040015184606001518560800151612837565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae5467ffffffffffffffff808216835268010000000000000000820481166020840152700100000000000000000000000000000000820481169383019390935278010000000000000000000000000000000000000000000000009004909116606082015260009081805b8460400151518160ff16101561082957600061182d826001613e75565b90506118398782611e8e565b156119185760ff811660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf6020526040812060408051608081018252915467ffffffffffffffff8082168452680100000000000000008204811660208501527001000000000000000000000000000000008204811684840152780100000000000000000000000000000000000000000000000090910416606083015288015180519192506119069160ff86169081106118f8576118f8613d8e565b602002602001015182612991565b6119109085613e9a565b93505061194f565b61194286604001518360ff168151811061193457611934613d8e565b602002602001015185612991565b61194c9084613e9a565b92505b508061195a81613eb2565b915050611810565b60005b8160400151518160ff161015610c57576000611982826001613e75565b9050600083604001518360ff168151811061199f5761199f613d8e565b602002602001015190506119b38282612a33565b505080806119c090613eb2565b915050611965565b816001600160a01b03166119da611349565b6001600160a01b031603611a565760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016105e6565b6001600160a01b0383811660008181527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde12602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155825190815291517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319281900390910190a3505050565b60008082600001518360200151604051602001611b7492919060609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016825260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166014820152601c0190565b60405160208183030381529060405280519060200120905060005b8360400151518160ff161015611c97576000611bac826001613e75565b9050600085604001518360ff1681518110611bc957611bc9613d8e565b602090810291909101810151805181830151604080840151606085015182519687018b90527fff0000000000000000000000000000000000000000000000000000000000000060f88a901b16928701929092527fffff00000000000000000000000000000000000000000000000000000000000060f094851b8116604188015292841b83166043870152831b8216604586015290911b166047830152915060490160405160208183030381529060405280519060200120935050508080611c8f90613eb2565b915050611b8f565b50611613816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6040805160808101825260008082526020820181905291810182905260608101829052905b8260400151518160ff161015611dd157600083604001518260ff1681518110611d3f57611d3f613d8e565b60200260200101519050806000015183600001818151611d5f9190613ed1565b61ffff169052506020808201519084018051611d7c908390613ed1565b61ffff169052506040808201519084018051611d99908390613ed1565b61ffff169052506060808201519084018051611db6908390613ed1565b61ffff16905250819050611dc981613eb2565b915050611d14565b50919050565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae5467ffffffffffffffff80821683526801000000000000000082048116602084015270010000000000000000000000000000000082048116938301939093527801000000000000000000000000000000000000000000000000900490911660608201526000906116138382612991565b611e80868686868686612c10565b6113d7868686868686612e13565b6000611e9982612f6e565b611ea5575060006103c0565b60ff82166002148015611f60575060007f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c600201546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152909116906370a0823190602401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e9190613ef7565b115b15611f6d575060016103c0565b50600092915050565b60ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602090815260408083208151608081018352905467ffffffffffffffff80821683526801000000000000000082048116948301949094527001000000000000000000000000000000008104841692820192909252780100000000000000000000000000000000000000000000000090910490911660608201526120238184612500565b949350505050565b81518351146120a25760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d6174636800000000000000000000000000000000000000000000000060648201526084016105e6565b6001600160a01b03841661211e5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105e6565b7fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde1160005b845181101561227657600085828151811061215f5761215f613d8e565b60200260200101519050600085838151811061217d5761217d613d8e565b602090810291909101810151600084815286835260408082206001600160a01b038e1683529093529190912054909150818110156122235760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201527f6f72207472616e7366657200000000000000000000000000000000000000000060648201526084016105e6565b6000838152602086815260408083206001600160a01b038e811685529252808320938590039093558a168152908120805460019590950194839290612269908490613e9a565b9091555061214292505050565b50846001600160a01b0316866001600160a01b0316886001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122c6929190613f10565b60405180910390a45b50505050505050565b6001600160a01b0384163b156113d7576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906123359089908990889088908890600401613f35565b6020604051808303816000875af1925050508015612370575060408051601f3d908101601f1916820190925261236d91810190613f93565b60015b6124255761237c613fb0565b806308c379a0036123b55750612390613fcb565b8061239b57506123b7565b8060405162461bcd60e51b81526004016105e691906138fd565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016105e6565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c8100000000000000000000000000000000000000000000000000000000146122cf5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016105e6565b60008060006124eb85856130bc565b915091506124f88161312a565b509392505050565b600060018260ff16600481111561251957612519613dbd565b600481111561252a5761252a613dbd565b03612537575081516103c0565b60028260ff16600481111561254e5761254e613dbd565b600481111561255f5761255f613dbd565b0361256f575060208201516103c0565b60038260ff16600481111561258657612586613dbd565b600481111561259757612597613dbd565b036125a7575060408201516103c0565b60048260ff1660048111156125be576125be613dbd565b60048111156125cf576125cf613dbd565b036125df575060608201516103c0565b60405162461bcd60e51b815260206004820152601960248201527f5f67657450726963653a2077726f6e672063617465676f72790000000000000060448201526064016105e6565b60408051608081018252600080825260208201819052918101829052606081018290529060ff8316600481111561266057612660613dbd565b9050600181600481111561267657612676613dbd565b0361268457505081516103c0565b600281600481111561269857612698613dbd565b036126a957505060208201516103c0565b60038160048111156126bd576126bd613dbd565b036126ce57505060408201516103c0565b60048160048111156126e2576126e2613dbd565b036126f357505060608201516103c0565b60405162461bcd60e51b815260206004820152601c60248201527f5f67657443617465676f72793a2077726f6e672063617465676f72790000000060448201526064016105e6565b60008261ffff161161278f5760405162461bcd60e51b815260206004820152600e60248201527f696e76616c696420616d6f756e7400000000000000000000000000000000000060448201526064016105e6565b806020015161ffff168282600001516127a89190613ed1565b61ffff1611156127fa5760405162461bcd60e51b815260206004820152600860248201527f736f6c64206f757400000000000000000000000000000000000000000000000060448201526064016105e6565b6000816000015161ffff1682604001516128149190614073565b62ffffff169050600061282b61ffff851683614091565b9050610b7b8282613319565b60ff83811660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f60205260408120918416600481111561287d5761287d613dbd565b9050600181600481111561289357612893613dbd565b036128cf578154839083906000906128b090849061ffff16613ed1565b92506101000a81548161ffff021916908361ffff160217905550610604565b60028160048111156128e3576128e3613dbd565b03612903576001820180548491906000906128b090849061ffff16613ed1565b600381600481111561291757612917613dbd565b03612937576002820180548491906000906128b090849061ffff16613ed1565b600481600481111561294b5761294b613dbd565b036106045760038201805484919060009061296b90849061ffff16613ed1565b92506101000a81548161ffff021916908361ffff1602179055505050505050565b919050565b6000826060015161ffff16826060015167ffffffffffffffff166129b59190613e1b565b836040015161ffff16836040015167ffffffffffffffff166129d79190613e1b565b846020015161ffff16846020015167ffffffffffffffff166129f99190613e1b565b85518551612a159161ffff169067ffffffffffffffff16613e1b565b612a1f9190613e9a565b612a299190613e9a565b6103bd9190613e9a565b60ff821660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f6020908152604091829020825161010081018452815461ffff808216608080850191825262010000808504841660a087015264010000000080860462ffffff90811660c089015267010000000000000096879004811660e089015293875289518084018b52600189015480871682528381048716828c01528281048616828d01528790048516606080830191909152888b01919091528a518085018c5260028a015480881682528481048816828d01528381048716828e0152889004861681830152888c01528a519384018b5260039098015480861684529182048516988301989098529687048216978101979097529190940416848301529081019290925282511615612b805781518151612b73919061273b565b612b808360018451612837565b602082015161ffff1615612bb057612ba08260200151826020015161273b565b612bb08360028460200151612837565b604082015161ffff1615612be057612bd08260400151826040015161273b565b612be08360038460400151612837565b606082015161ffff1615610c4057612c008260600151826060015161273b565b610c408360048460600151612837565b6001600160a01b038416612c8c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105e6565b6000612c9784613408565b90506000612ca484613408565b9050612cbe888888612cb589613408565b61060489613408565b60008581527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde11602081815260408084206001600160a01b038c1685529091529091205485811015612d775760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201527f6f72207472616e7366657200000000000000000000000000000000000000000060648201526084016105e6565b6000878152602083815260408083206001600160a01b038d81168552925280832093899003909355891681529081208054879290612db6908490613e9a565b909155505060408051878152602081018790526001600160a01b03808a16928b821692918d16917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050505050505050565b6001600160a01b0384163b156113d7576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e6190612e7090899089908890889088906004016140b4565b6020604051808303816000875af1925050508015612eab575060408051601f3d908101601f19168201909252612ea891810190613f93565b60015b612eb75761237c613fb0565b7fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e6100000000000000000000000000000000000000000000000000000000146122cf5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016105e6565b60ff811660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602052604081205467ffffffffffffffff1615801590612ffe575060ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602052604090205468010000000000000000900467ffffffffffffffff1615155b8015613058575060ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf6020526040902054700100000000000000000000000000000000900467ffffffffffffffff1615155b80156103c057505060ff1660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff16151590565b60008082516041036130f25760208301516040840151606085015160001a6130e687828585613453565b94509450505050613123565b825160400361311b5760208301516040840151613110868383613540565b935093505050613123565b506000905060025b9250929050565b600081600481111561313e5761313e613dbd565b036131465750565b600181600481111561315a5761315a613dbd565b036131a75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105e6565b60028160048111156131bb576131bb613dbd565b036132085760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105e6565b600381600481111561321c5761321c613dbd565b0361328f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b60048160048111156132a3576132a3613dbd565b036133165760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b50565b8067ffffffffffffffff168267ffffffffffffffff161015610c575767ffffffffffffffff821660009081527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde1160205260408120600191613378611349565b6001600160a01b0316815260208101919091526040016000205561339a611349565b6001600160a01b031660006133ad611349565b6040805167ffffffffffffffff87168152600160208201526001600160a01b0392909216917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4600190910190613319565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061344257613442613d8e565b602090810291909101015292915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561348a5750600090506003613537565b8460ff16601b141580156134a257508460ff16601c14155b156134b35750600090506004613537565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613507573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661353057600060019250925050613537565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83168161357660ff86901c601b613e9a565b905061358487828885613453565b935093505050935093915050565b6001600160a01b038116811461331657600080fd5b600080604083850312156135ba57600080fd5b82356135c581613592565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461331657600080fd5b60006020828403121561361357600080fd5b8135611613816135d3565b6000806040838503121561363157600080fd5b823561363c81613592565b9150602083013561364c81613592565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810181811067ffffffffffffffff821117156136a6576136a6613657565b60405250565b6080810181811067ffffffffffffffff821117156136a6576136a6613657565b601f19601f830116810181811067ffffffffffffffff821117156136f2576136f2613657565b6040525050565b600067ffffffffffffffff82111561371357613713613657565b5060051b60200190565b600082601f83011261372e57600080fd5b8135602061373b826136f9565b60405161374882826136cc565b83815260059390931b850182019282810191508684111561376857600080fd5b8286015b84811015613783578035835291830191830161376c565b509695505050505050565b600082601f83011261379f57600080fd5b813567ffffffffffffffff8111156137b9576137b9613657565b6040516137d06020601f19601f85011601826136cc565b8181528460208386010111156137e557600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561381a57600080fd5b853561382581613592565b9450602086013561383581613592565b9350604086013567ffffffffffffffff8082111561385257600080fd5b61385e89838a0161371d565b9450606088013591508082111561387457600080fd5b61388089838a0161371d565b9350608088013591508082111561389657600080fd5b506138a38882890161378e565b9150509295509295909350565b6000815180845260005b818110156138d6576020818501810151868301820152016138ba565b818111156138e8576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006103bd60208301846138b0565b6000806040838503121561392357600080fd5b823567ffffffffffffffff8082111561393b57600080fd5b818501915085601f83011261394f57600080fd5b8135602061395c826136f9565b60405161396982826136cc565b83815260059390931b850182019282810191508984111561398957600080fd5b948201945b838610156139b05785356139a181613592565b8252948201949082019061398e565b965050860135925050808211156139c657600080fd5b506139d38582860161371d565b9150509250929050565b600081518084526020808501945080840160005b83811015613a0d578151875295820195908201906001016139f1565b509495945050505050565b6020815260006103bd60208301846139dd565b600060208284031215613a3d57600080fd5b813561161381613592565b803567ffffffffffffffff8116811461298c57600080fd5b803560ff8116811461298c57600080fd5b803561ffff8116811461298c57600080fd5b60008083601f840112613a9557600080fd5b50813567ffffffffffffffff811115613aad57600080fd5b60208301915083602082850101111561312357600080fd5b600080600083850360c0811215613adb57600080fd5b60a0811215613ae957600080fd5b5060405160a0810167ffffffffffffffff8282108183111715613b0e57613b0e613657565b8160405286359150613b1f82613592565b818352613b2e60208801613a48565b6020840152613b3f60408801613a60565b6040840152613b5060608801613a60565b6060840152613b6160808801613a71565b608084015291945060a08601359180831115613b7c57600080fd5b5050613b8a86828701613a83565b9497909650939450505050565b60008060006040808587031215613bad57600080fd5b843567ffffffffffffffff80821115613bc557600080fd5b8187019150606080838a031215613bdb57600080fd5b8351613be681613686565b8335613bf181613592565b81526020613c00858201613a48565b818301528585013584811115613c1557600080fd5b8086019550508a601f860112613c2a57600080fd5b8435613c35816136f9565b8751613c4182826136cc565b82815260079290921b870183019183810191508d831115613c6157600080fd5b968301965b82881015613cd4576080888f031215613c7f5760008081fd5b8851613c8a816136ac565b613c9389613a71565b8152613ca0858a01613a71565b85820152613caf8a8a01613a71565b8a820152613cbe878a01613a71565b8188015282526080979097019690830190613c66565b978401979097525090975088013593505080831115613b7c57600080fd5b60008060408385031215613d0557600080fd5b8235613d1081613592565b91506020830135801515811461364c57600080fd5b600080600080600060a08688031215613d3d57600080fd5b8535613d4881613592565b94506020860135613d5881613592565b93506040860135925060608601359150608086013567ffffffffffffffff811115613d8257600080fd5b6138a38882890161378e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e5357613e53613dec565b500290565b600060208284031215613e6a57600080fd5b815161161381613592565b600060ff821660ff84168060ff03821115613e9257613e92613dec565b019392505050565b60008219821115613ead57613ead613dec565b500190565b600060ff821660ff8103613ec857613ec8613dec565b60010192915050565b600061ffff808316818516808303821115613eee57613eee613dec565b01949350505050565b600060208284031215613f0957600080fd5b5051919050565b604081526000613f2360408301856139dd565b828103602084015261054181856139dd565b60006001600160a01b03808816835280871660208401525060a06040830152613f6160a08301866139dd565b8281036060840152613f7381866139dd565b90508281036080840152613f8781856138b0565b98975050505050505050565b600060208284031215613fa557600080fd5b8151611613816135d3565b600060033d11156113b85760046000803e5060005160e01c90565b600060443d1015613fd95790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561402757505050505090565b828501915081518181111561403f5750505050505090565b843d87010160208285010111156140595750505050505090565b614068602082860101876136cc565b509095945050505050565b600062ffffff808316818516808303821115613eee57613eee613dec565b600067ffffffffffffffff808316818516808303821115613eee57613eee613dec565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526140ec60a08301846138b0565b97965050505050505056fea2646970667358221220bec2cd92a8e3ae6e4d1edef7c0913c162500323fda50396d0e7662b097e655e964736f6c634300080e0033

Deployed Bytecode

0x60806040526004361061010d5760003560e01c80638d90f9f2116100a5578063a9889b8611610074578063e985e9c511610059578063e985e9c51461035e578063f242432a1461037e578063ff00b7e41461039e57600080fd5b8063a9889b8614610304578063ce1b815f1461031757600080fd5b80638d90f9f21461029e5780639f94f65a146102b1578063a22cb465146102c4578063a67540c8146102e457600080fd5b8063486ff0cd116100e1578063486ff0cd146101b75780634e1273f414610203578063572b6c05146102305780636ff3160c1461027e57600080fd5b8062fdd58e1461011257806301ffc9a7146101455780632d95fdb5146101755780632eb2c2d614610195575b600080fd5b34801561011e57600080fd5b5061013261012d3660046135a7565b6103b1565b6040519081526020015b60405180910390f35b34801561015157600080fd5b50610165610160366004613601565b6103c6565b604051901515815260200161013c565b34801561018157600080fd5b5061016561019036600461361e565b61041f565b3480156101a157600080fd5b506101b56101b0366004613802565b61054a565b005b3480156101c357600080fd5b50604080518082018252600581527f322e322e350000000000000000000000000000000000000000000000000000006020820152905161013c91906138fd565b34801561020f57600080fd5b5061022361021e366004613910565b61060b565b60405161013c9190613a18565b34801561023c57600080fd5b5061016561024b366004613a2b565b7fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546001600160a01b0390811691161490565b34801561028a57600080fd5b50610165610299366004613ac5565b610832565b6101b56102ac366004613ac5565b610a9e565b6101b56102bf366004613b97565b610b81565b3480156102d057600080fd5b506101b56102df366004613cf2565b610c45565b3480156102f057600080fd5b506101656102ff366004613b97565b610c5b565b6101b5610312366004613b97565b610f14565b34801561032357600080fd5b507fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546040516001600160a01b03909116815260200161013c565b34801561036a57600080fd5b5061016561037936600461361e565b610fd8565b34801561038a57600080fd5b506101b5610399366004613d25565b610fe4565b6101b56103ac366004613ac5565b611099565b60006103bd83836111d3565b90505b92915050565b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604081205460ff166103c0565b7f683ec2651084e88e7bf4ad71f4d5cb4433c260c38c3dcbb76caed0575152e6c8546000906001600160a01b0316610458818585611298565b156104675760019150506103c0565b7f683ec2651084e88e7bf4ad71f4d5cb4433c260c38c3dcbb76caed0575152e6c7546001600160a01b031661049d818686611298565b156104ad576001925050506103c0565b6001600160a01b03841660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd950190602052604090205460ff16156104f8576001925050506103c0565b6001600160a01b0380861660009081527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde12602090815260408083209388168352929052205460ff165b95945050505050565b610552611349565b6001600160a01b0316856001600160a01b03161480610578575061057885610379611349565b6105ef5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f766564000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6106046105fa611349565b86868686866113bb565b5050505050565b606081518351146106845760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016105e6565b82517fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde119060009067ffffffffffffffff8111156106c3576106c3613657565b6040519080825280602002602001820160405280156106ec578160200160208202803683370190505b50905060005b85518110156108295760006001600160a01b031686828151811061071857610718613d8e565b60200260200101516001600160a01b03160361079c5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527f20746865207a65726f206164647265737300000000000000000000000000000060648201526084016105e6565b8260008683815181106107b1576107b1613d8e565b6020026020010151815260200190815260200160002060008783815181106107db576107db613d8e565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061081657610816613d8e565b60209081029190910101526001016106f2565b50949350505050565b6000807f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5460ff16600281111561086b5761086b613dbd565b9050600281600281111561088157610881613dbd565b148061089e5750600181600281111561089c5761089c613dbd565b145b6108ea5760405162461bcd60e51b815260206004820152601660248201527f6d696e744163746976653a206e6f74206163746976650000000000000000000060448201526064016105e6565b3233146109395760405162461bcd60e51b815260206004820152601b60248201527f6f6e6c79454f413a2063616c6c657220697320636f6e7472616374000000000060448201526064016105e6565b610981610945866113df565b85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061152992505050565b6109cd5760405162461bcd60e51b815260206004820152601a60248201527f63616e4d696e743a20696e76616c6964207369676e617475726500000000000060448201526064016105e6565b84516001600160a01b03166109e0611349565b6001600160a01b031614610a365760405162461bcd60e51b815260206004820152601260248201527f63616e4d696e743a206e6f74206275796572000000000000000000000000000060448201526064016105e6565b42856020015167ffffffffffffffff1611610a935760405162461bcd60e51b815260206004820152601a60248201527f63616e4d696e743a207369676e6174757265206578706972656400000000000060448201526064016105e6565b506001949350505050565b610aa9838383610832565b610af55760405162461bcd60e51b815260206004820152600d60248201527f6d696e743a20696e76616c69640000000000000000000000000000000000000060448201526064016105e6565b6000610b048460600151611576565b67ffffffffffffffff169050836080015161ffff1681610b249190613e1b565b3414610b725760405162461bcd60e51b815260206004820152601160248201527f6d696e743a2077726f6e6720707269636500000000000000000000000000000060448201526064016105e6565b610b7b8461161a565b50505050565b610b8c838383610c5b565b610bd85760405162461bcd60e51b815260206004820152601960248201527f6d696e744d616e79446973636f756e743a20696e76616c69640000000000000060448201526064016105e6565b610be9610be3611349565b8461177c565b3414610c375760405162461bcd60e51b815260206004820152601d60248201527f6d696e744d616e79446973636f756e743a2077726f6e6720707269636500000060448201526064016105e6565b610c4083611962565b505050565b610c57610c50611349565b83836119c8565b5050565b6000807f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5460ff166002811115610c9457610c94613dbd565b90506002816002811115610caa57610caa613dbd565b1480610cc757506001816002811115610cc557610cc5613dbd565b145b610d135760405162461bcd60e51b815260206004820152601660248201527f6d696e744163746976653a206e6f74206163746976650000000000000000000060448201526064016105e6565b323314610d625760405162461bcd60e51b815260206004820152601b60248201527f6f6e6c79454f413a2063616c6c657220697320636f6e7472616374000000000060448201526064016105e6565b610d6e61094586611b01565b610dba5760405162461bcd60e51b815260206004820152601e60248201527f63616e4d696e744d616e793a20696e76616c6964207369676e6174757265000060448201526064016105e6565b84516001600160a01b0316610dcd611349565b6001600160a01b031614610e235760405162461bcd60e51b815260206004820152601660248201527f63616e4d696e744d616e793a206e6f742062757965720000000000000000000060448201526064016105e6565b42856020015167ffffffffffffffff1611610e805760405162461bcd60e51b815260206004820152601e60248201527f63616e4d696e744d616e793a207369676e61747572652065787069726564000060448201526064016105e6565b7f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018e5474010000000000000000000000000000000000000000900460ff1660ff168560400151511115610a935760405162461bcd60e51b815260206004820152601860248201527f63616e4d696e744d616e793a2077726f6e6720696e646578000000000000000060448201526064016105e6565b610f1f838383610c5b565b610f6b5760405162461bcd60e51b815260206004820152601160248201527f6d696e744d616e793a20696e76616c696400000000000000000000000000000060448201526064016105e6565b6000610f7684611cef565b9050610f8181611dd7565b3414610fcf5760405162461bcd60e51b815260206004820152601560248201527f6d696e744d616e793a2077726f6e67207072696365000000000000000000000060448201526064016105e6565b610b7b84611962565b60006103bd838361041f565b610fec611349565b6001600160a01b0316856001600160a01b03161480611012575061101285610379611349565b6110845760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f766564000000000000000000000000000000000000000000000060648201526084016105e6565b61060461108f611349565b8686868686611e72565b6110a4838383610832565b6110f05760405162461bcd60e51b815260206004820152601560248201527f6d696e74446973636f756e743a20696e76616c6964000000000000000000000060448201526064016105e6565b6111056110fb611349565b8460400151611e8e565b6111515760405162461bcd60e51b815260206004820152601a60248201527f6d696e74446973636f756e743a20696e76616c6964207a6f6e6500000000000060448201526064016105e6565b600061116584604001518560600151611f76565b67ffffffffffffffff169050836080015161ffff16816111859190613e1b565b3414610b725760405162461bcd60e51b815260206004820152601960248201527f6d696e74446973636f756e743a2077726f6e672070726963650000000000000060448201526064016105e6565b60006001600160a01b0383166112515760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084016105e6565b7fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde116000928352602090815260408084206001600160a01b0395909516845293905250205490565b6000836001600160a01b0381161580159061054157506040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152808516919083169063c455279190602401602060405180830381865afa158015611312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113369190613e58565b6001600160a01b03161495945050505050565b60006014361080159061138557507fba2deb1b50117e9b92f0700714400c079451bb20f846b3064402c3bac14426ce546001600160a01b031633145b156113b557507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6113c986868686868661202b565b6113d78686868686866122d8565b505050505050565b60006103c0826000015183602001518460400151856060015186608001516040516020016114c995949392919060609590951b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016855260c09390931b7fffffffffffffffff00000000000000000000000000000000000000000000000016601485015260f891821b7fff00000000000000000000000000000000000000000000000000000000000000908116601c860152911b16601d83015260f01b7fffff00000000000000000000000000000000000000000000000000000000000016601e82015260200190565b60408051601f1981840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b600061153583836124dc565b6001600160a01b03167f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c5461010090046001600160a01b0316149392505050565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae805467ffffffffffffffff8082168452680100000000000000008204811660208501527001000000000000000000000000000000008204811694840194909452780100000000000000000000000000000000000000000000000090049092166060820152600091906116139084612500565b9392505050565b60408181015160ff1660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f6020908152828220835161010081018552815461ffff808216608080850191825262010000808504841660a087015262ffffff640100000000808704821660c089015267010000000000000096879004821660e08901529387528a518084018c52600189015480871682528381048716828c01528581048316828e01528790048216606080830191909152888b01919091528b518085018d5260028a015480881682528481048816828d01528681048416828f0152889004831681830152888d01528b519384018c526003909801548086168452918204909416978201979097529086048216978101979097529304909216848201528082019390935291830151611755908390612627565b905061176583608001518261273b565b610c40836040015184606001518560800151612837565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae5467ffffffffffffffff808216835268010000000000000000820481166020840152700100000000000000000000000000000000820481169383019390935278010000000000000000000000000000000000000000000000009004909116606082015260009081805b8460400151518160ff16101561082957600061182d826001613e75565b90506118398782611e8e565b156119185760ff811660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf6020526040812060408051608081018252915467ffffffffffffffff8082168452680100000000000000008204811660208501527001000000000000000000000000000000008204811684840152780100000000000000000000000000000000000000000000000090910416606083015288015180519192506119069160ff86169081106118f8576118f8613d8e565b602002602001015182612991565b6119109085613e9a565b93505061194f565b61194286604001518360ff168151811061193457611934613d8e565b602002602001015185612991565b61194c9084613e9a565b92505b508061195a81613eb2565b915050611810565b60005b8160400151518160ff161015610c57576000611982826001613e75565b9050600083604001518360ff168151811061199f5761199f613d8e565b602002602001015190506119b38282612a33565b505080806119c090613eb2565b915050611965565b816001600160a01b03166119da611349565b6001600160a01b031603611a565760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016105e6565b6001600160a01b0383811660008181527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde12602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155825190815291517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319281900390910190a3505050565b60008082600001518360200151604051602001611b7492919060609290921b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016825260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166014820152601c0190565b60405160208183030381529060405280519060200120905060005b8360400151518160ff161015611c97576000611bac826001613e75565b9050600085604001518360ff1681518110611bc957611bc9613d8e565b602090810291909101810151805181830151604080840151606085015182519687018b90527fff0000000000000000000000000000000000000000000000000000000000000060f88a901b16928701929092527fffff00000000000000000000000000000000000000000000000000000000000060f094851b8116604188015292841b83166043870152831b8216604586015290911b166047830152915060490160405160208183030381529060405280519060200120935050508080611c8f90613eb2565b915050611b8f565b50611613816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6040805160808101825260008082526020820181905291810182905260608101829052905b8260400151518160ff161015611dd157600083604001518260ff1681518110611d3f57611d3f613d8e565b60200260200101519050806000015183600001818151611d5f9190613ed1565b61ffff169052506020808201519084018051611d7c908390613ed1565b61ffff169052506040808201519084018051611d99908390613ed1565b61ffff169052506060808201519084018051611db6908390613ed1565b61ffff16905250819050611dc981613eb2565b915050611d14565b50919050565b604080516080810182527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47fae5467ffffffffffffffff80821683526801000000000000000082048116602084015270010000000000000000000000000000000082048116938301939093527801000000000000000000000000000000000000000000000000900490911660608201526000906116138382612991565b611e80868686868686612c10565b6113d7868686868686612e13565b6000611e9982612f6e565b611ea5575060006103c0565b60ff82166002148015611f60575060007f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018c600201546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152909116906370a0823190602401602060405180830381865afa158015611f3a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f5e9190613ef7565b115b15611f6d575060016103c0565b50600092915050565b60ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602090815260408083208151608081018352905467ffffffffffffffff80821683526801000000000000000082048116948301949094527001000000000000000000000000000000008104841692820192909252780100000000000000000000000000000000000000000000000090910490911660608201526120238184612500565b949350505050565b81518351146120a25760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d6174636800000000000000000000000000000000000000000000000060648201526084016105e6565b6001600160a01b03841661211e5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105e6565b7fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde1160005b845181101561227657600085828151811061215f5761215f613d8e565b60200260200101519050600085838151811061217d5761217d613d8e565b602090810291909101810151600084815286835260408082206001600160a01b038e1683529093529190912054909150818110156122235760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201527f6f72207472616e7366657200000000000000000000000000000000000000000060648201526084016105e6565b6000838152602086815260408083206001600160a01b038e811685529252808320938590039093558a168152908120805460019590950194839290612269908490613e9a565b9091555061214292505050565b50846001600160a01b0316866001600160a01b0316886001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122c6929190613f10565b60405180910390a45b50505050505050565b6001600160a01b0384163b156113d7576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906123359089908990889088908890600401613f35565b6020604051808303816000875af1925050508015612370575060408051601f3d908101601f1916820190925261236d91810190613f93565b60015b6124255761237c613fb0565b806308c379a0036123b55750612390613fcb565b8061239b57506123b7565b8060405162461bcd60e51b81526004016105e691906138fd565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016105e6565b7fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c8100000000000000000000000000000000000000000000000000000000146122cf5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016105e6565b60008060006124eb85856130bc565b915091506124f88161312a565b509392505050565b600060018260ff16600481111561251957612519613dbd565b600481111561252a5761252a613dbd565b03612537575081516103c0565b60028260ff16600481111561254e5761254e613dbd565b600481111561255f5761255f613dbd565b0361256f575060208201516103c0565b60038260ff16600481111561258657612586613dbd565b600481111561259757612597613dbd565b036125a7575060408201516103c0565b60048260ff1660048111156125be576125be613dbd565b60048111156125cf576125cf613dbd565b036125df575060608201516103c0565b60405162461bcd60e51b815260206004820152601960248201527f5f67657450726963653a2077726f6e672063617465676f72790000000000000060448201526064016105e6565b60408051608081018252600080825260208201819052918101829052606081018290529060ff8316600481111561266057612660613dbd565b9050600181600481111561267657612676613dbd565b0361268457505081516103c0565b600281600481111561269857612698613dbd565b036126a957505060208201516103c0565b60038160048111156126bd576126bd613dbd565b036126ce57505060408201516103c0565b60048160048111156126e2576126e2613dbd565b036126f357505060608201516103c0565b60405162461bcd60e51b815260206004820152601c60248201527f5f67657443617465676f72793a2077726f6e672063617465676f72790000000060448201526064016105e6565b60008261ffff161161278f5760405162461bcd60e51b815260206004820152600e60248201527f696e76616c696420616d6f756e7400000000000000000000000000000000000060448201526064016105e6565b806020015161ffff168282600001516127a89190613ed1565b61ffff1611156127fa5760405162461bcd60e51b815260206004820152600860248201527f736f6c64206f757400000000000000000000000000000000000000000000000060448201526064016105e6565b6000816000015161ffff1682604001516128149190614073565b62ffffff169050600061282b61ffff851683614091565b9050610b7b8282613319565b60ff83811660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f60205260408120918416600481111561287d5761287d613dbd565b9050600181600481111561289357612893613dbd565b036128cf578154839083906000906128b090849061ffff16613ed1565b92506101000a81548161ffff021916908361ffff160217905550610604565b60028160048111156128e3576128e3613dbd565b03612903576001820180548491906000906128b090849061ffff16613ed1565b600381600481111561291757612917613dbd565b03612937576002820180548491906000906128b090849061ffff16613ed1565b600481600481111561294b5761294b613dbd565b036106045760038201805484919060009061296b90849061ffff16613ed1565b92506101000a81548161ffff021916908361ffff1602179055505050505050565b919050565b6000826060015161ffff16826060015167ffffffffffffffff166129b59190613e1b565b836040015161ffff16836040015167ffffffffffffffff166129d79190613e1b565b846020015161ffff16846020015167ffffffffffffffff166129f99190613e1b565b85518551612a159161ffff169067ffffffffffffffff16613e1b565b612a1f9190613e9a565b612a299190613e9a565b6103bd9190613e9a565b60ff821660009081527f03d0458dff58ff412eb9d195718ad8748b21fc386854067c31d72bc8cd95018f6020908152604091829020825161010081018452815461ffff808216608080850191825262010000808504841660a087015264010000000080860462ffffff90811660c089015267010000000000000096879004811660e089015293875289518084018b52600189015480871682528381048716828c01528281048616828d01528790048516606080830191909152888b01919091528a518085018c5260028a015480881682528481048816828d01528381048716828e0152889004861681830152888c01528a519384018b5260039098015480861684529182048516988301989098529687048216978101979097529190940416848301529081019290925282511615612b805781518151612b73919061273b565b612b808360018451612837565b602082015161ffff1615612bb057612ba08260200151826020015161273b565b612bb08360028460200151612837565b604082015161ffff1615612be057612bd08260400151826040015161273b565b612be08360038460400151612837565b606082015161ffff1615610c4057612c008260600151826060015161273b565b610c408360048460600151612837565b6001600160a01b038416612c8c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105e6565b6000612c9784613408565b90506000612ca484613408565b9050612cbe888888612cb589613408565b61060489613408565b60008581527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde11602081815260408084206001600160a01b038c1685529091529091205485811015612d775760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201527f6f72207472616e7366657200000000000000000000000000000000000000000060648201526084016105e6565b6000878152602083815260408083206001600160a01b038d81168552925280832093899003909355891681529081208054879290612db6908490613e9a565b909155505060408051878152602081018790526001600160a01b03808a16928b821692918d16917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050505050505050565b6001600160a01b0384163b156113d7576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e6190612e7090899089908890889088906004016140b4565b6020604051808303816000875af1925050508015612eab575060408051601f3d908101601f19168201909252612ea891810190613f93565b60015b612eb75761237c613fb0565b7fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e6100000000000000000000000000000000000000000000000000000000146122cf5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016105e6565b60ff811660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602052604081205467ffffffffffffffff1615801590612ffe575060ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf602052604090205468010000000000000000900467ffffffffffffffff1615155b8015613058575060ff821660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf6020526040902054700100000000000000000000000000000000900467ffffffffffffffff1615155b80156103c057505060ff1660009081527fa43280b110721f32087cea441bbd9dbbd453e2f4651e488765236a6a1fb47faf60205260409020547801000000000000000000000000000000000000000000000000900467ffffffffffffffff16151590565b60008082516041036130f25760208301516040840151606085015160001a6130e687828585613453565b94509450505050613123565b825160400361311b5760208301516040840151613110868383613540565b935093505050613123565b506000905060025b9250929050565b600081600481111561313e5761313e613dbd565b036131465750565b600181600481111561315a5761315a613dbd565b036131a75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105e6565b60028160048111156131bb576131bb613dbd565b036132085760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105e6565b600381600481111561321c5761321c613dbd565b0361328f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b60048160048111156132a3576132a3613dbd565b036133165760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105e6565b50565b8067ffffffffffffffff168267ffffffffffffffff161015610c575767ffffffffffffffff821660009081527fda64505114ffbd301f95f2eeb25343e93533c4e22ea0c8ba92ee906a975cde1160205260408120600191613378611349565b6001600160a01b0316815260208101919091526040016000205561339a611349565b6001600160a01b031660006133ad611349565b6040805167ffffffffffffffff87168152600160208201526001600160a01b0392909216917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4600190910190613319565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061344257613442613d8e565b602090810291909101015292915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561348a5750600090506003613537565b8460ff16601b141580156134a257508460ff16601c14155b156134b35750600090506004613537565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613507573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661353057600060019250925050613537565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83168161357660ff86901c601b613e9a565b905061358487828885613453565b935093505050935093915050565b6001600160a01b038116811461331657600080fd5b600080604083850312156135ba57600080fd5b82356135c581613592565b946020939093013593505050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461331657600080fd5b60006020828403121561361357600080fd5b8135611613816135d3565b6000806040838503121561363157600080fd5b823561363c81613592565b9150602083013561364c81613592565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810181811067ffffffffffffffff821117156136a6576136a6613657565b60405250565b6080810181811067ffffffffffffffff821117156136a6576136a6613657565b601f19601f830116810181811067ffffffffffffffff821117156136f2576136f2613657565b6040525050565b600067ffffffffffffffff82111561371357613713613657565b5060051b60200190565b600082601f83011261372e57600080fd5b8135602061373b826136f9565b60405161374882826136cc565b83815260059390931b850182019282810191508684111561376857600080fd5b8286015b84811015613783578035835291830191830161376c565b509695505050505050565b600082601f83011261379f57600080fd5b813567ffffffffffffffff8111156137b9576137b9613657565b6040516137d06020601f19601f85011601826136cc565b8181528460208386010111156137e557600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561381a57600080fd5b853561382581613592565b9450602086013561383581613592565b9350604086013567ffffffffffffffff8082111561385257600080fd5b61385e89838a0161371d565b9450606088013591508082111561387457600080fd5b61388089838a0161371d565b9350608088013591508082111561389657600080fd5b506138a38882890161378e565b9150509295509295909350565b6000815180845260005b818110156138d6576020818501810151868301820152016138ba565b818111156138e8576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006103bd60208301846138b0565b6000806040838503121561392357600080fd5b823567ffffffffffffffff8082111561393b57600080fd5b818501915085601f83011261394f57600080fd5b8135602061395c826136f9565b60405161396982826136cc565b83815260059390931b850182019282810191508984111561398957600080fd5b948201945b838610156139b05785356139a181613592565b8252948201949082019061398e565b965050860135925050808211156139c657600080fd5b506139d38582860161371d565b9150509250929050565b600081518084526020808501945080840160005b83811015613a0d578151875295820195908201906001016139f1565b509495945050505050565b6020815260006103bd60208301846139dd565b600060208284031215613a3d57600080fd5b813561161381613592565b803567ffffffffffffffff8116811461298c57600080fd5b803560ff8116811461298c57600080fd5b803561ffff8116811461298c57600080fd5b60008083601f840112613a9557600080fd5b50813567ffffffffffffffff811115613aad57600080fd5b60208301915083602082850101111561312357600080fd5b600080600083850360c0811215613adb57600080fd5b60a0811215613ae957600080fd5b5060405160a0810167ffffffffffffffff8282108183111715613b0e57613b0e613657565b8160405286359150613b1f82613592565b818352613b2e60208801613a48565b6020840152613b3f60408801613a60565b6040840152613b5060608801613a60565b6060840152613b6160808801613a71565b608084015291945060a08601359180831115613b7c57600080fd5b5050613b8a86828701613a83565b9497909650939450505050565b60008060006040808587031215613bad57600080fd5b843567ffffffffffffffff80821115613bc557600080fd5b8187019150606080838a031215613bdb57600080fd5b8351613be681613686565b8335613bf181613592565b81526020613c00858201613a48565b818301528585013584811115613c1557600080fd5b8086019550508a601f860112613c2a57600080fd5b8435613c35816136f9565b8751613c4182826136cc565b82815260079290921b870183019183810191508d831115613c6157600080fd5b968301965b82881015613cd4576080888f031215613c7f5760008081fd5b8851613c8a816136ac565b613c9389613a71565b8152613ca0858a01613a71565b85820152613caf8a8a01613a71565b8a820152613cbe878a01613a71565b8188015282526080979097019690830190613c66565b978401979097525090975088013593505080831115613b7c57600080fd5b60008060408385031215613d0557600080fd5b8235613d1081613592565b91506020830135801515811461364c57600080fd5b600080600080600060a08688031215613d3d57600080fd5b8535613d4881613592565b94506020860135613d5881613592565b93506040860135925060608601359150608086013567ffffffffffffffff811115613d8257600080fd5b6138a38882890161378e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613e5357613e53613dec565b500290565b600060208284031215613e6a57600080fd5b815161161381613592565b600060ff821660ff84168060ff03821115613e9257613e92613dec565b019392505050565b60008219821115613ead57613ead613dec565b500190565b600060ff821660ff8103613ec857613ec8613dec565b60010192915050565b600061ffff808316818516808303821115613eee57613eee613dec565b01949350505050565b600060208284031215613f0957600080fd5b5051919050565b604081526000613f2360408301856139dd565b828103602084015261054181856139dd565b60006001600160a01b03808816835280871660208401525060a06040830152613f6160a08301866139dd565b8281036060840152613f7381866139dd565b90508281036080840152613f8781856138b0565b98975050505050505050565b600060208284031215613fa557600080fd5b8151611613816135d3565b600060033d11156113b85760046000803e5060005160e01c90565b600060443d1015613fd95790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561402757505050505090565b828501915081518181111561403f5750505050505090565b843d87010160208285010111156140595750505050505090565b614068602082860101876136cc565b509095945050505050565b600062ffffff808316818516808303821115613eee57613eee613dec565b600067ffffffffffffffff808316818516808303821115613eee57613eee613dec565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526140ec60a08301846138b0565b97965050505050505056fea2646970667358221220bec2cd92a8e3ae6e4d1edef7c0913c162500323fda50396d0e7662b097e655e964736f6c634300080e0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.