: RILLAZ DEPIX (DEPIX)
Overview
TokenID
150
Total Transfers
-
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Depix
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity)
/** *Submitted for verification at curtis.apescan.io on 2024-11-27 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.28; // lib/creator-token-standards/src/interfaces/ICreatorToken.sol interface ICreatorToken { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction); } // lib/creator-token-standards/src/interfaces/ICreatorTokenLegacy.sol interface ICreatorTokenLegacy { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (address validator); function setTransferValidator(address validator) external; } // lib/creator-token-standards/src/interfaces/ITransferValidator.sol interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId) external view; function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external; function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external; function afterAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransfer(address operator, address token) external; function afterAuthorizedTransfer(address token) external; function beforeAuthorizedTransfer(address token, uint256 tokenId) external; function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external; function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external; } // lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // lib/openzeppelin-contracts/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // lib/openzeppelin-contracts/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol) /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // lib/openzeppelin-contracts/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // lib/creator-token-standards/src/access/OwnablePermissions.sol abstract contract OwnablePermissions is Context { function _requireCallerIsContractOwner() internal view virtual; } // lib/creator-token-standards/src/utils/TransferValidation.sol /** * @title TransferValidation * @author Limit Break, Inc. * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks. * Openzeppelin's ERC721 contract only provides hooks for before and after transfer. This allows * developers to validate or customize transfers within the context of a mint, a burn, or a transfer. */ abstract contract TransferValidation is Context { /// @dev Thrown when the from and to address are both the zero address. error ShouldNotMintToBurnAddress(); /*************************************************************************/ /* Transfers Without Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /*************************************************************************/ /* Transfers With Amounts */ /*************************************************************************/ /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, amount, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, amount, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {} } // lib/openzeppelin-contracts/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } // lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // lib/openzeppelin-contracts/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // lib/creator-token-standards/src/utils/AutomaticValidatorTransferApproval.sol /** * @title AutomaticValidatorTransferApproval * @author Limit Break, Inc. * @notice Base contract mix-in that provides boilerplate code giving the contract owner the * option to automatically approve a 721-C transfer validator implementation for transfers. */ abstract contract AutomaticValidatorTransferApproval is OwnablePermissions { /// @dev Emitted when the automatic approval flag is modified by the creator. event AutomaticApprovalOfTransferValidatorSet(bool autoApproved); /// @dev If true, the collection's transfer validator is automatically approved to transfer holder's tokens. bool public autoApproveTransfersFromValidator; /** * @notice Sets if the transfer validator is automatically approved as an operator for all token owners. * * @dev Throws when the caller is not the contract owner. * * @param autoApprove If true, the collection's transfer validator will be automatically approved to * transfer holder's tokens. */ function setAutomaticApprovalOfTransfersFromValidator(bool autoApprove) external { _requireCallerIsContractOwner(); autoApproveTransfersFromValidator = autoApprove; emit AutomaticApprovalOfTransferValidatorSet(autoApprove); } } // lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // lib/creator-token-standards/src/access/OwnableBasic.sol abstract contract OwnableBasic is OwnablePermissions, Ownable { function _requireCallerIsContractOwner() internal view virtual override { _checkOwner(); } } // lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // lib/creator-token-standards/src/programmable-royalties/BasicRoyalties.sol /** * @title BasicRoyaltiesBase * @author Limit Break, Inc. * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties. */ abstract contract BasicRoyaltiesBase is ERC2981 { event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator); event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator); function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { super._setDefaultRoyalty(receiver, feeNumerator); emit DefaultRoyaltySet(receiver, feeNumerator); } function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override { super._setTokenRoyalty(tokenId, receiver, feeNumerator); emit TokenRoyaltySet(tokenId, receiver, feeNumerator); } } /** * @title BasicRoyalties * @author Limit Break, Inc. * @notice Constructable BasicRoyalties Contract implementation. */ abstract contract BasicRoyalties is BasicRoyaltiesBase { constructor(address receiver, uint96 feeNumerator) { _setDefaultRoyalty(receiver, feeNumerator); } } /** * @title BasicRoyaltiesInitializable * @author Limit Break, Inc. * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. */ abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {} // src/PhaseManager.sol error NoActivePhase(); error InvalidTimestamps(); error InvalidLimits(); error InvalidPhaseType(); error NoTwinPhase(); error NotWhitelisted(); error InvalidPhaseConfiguration(); enum PhaseType { NONE, TWIN_PHASE1, TWIN_PHASE2, ALBARRA_OG_WL, RILLAZ_HOLDER_WL, COMMUNITY_WL, PUBLIC_SALE } contract PhaseManager is OwnableBasic { struct Phase { bytes32 merkleRoot; uint96 price; uint64 start; uint64 end; uint8 maxPerWallet; uint16 maxSupplyPerPhase; } // State variables mapping(PhaseType => Phase) public phases; function configurePhase( PhaseType phaseType, bytes32 merkleRoot, uint96 price, uint64 start, uint64 end, uint8 maxPerWallet, uint16 maxSupplyPerPhase ) external { _requireCallerIsContractOwner(); if (phaseType == PhaseType.NONE) revert InvalidPhaseType(); if (end <= start) revert InvalidTimestamps(); if (maxPerWallet == 0) revert InvalidLimits(); if (maxSupplyPerPhase == 0) revert InvalidLimits(); phases[phaseType] = Phase({ merkleRoot: merkleRoot, price: price, start: start, end: end, maxPerWallet: maxPerWallet, maxSupplyPerPhase: maxSupplyPerPhase }); } function currentPhase() public view returns (Phase memory, PhaseType) { uint256 currentTimestamp = block.timestamp; for ( PhaseType i = PhaseType.TWIN_PHASE1; i <= type(PhaseType).max; i = PhaseType(uint8(i) + 1) ) { if ( currentTimestamp >= phases[i].start && currentTimestamp <= phases[i].end ) { return (phases[i], i); } } return (phases[PhaseType.NONE], PhaseType.NONE); } function isWhitelistedForPhase( PhaseType phaseType, address user, bytes32[] calldata merkleProof ) public view returns (bool) { return MerkleProof.verify( merkleProof, phases[phaseType].merkleRoot, keccak256(abi.encodePacked(user)) ); } } // lib/creator-token-standards/src/utils/CreatorTokenBase.sol /** * @title CreatorTokenBase * @author Limit Break, Inc. * @notice CreatorTokenBaseV3 is an abstract contract that provides basic functionality for managing token * transfer policies through an implementation of ICreatorTokenTransferValidator/ICreatorTokenTransferValidatorV2/ICreatorTokenTransferValidatorV3. * This contract is intended to be used as a base for creator-specific token contracts, enabling customizable transfer * restrictions and security policies. * * <h4>Features:</h4> * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul> * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul> * * <h4>Benefits:</h4> * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul> * <ul>Allows creators to enforce policies such as account and codehash blacklists, whitelists, and graylists.</ul> * <ul>Can be easily integrated into other token contracts as a base contract.</ul> * * <h4>Intended Usage:</h4> * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and * security policies.</ul> * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the * creator token.</ul> * * <h4>Compatibility:</h4> * <ul>Backward and Forward Compatible - V1/V2/V3 Creator Token Base will work with V1/V2/V3 Transfer Validators.</ul> */ abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken { /// @dev Thrown when setting a transfer validator address that has no deployed code. error CreatorTokenBase__InvalidTransferValidatorContract(); /// @dev The default transfer validator that will be used if no transfer validator has been set by the creator. address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x721C00182a990771244d7A71B9FA2ea789A3b433); /// @dev Used to determine if the default transfer validator is applied. /// @dev Set to true when the creator sets a transfer validator address. bool private isValidatorInitialized; /// @dev Address of the transfer validator to apply to transactions. address private transferValidator; /** * @notice Sets the transfer validator for the token contract. * * @dev Throws when provided validator contract is not the zero address and does not have code. * @dev Throws when the caller is not the contract owner. * * @dev <h4>Postconditions:</h4> * 1. The transferValidator address is updated. * 2. The `TransferValidatorUpdated` event is emitted. * * @param transferValidator_ The address of the transfer validator contract. */ function setTransferValidator(address transferValidator_) public { _requireCallerIsContractOwner(); bool isValidTransferValidator = transferValidator_.code.length > 0; if(transferValidator_ != address(0) && !isValidTransferValidator) { revert CreatorTokenBase__InvalidTransferValidatorContract(); } emit TransferValidatorUpdated(address(getTransferValidator()), transferValidator_); isValidatorInitialized = true; transferValidator = transferValidator_; } /** * @notice Returns the transfer validator contract address for this token contract. */ function getTransferValidator() public view override returns (address validator) { validator = transferValidator; if (validator == address(0)) { if (!isValidatorInitialized) { validator = DEFAULT_TRANSFER_VALIDATOR; } } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId); } } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the * transfer validator is expected to pre-validate the transfer. * * @dev Used for ERC20 and ERC1155 token transfers which have an amount value to validate in the transfer validator. * @dev The `tokenId` for ERC20 tokens should be set to `0`. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. * @param tokenId The token id being transferred. * @param amount The amount of token being transferred. */ function _preValidateTransfer( address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 /*value*/) internal virtual override { address validator = getTransferValidator(); if (validator != address(0)) { if (msg.sender == validator) { return; } ITransferValidator(validator).validateTransfer(caller, from, to, tokenId, amount); } } } // lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol) /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // lib/creator-token-standards/src/token/erc721/ERC721OpenZeppelin.sol abstract contract ERC721OpenZeppelinBase is ERC721 { // Token name string internal _contractName; // Token symbol string internal _contractSymbol; function name() public view virtual override returns (string memory) { return _contractName; } function symbol() public view virtual override returns (string memory) { return _contractSymbol; } function _setNameAndSymbol(string memory name_, string memory symbol_) internal { _contractName = name_; _contractSymbol = symbol_; } } abstract contract ERC721OpenZeppelin is ERC721OpenZeppelinBase { constructor(string memory name_, string memory symbol_) ERC721("", "") { _setNameAndSymbol(name_, symbol_); } } abstract contract ERC721OpenZeppelinInitializable is OwnablePermissions, ERC721OpenZeppelinBase { error ERC721OpenZeppelinInitializable__AlreadyInitializedERC721(); /// @notice Specifies whether or not the contract is initialized bool private _erc721Initialized; /// @dev Initializes parameters of ERC721 tokens. /// These cannot be set in the constructor because this contract is optionally compatible with EIP-1167. function initializeERC721(string memory name_, string memory symbol_) public { _requireCallerIsContractOwner(); if(_erc721Initialized) { revert ERC721OpenZeppelinInitializable__AlreadyInitializedERC721(); } _erc721Initialized = true; _setNameAndSymbol(name_, symbol_); } } // lib/creator-token-standards/src/erc721c/ERC721C.sol /** * @title ERC721C * @author Limit Break, Inc. * @notice Extends OpenZeppelin's ERC721 implementation with Creator Token functionality, which * allows the contract owner to update the transfer validation logic by managing a security policy in * an external transfer validation security policy registry. See {CreatorTokenTransferValidator}. */ abstract contract ERC721C is ERC721OpenZeppelin, CreatorTokenBase, AutomaticValidatorTransferApproval { /** * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved * for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { isApproved = super.isApprovedForAll(owner, operator); if (!isApproved) { if (autoApproveTransfersFromValidator) { isApproved = operator == address(getTransferValidator()); } } } /** * @notice Indicates whether the contract implements the specified interface. * @dev Overrides supportsInterface in ERC165. * @param interfaceId The interface id * @return true if the contract implements the specified interface, false otherwise */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || interfaceId == type(ICreatorTokenLegacy).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Returns the function selector for the transfer validator's validation function to be called * @notice for transaction simulation. */ function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)")); isViewFunction = true; } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateBeforeTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateAfterTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } } /** * @title ERC721CInitializable * @author Limit Break, Inc. * @notice Initializable implementation of ERC721C to allow for EIP-1167 proxy clones. */ abstract contract ERC721CInitializable is ERC721OpenZeppelinInitializable, CreatorTokenBase, AutomaticValidatorTransferApproval { /** * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved * for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { isApproved = super.isApprovedForAll(owner, operator); if (!isApproved) { if (autoApproveTransfersFromValidator) { isApproved = operator == address(getTransferValidator()); } } } /** * @notice Indicates whether the contract implements the specified interface. * @dev Overrides supportsInterface in ERC165. * @param interfaceId The interface id * @return true if the contract implements the specified interface, false otherwise */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || interfaceId == type(ICreatorTokenLegacy).interfaceId || super.supportsInterface(interfaceId); } /** * @notice Returns the function selector for the transfer validator's validation function to be called * @notice for transaction simulation. */ function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)")); isViewFunction = true; } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateBeforeTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual override { for (uint256 i = 0; i < batchSize;) { _validateAfterTransfer(from, to, firstTokenId + i); unchecked { ++i; } } } } // src/Depix.sol error IncorrectValue(); error AlreadyMinted(); error NotOwner(); error TransferFailed(); error TwinSupplyReached(); error MaxSupplyReached(); error MaxPerWalletExceeded(); error InvalidAmount(); error InvalidAddress(); error InvalidURI(); error InvalidPhase(); error InvalidProof(); abstract contract RILLAZC { function ownerOf(uint256 tokenId) public view virtual returns (address); } contract Depix is ERC721C, BasicRoyalties, OwnableBasic { RILLAZC immutable RILLAZ; PhaseManager immutable phaseManager; address immutable MINT_FUNDS_RECEIVER; uint256 constant MAX_SUPPLY = 10000; uint256 constant TWIN_MAX_SUPPLY = 3500; uint256 public currentSupply; uint256 public tokenCounter = 10000; string private baseTokenURI; mapping(uint256 => bool) public hasTwinMap; mapping(PhaseType => uint256) public mintedPerPhase; mapping(address => mapping(PhaseType => uint256)) public userMintedPerPhase; constructor( address royaltyReceiver_, uint96 royaltyFeeNumerator_, string memory name_, string memory symbol_, RILLAZC rillaz_, PhaseManager phaseManager_ ) ERC721OpenZeppelin(name_, symbol_) BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_) OwnableBasic() { if (royaltyReceiver_ == address(0)) revert InvalidAddress(); if (address(rillaz_) == address(0)) revert InvalidAddress(); if (address(phaseManager_) == address(0)) revert InvalidAddress(); RILLAZ = rillaz_; phaseManager = phaseManager_; MINT_FUNDS_RECEIVER = royaltyReceiver_; } function mintTwin( uint256[] calldata tokenIds, bytes32[] calldata merkleProof ) external payable { uint256 len = tokenIds.length; if (len == 0) revert InvalidAmount(); (PhaseManager.Phase memory phase, PhaseType phaseType) = phaseManager.currentPhase(); if (phaseType == PhaseType.NONE || phaseType > PhaseType.TWIN_PHASE2) revert NoTwinPhase(); if (userMintedPerPhase[msg.sender][phaseType] + len > phase.maxPerWallet) revert MaxPerWalletExceeded(); if (twinSupply() + len > TWIN_MAX_SUPPLY) revert TwinSupplyReached(); bool isWhitelisted = phaseManager.isWhitelistedForPhase(phaseType, msg.sender, merkleProof); if (isWhitelisted && msg.value != 0) revert IncorrectValue(); userMintedPerPhase[msg.sender][phaseType] += len; mintedPerPhase[phaseType] += len; currentSupply += len; for (uint256 i = 0; i < len; i++) { if (RILLAZ.ownerOf(tokenIds[i]) != msg.sender) revert NotOwner(); if (hasTwinMap[tokenIds[i]]) revert AlreadyMinted(); hasTwinMap[tokenIds[i]] = true; _mint(msg.sender, tokenIds[i]); } if (!isWhitelisted) { uint256 mintCost = phase.price * len; if (msg.value != mintCost) revert IncorrectValue(); (bool success, ) = MINT_FUNDS_RECEIVER.call{value: msg.value}(""); if (!success) revert TransferFailed(); } } function publicMint( uint256 amount, bytes32[] calldata merkleProof ) external payable { if (amount == 0) revert InvalidAmount(); (PhaseManager.Phase memory phase, PhaseType phaseType) = phaseManager.currentPhase(); if (phaseType <= PhaseType.TWIN_PHASE2) revert InvalidPhase(); if (userMintedPerPhase[msg.sender][phaseType] + amount > phase.maxPerWallet) revert MaxPerWalletExceeded(); if (currentSupply + amount > MAX_SUPPLY) revert MaxSupplyReached(); if (mintedPerPhase[phaseType] + amount > phase.maxSupplyPerPhase) revert MaxSupplyReached(); if (phaseType < PhaseType.PUBLIC_SALE) { if (merkleProof.length == 0) revert InvalidProof(); if (!phaseManager.isWhitelistedForPhase(phaseType, msg.sender, merkleProof)) revert NotWhitelisted(); } if (phase.price > 0) { uint256 mintCost = phase.price * amount; if (msg.value != mintCost) revert IncorrectValue(); } else { if (msg.value != 0) revert IncorrectValue(); } // Update state userMintedPerPhase[msg.sender][phaseType] += amount; mintedPerPhase[phaseType] += amount; currentSupply += amount; if (phase.price > 0) { (bool success, ) = MINT_FUNDS_RECEIVER.call{value: msg.value}(""); if (!success) revert TransferFailed(); } for (uint256 i = 0; i < amount; i++) { _mint(msg.sender, tokenCounter); tokenCounter++; } } function setDefaultRoyalty(address receiver, uint96 feeNumerator) public { _requireCallerIsContractOwner(); _setDefaultRoyalty(receiver, feeNumerator); } function setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) public { _requireCallerIsContractOwner(); _setTokenRoyalty(tokenId, receiver, feeNumerator); } function setBaseURI(string calldata baseURI) external { _requireCallerIsContractOwner(); if (bytes(baseURI).length == 0) revert InvalidURI(); baseTokenURI = baseURI; } function twinSupply() public view returns (uint256) { return mintedPerPhase[PhaseType.TWIN_PHASE1] + mintedPerPhase[PhaseType.TWIN_PHASE2]; } function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC721C, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } function _baseURI() internal view override returns (string memory) { return baseTokenURI; } function getMintedPerPhase(PhaseType phaseType) external view returns (uint256) { return mintedPerPhase[phaseType]; } function getUserMintedPerPhase(address user, PhaseType phaseType) external view returns (uint256) { return userMintedPerPhase[user][phaseType]; } }
[{"inputs":[{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyFeeNumerator_","type":"uint96"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract RILLAZC","name":"rillaz_","type":"address"},{"internalType":"contract PhaseManager","name":"phaseManager_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyMinted","type":"error"},{"inputs":[],"name":"CreatorTokenBase__InvalidTransferValidatorContract","type":"error"},{"inputs":[],"name":"IncorrectValue","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidPhase","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidURI","type":"error"},{"inputs":[],"name":"MaxPerWalletExceeded","type":"error"},{"inputs":[],"name":"MaxSupplyReached","type":"error"},{"inputs":[],"name":"NoTwinPhase","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"ShouldNotMintToBurnAddress","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TwinSupplyReached","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"autoApproved","type":"bool"}],"name":"AutomaticApprovalOfTransferValidatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"TokenRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldValidator","type":"address"},{"indexed":false,"internalType":"address","name":"newValidator","type":"address"}],"name":"TransferValidatorUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_TRANSFER_VALIDATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoApproveTransfersFromValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum PhaseType","name":"phaseType","type":"uint8"}],"name":"getMintedPerPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferValidationFunction","outputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"},{"internalType":"bool","name":"isViewFunction","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTransferValidator","outputs":[{"internalType":"address","name":"validator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum PhaseType","name":"phaseType","type":"uint8"}],"name":"getUserMintedPerPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hasTwinMap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isApproved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"mintTwin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum PhaseType","name":"","type":"uint8"}],"name":"mintedPerPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"autoApprove","type":"bool"}],"name":"setAutomaticApprovalOfTransfersFromValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"transferValidator_","type":"address"}],"name":"setTransferValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twinSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"enum PhaseType","name":"","type":"uint8"}],"name":"userMintedPerPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e0604052612710600d5534801561001657600080fd5b50604051613767380380613767833981016040819052610035916103d1565b8585858560405180602001604052806000815250604051806020016040528060008152508160009081610068919061051c565b506001610075828261051c565b505050610088828261013960201b60201c565b5061009590508282610157565b506100a19050336101ac565b6001600160a01b0386166100c85760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0382166100ef5760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0381166101165760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03918216608052811660a0529390931660c052506105da915050565b6006610145838261051c565b506007610152828261051c565b505050565b61016182826101fe565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b03821611156102715760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b0382166102c75760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610268565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600955565b6001600160a01b038116811461031557600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261033f57600080fd5b81516001600160401b0381111561035857610358610318565b604051601f8201601f19908116603f011681016001600160401b038111828210171561038657610386610318565b60405281815283820160200185101561039e57600080fd5b60005b828110156103bd576020818601810151838301820152016103a1565b506000918101602001919091529392505050565b60008060008060008060c087890312156103ea57600080fd5b86516103f581610300565b60208801519096506001600160601b038116811461041257600080fd5b60408801519095506001600160401b0381111561042e57600080fd5b61043a89828a0161032e565b606089015190955090506001600160401b0381111561045857600080fd5b61046489828a0161032e565b935050608087015161047581610300565b60a088015190925061048681610300565b809150509295509295509295565b600181811c908216806104a857607f821691505b6020821081036104c857634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561015257806000526020600020601f840160051c810160208510156104f55750805b601f840160051c820191505b818110156105155760008155600101610501565b5050505050565b81516001600160401b0381111561053557610535610318565b610549816105438454610494565b846104ce565b6020601f82116001811461057d57600083156105655750848201515b600019600385901b1c1916600184901b178455610515565b600084815260208120601f198516915b828110156105ad578785015182556020948501946001909201910161058d565b50848210156105cb5786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b60805160a05160c05161314261062560003960008181610e15015261179601526000818161093801528181610ad20152818161139d01526115b701526000610c4301526131426000f3fe60806040526004361061020f5760003560e01c806370a0823111610118578063c87b56dd116100a0578063eef998101161006f578063eef9981014610644578063f2fde38b14610657578063f631e96914610677578063f9528e2a1461068c578063ffe5387e146106bc57600080fd5b8063c87b56dd146105c1578063d082e381146105e1578063d2bf6492146105f7578063e985e9c51461062457600080fd5b806395d89b41116100e757806395d89b411461052c5780639e05d24014610541578063a22cb46514610561578063a9fc664e14610581578063b88d4fde146105a157600080fd5b806370a08231146104c3578063715018a6146104e3578063771282f6146104f85780638da5cb5b1461050e57600080fd5b806323b872dd1161019b5780635944c7531161016a5780635944c753146103fc5780635f555fb91461041c5780636221d13c146104625780636352211e14610483578063659f875b146104a357600080fd5b806323b872dd1461035d5780632a55205a1461037d57806342842e0e146103bc57806355f804b3146103dc57600080fd5b8063081812fc116101e2578063081812fc146102cd578063095ea7b3146102ed578063098144d41461030d5780630d705df6146103225780632157c6491461034a57600080fd5b8063014635461461021457806301ffc9a71461025957806304634d8d1461028957806306fdde03146102ab575b600080fd5b34801561022057600080fd5b5061023c73721c00182a990771244d7a71b9fa2ea789a3b43381565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026557600080fd5b50610279610274366004612679565b6106dc565b6040519015158152602001610250565b34801561029557600080fd5b506102a96102a43660046126c0565b6106ed565b005b3480156102b757600080fd5b506102c0610703565b6040516102509190612749565b3480156102d957600080fd5b5061023c6102e836600461275c565b610795565b3480156102f957600080fd5b506102a9610308366004612775565b6107bc565b34801561031957600080fd5b5061023c6108d6565b34801561032e57600080fd5b506040805163657711f560e11b81526001602082015201610250565b6102a96103583660046127e5565b610910565b34801561036957600080fd5b506102a9610378366004612854565b610eb2565b34801561038957600080fd5b5061039d610398366004612895565b610ee3565b604080516001600160a01b039093168352602083019190915201610250565b3480156103c857600080fd5b506102a96103d7366004612854565b610f91565b3480156103e857600080fd5b506102a96103f73660046128b7565b610fac565b34801561040857600080fd5b506102a9610417366004612929565b610fe3565b34801561042857600080fd5b50610454610437366004612978565b601160209081526000928352604080842090915290825290205481565b604051908152602001610250565b34801561046e57600080fd5b5060085461027990600160a81b900460ff1681565b34801561048f57600080fd5b5061023c61049e36600461275c565b610ff6565b3480156104af57600080fd5b506104546104be366004612978565b611056565b3480156104cf57600080fd5b506104546104de3660046129a6565b6110a9565b3480156104ef57600080fd5b506102a961112f565b34801561050457600080fd5b50610454600c5481565b34801561051a57600080fd5b50600b546001600160a01b031661023c565b34801561053857600080fd5b506102c0611143565b34801561054d57600080fd5b506102a961055c3660046129d1565b611152565b34801561056d57600080fd5b506102a961057c3660046129ee565b6111b2565b34801561058d57600080fd5b506102a961059c3660046129a6565b6111bd565b3480156105ad57600080fd5b506102a96105bc366004612a8a565b611274565b3480156105cd57600080fd5b506102c06105dc36600461275c565b6112ac565b3480156105ed57600080fd5b50610454600d5481565b34801561060357600080fd5b50610454610612366004612b51565b60106020526000908152604090205481565b34801561063057600080fd5b5061027961063f366004612b6e565b611313565b6102a9610652366004612b9c565b611377565b34801561066357600080fd5b506102a96106723660046129a6565b611864565b34801561068357600080fd5b506104546118dd565b34801561069857600080fd5b506102796106a736600461275c565b600f6020526000908152604090205460ff1681565b3480156106c857600080fd5b506104546106d7366004612b51565b61193d565b60006106e78261197c565b92915050565b6106f56119a1565b6106ff82826119a9565b5050565b60606006805461071290612be7565b80601f016020809104026020016040519081016040528092919081815260200182805461073e90612be7565b801561078b5780601f106107605761010080835404028352916020019161078b565b820191906000526020600020905b81548152906001019060200180831161076e57829003601f168201915b5050505050905090565b60006107a0826119fe565b506000908152600460205260409020546001600160a01b031690565b60006107c782610ff6565b9050806001600160a01b0316836001600160a01b0316036108395760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061085557506108558133611313565b6108c75760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610830565b6108d18383611a5d565b505050565b60085461010090046001600160a01b03168061090d5760085460ff1661090d575073721c00182a990771244d7a71b9fa2ea789a3b4335b90565b8260008190036109335760405163162908e360e11b815260040160405180910390fd5b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663055ad42e6040518163ffffffff1660e01b815260040160e060405180830381865afa158015610994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b89190612c5a565b909250905060008160068111156109d1576109d1612cff565b14806109ee575060028160068111156109ec576109ec612cff565b115b15610a0c57604051635ce1196360e01b815260040160405180910390fd5b608082015133600090815260116020526040812060ff909216918591846006811115610a3a57610a3a612cff565b6006811115610a4b57610a4b612cff565b815260200190815260200160002054610a649190612d2b565b1115610a8357604051637ab0312d60e11b815260040160405180910390fd5b610dac83610a8f6118dd565b610a999190612d2b565b1115610ab857604051637201d58360e01b815260040160405180910390fd5b60405163f31755b760e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f31755b790610b0d90859033908b908b90600401612d3e565b602060405180830381865afa158015610b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4e9190612dad565b9050808015610b5c57503415155b15610b7a57604051636956f2ab60e11b815260040160405180910390fd5b3360009081526011602052604081208591846006811115610b9d57610b9d612cff565b6006811115610bae57610bae612cff565b81526020019081526020016000206000828254610bcb9190612d2b565b9091555084905060106000846006811115610be857610be8612cff565b6006811115610bf957610bf9612cff565b81526020019081526020016000206000828254610c169190612d2b565b9250508190555083600c6000828254610c2f9190612d2b565b90915550600090505b84811015610dce57337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e8b8b85818110610c8257610c82612dca565b905060200201356040518263ffffffff1660e01b8152600401610ca791815260200190565b602060405180830381865afa158015610cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce89190612de0565b6001600160a01b031614610d0f576040516330cd747160e01b815260040160405180910390fd5b600f60008a8a84818110610d2557610d25612dca565b602090810292909201358352508101919091526040016000205460ff1615610d6057604051631bbdf5c560e31b815260040160405180910390fd5b6001600f60008b8b85818110610d7857610d78612dca565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550610dc6338a8a84818110610dba57610dba612dca565b90506020020135611acb565b600101610c38565b5080610ea85760008484602001516001600160601b0316610def9190612dfd565b9050803414610e1157604051636956f2ab60e11b815260040160405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d8060008114610e7e576040519150601f19603f3d011682016040523d82523d6000602084013e610e83565b606091505b5050905080610ea5576040516312171d8360e31b815260040160405180910390fd5b50505b5050505050505050565b610ebc3382611c6e565b610ed85760405162461bcd60e51b815260040161083090612e14565b6108d1838383611ccd565b6000828152600a602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610f585750604080518082019091526009546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610f77906001600160601b031687612dfd565b610f819190612e61565b91519350909150505b9250929050565b6108d183838360405180602001604052806000815250611274565b610fb46119a1565b6000819003610fd657604051633ba0191160e01b815260040160405180910390fd5b600e6108d1828483612eca565b610feb6119a1565b6108d1838383611e46565b6000818152600260205260408120546001600160a01b0316806106e75760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610830565b6001600160a01b03821660009081526011602052604081208183600681111561108157611081612cff565b600681111561109257611092612cff565b815260200190815260200160002054905092915050565b60006001600160a01b0382166111135760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610830565b506001600160a01b031660009081526003602052604090205490565b611137611ea0565b6111416000611efa565b565b60606007805461071290612be7565b61115a6119a1565b60088054821515600160a81b0260ff60a81b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc906111a790831515815260200190565b60405180910390a150565b6106ff338383611f4c565b6111c56119a1565b6001600160a01b038116803b151590158015906111e0575080155b156111fe576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac6112276108d6565b604080516001600160a01b03928316815291851660208301520160405180910390a150600880546001600160a01b03909216610100026001600160a81b0319909216919091176001179055565b61127e3383611c6e565b61129a5760405162461bcd60e51b815260040161083090612e14565b6112a684848484612012565b50505050565b60606112b7826119fe565b60006112c1612045565b905060008151116112e1576040518060200160405280600081525061130c565b806112eb84612054565b6040516020016112fc929190612f89565b6040516020818303038152906040525b9392505050565b6001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff16806106e757600854600160a81b900460ff16156106e75761135b6108d6565b6001600160a01b0316826001600160a01b031614905092915050565b826000036113985760405163162908e360e11b815260040160405180910390fd5b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663055ad42e6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156113f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141d9190612c5a565b9092509050600281600681111561143657611436612cff565b116114545760405163268dbf6760e21b815260040160405180910390fd5b608082015133600090815260116020526040812060ff90921691879184600681111561148257611482612cff565b600681111561149357611493612cff565b8152602001908152602001600020546114ac9190612d2b565b11156114cb57604051637ab0312d60e11b815260040160405180910390fd5b61271085600c546114dc9190612d2b565b11156114fb5760405163d05cb60960e01b815260040160405180910390fd5b8160a0015161ffff16856010600084600681111561151b5761151b612cff565b600681111561152c5761152c612cff565b8152602001908152602001600020546115459190612d2b565b11156115645760405163d05cb60960e01b815260040160405180910390fd5b600681600681111561157857611578612cff565b10156116505760008390036115a0576040516309bde33960e01b815260040160405180910390fd5b60405163f31755b760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f31755b7906115f2908490339089908990600401612d3e565b602060405180830381865afa15801561160f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116339190612dad565b61165057604051630b094f2760e31b815260040160405180910390fd5b60208201516001600160601b0316156116a65760008583602001516001600160601b031661167e9190612dfd565b90508034146116a057604051636956f2ab60e11b815260040160405180910390fd5b506116c5565b34156116c557604051636956f2ab60e11b815260040160405180910390fd5b33600090815260116020526040812086918360068111156116e8576116e8612cff565b60068111156116f9576116f9612cff565b815260200190815260200160002060008282546117169190612d2b565b909155508590506010600083600681111561173357611733612cff565b600681111561174457611744612cff565b815260200190815260200160002060008282546117619190612d2b565b9250508190555084600c600082825461177a9190612d2b565b909155505060208201516001600160601b0316156118285760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d80600081146117ff576040519150601f19603f3d011682016040523d82523d6000602084013e611804565b606091505b5050905080611826576040516312171d8360e31b815260040160405180910390fd5b505b60005b8581101561185c5761183f33600d54611acb565b600d805490600061184f83612fb8565b909155505060010161182b565b505050505050565b61186c611ea0565b6001600160a01b0381166118d15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610830565b6118da81611efa565b50565b60106020527f853b2fefe141400fef543280f93d98bd49996069f632d0d20236afeeed8e46a254600160009081527f8c6065603763fec3f5742441d3833f3f43b982453612d76adb39a885e3006b5f54909161193891612d2b565b905090565b60006010600083600681111561195557611955612cff565b600681111561196657611966612cff565b8152602001908152602001600020549050919050565b60006001600160e01b0319821663152a902d60e11b14806106e757506106e7826120e6565b611141611ea0565b6119b38282612126565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6000818152600260205260409020546001600160a01b03166118da5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610830565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a9282610ff6565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b038216611b215760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610830565b6000818152600260205260409020546001600160a01b031615611b865760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610830565b611b946000838360016121e0565b6000818152600260205260409020546001600160a01b031615611bf95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610830565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46106ff60008383600161220e565b600080611c7a83610ff6565b9050806001600160a01b0316846001600160a01b03161480611ca15750611ca18185611313565b80611cc55750836001600160a01b0316611cba84610795565b6001600160a01b0316145b949350505050565b826001600160a01b0316611ce082610ff6565b6001600160a01b031614611d065760405162461bcd60e51b815260040161083090612fd1565b6001600160a01b038216611d685760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610830565b611d7583838360016121e0565b826001600160a01b0316611d8882610ff6565b6001600160a01b031614611dae5760405162461bcd60e51b815260040161083090612fd1565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a46108d1838383600161220e565b611e51838383612235565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b600b546001600160a01b031633146111415760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610830565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603611fad5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610830565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101611e93565b61201d848484611ccd565b61202984848484612300565b6112a65760405162461bcd60e51b815260040161083090613016565b6060600e805461071290612be7565b6060600061206183612401565b60010190506000816001600160401b0381111561208057612080612a1c565b6040519080825280601f01601f1916602001820160405280156120aa576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846120b457509392505050565b60006001600160e01b03198216632b435fdb60e21b148061211757506001600160e01b0319821663503e914d60e11b145b806106e757506106e7826124d9565b6127106001600160601b03821611156121515760405162461bcd60e51b815260040161083090613068565b6001600160a01b0382166121a75760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610830565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600955565b60005b81811015612207576121ff85856121fa8487612d2b565b612529565b6001016121e3565b5050505050565b60005b818110156122075761222d85856122288487612d2b565b61257f565b600101612211565b6127106001600160601b03821611156122605760405162461bcd60e51b815260040161083090613068565b6001600160a01b0382166122b65760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610830565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600a90529190942093519051909116600160a01b029116179055565b60006001600160a01b0384163b156123f657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906123449033908990889088906004016130b2565b6020604051808303816000875af192505050801561237f575060408051601f3d908101601f1916820190925261237c918101906130ef565b60015b6123dc573d8080156123ad576040519150601f19603f3d011682016040523d82523d6000602084013e6123b2565b606091505b5080516000036123d45760405162461bcd60e51b815260040161083090613016565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611cc5565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106124405772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061246c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061248a57662386f26fc10000830492506010015b6305f5e10083106124a2576305f5e100830492506008015b61271083106124b657612710830492506004015b606483106124c8576064830492506002015b600a83106106e75760010192915050565b60006001600160e01b031982166380ac58cd60e01b148061250a57506001600160e01b03198216635b5e139f60e01b145b806106e757506301ffc9a760e01b6001600160e01b03198316146106e7565b6001600160a01b0383811615908316158180156125435750805b1561256157604051635cbd944160e01b815260040160405180910390fd5b811561256d575b612207565b806125685761220733868686346125c6565b6001600160a01b0383811615908316158180156125995750805b156125b757604051635cbd944160e01b815260040160405180910390fd5b81612568578061256857612207565b60006125d06108d6565b90506001600160a01b0381161561185c576001600160a01b03811633036125f75750612207565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea9060840160006040518083038186803b15801561264f57600080fd5b505afa158015610ea5573d6000803e3d6000fd5b6001600160e01b0319811681146118da57600080fd5b60006020828403121561268b57600080fd5b813561130c81612663565b6001600160a01b03811681146118da57600080fd5b6001600160601b03811681146118da57600080fd5b600080604083850312156126d357600080fd5b82356126de81612696565b915060208301356126ee816126ab565b809150509250929050565b60005b838110156127145781810151838201526020016126fc565b50506000910152565b600081518084526127358160208601602086016126f9565b601f01601f19169290920160200192915050565b60208152600061130c602083018461271d565b60006020828403121561276e57600080fd5b5035919050565b6000806040838503121561278857600080fd5b823561279381612696565b946020939093013593505050565b60008083601f8401126127b357600080fd5b5081356001600160401b038111156127ca57600080fd5b6020830191508360208260051b8501011115610f8a57600080fd5b600080600080604085870312156127fb57600080fd5b84356001600160401b0381111561281157600080fd5b61281d878288016127a1565b90955093505060208501356001600160401b0381111561283c57600080fd5b612848878288016127a1565b95989497509550505050565b60008060006060848603121561286957600080fd5b833561287481612696565b9250602084013561288481612696565b929592945050506040919091013590565b600080604083850312156128a857600080fd5b50508035926020909101359150565b600080602083850312156128ca57600080fd5b82356001600160401b038111156128e057600080fd5b8301601f810185136128f157600080fd5b80356001600160401b0381111561290757600080fd5b85602082840101111561291957600080fd5b6020919091019590945092505050565b60008060006060848603121561293e57600080fd5b83359250602084013561295081612696565b91506040840135612960816126ab565b809150509250925092565b600781106118da57600080fd5b6000806040838503121561298b57600080fd5b823561299681612696565b915060208301356126ee8161296b565b6000602082840312156129b857600080fd5b813561130c81612696565b80151581146118da57600080fd5b6000602082840312156129e357600080fd5b813561130c816129c3565b60008060408385031215612a0157600080fd5b8235612a0c81612696565b915060208301356126ee816129c3565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715612a5457612a54612a1c565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612a8257612a82612a1c565b604052919050565b60008060008060808587031215612aa057600080fd5b8435612aab81612696565b93506020850135612abb81612696565b92506040850135915060608501356001600160401b03811115612add57600080fd5b8501601f81018713612aee57600080fd5b80356001600160401b03811115612b0757612b07612a1c565b612b1a601f8201601f1916602001612a5a565b818152886020838501011115612b2f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b600060208284031215612b6357600080fd5b813561130c8161296b565b60008060408385031215612b8157600080fd5b8235612b8c81612696565b915060208301356126ee81612696565b600080600060408486031215612bb157600080fd5b8335925060208401356001600160401b03811115612bce57600080fd5b612bda868287016127a1565b9497909650939450505050565b600181811c90821680612bfb57607f821691505b602082108103612c1b57634e487b7160e01b600052602260045260246000fd5b50919050565b80516001600160401b0381168114612c3857600080fd5b919050565b805161ffff81168114612c3857600080fd5b8051612c388161296b565b60008082840360e0811215612c6e57600080fd5b60c0811215612c7c57600080fd5b50612c85612a32565b835181526020840151612c97816126ab565b6020820152612ca860408501612c21565b6040820152612cb960608501612c21565b6060820152608084015160ff81168114612cd257600080fd5b6080820152612ce360a08501612c3d565b60a08201529150612cf660c08401612c4f565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156106e7576106e7612d15565b600060078610612d5e57634e487b7160e01b600052602160045260246000fd5b8582526001600160a01b038516602083015260606040830181905282018390526001600160fb1b03831115612d9257600080fd5b8260051b808560808501379190910160800195945050505050565b600060208284031215612dbf57600080fd5b815161130c816129c3565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612df257600080fd5b815161130c81612696565b80820281158282048414176106e7576106e7612d15565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600082612e7e57634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156108d157806000526020600020601f840160051c81016020851015612eaa5750805b601f840160051c820191505b818110156122075760008155600101612eb6565b6001600160401b03831115612ee157612ee1612a1c565b612ef583612eef8354612be7565b83612e83565b6000601f841160018114612f295760008515612f115750838201355b600019600387901b1c1916600186901b178355612207565b600083815260209020601f19861690835b82811015612f5a5786850135825560209485019460019092019101612f3a565b5086821015612f775760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008351612f9b8184602088016126f9565b835190830190612faf8183602088016126f9565b01949350505050565b600060018201612fca57612fca612d15565b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130e59083018461271d565b9695505050505050565b60006020828403121561310157600080fd5b815161130c8161266356fea26469706673582212208af4946a76327b24cf38ea8674e864cae786a4d9c67a824bcad18f9b2a98a0a364736f6c634300081c003300000000000000000000000055baf7c7665ccf5c1856e689741aa340f62984e500000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000b6b062ce38148ee0a34f8b811330fb80ff66d87d000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae000000000000000000000000000000000000000000000000000000000000000c52494c4c415a204445504958000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054445504958000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061020f5760003560e01c806370a0823111610118578063c87b56dd116100a0578063eef998101161006f578063eef9981014610644578063f2fde38b14610657578063f631e96914610677578063f9528e2a1461068c578063ffe5387e146106bc57600080fd5b8063c87b56dd146105c1578063d082e381146105e1578063d2bf6492146105f7578063e985e9c51461062457600080fd5b806395d89b41116100e757806395d89b411461052c5780639e05d24014610541578063a22cb46514610561578063a9fc664e14610581578063b88d4fde146105a157600080fd5b806370a08231146104c3578063715018a6146104e3578063771282f6146104f85780638da5cb5b1461050e57600080fd5b806323b872dd1161019b5780635944c7531161016a5780635944c753146103fc5780635f555fb91461041c5780636221d13c146104625780636352211e14610483578063659f875b146104a357600080fd5b806323b872dd1461035d5780632a55205a1461037d57806342842e0e146103bc57806355f804b3146103dc57600080fd5b8063081812fc116101e2578063081812fc146102cd578063095ea7b3146102ed578063098144d41461030d5780630d705df6146103225780632157c6491461034a57600080fd5b8063014635461461021457806301ffc9a71461025957806304634d8d1461028957806306fdde03146102ab575b600080fd5b34801561022057600080fd5b5061023c73721c00182a990771244d7a71b9fa2ea789a3b43381565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561026557600080fd5b50610279610274366004612679565b6106dc565b6040519015158152602001610250565b34801561029557600080fd5b506102a96102a43660046126c0565b6106ed565b005b3480156102b757600080fd5b506102c0610703565b6040516102509190612749565b3480156102d957600080fd5b5061023c6102e836600461275c565b610795565b3480156102f957600080fd5b506102a9610308366004612775565b6107bc565b34801561031957600080fd5b5061023c6108d6565b34801561032e57600080fd5b506040805163657711f560e11b81526001602082015201610250565b6102a96103583660046127e5565b610910565b34801561036957600080fd5b506102a9610378366004612854565b610eb2565b34801561038957600080fd5b5061039d610398366004612895565b610ee3565b604080516001600160a01b039093168352602083019190915201610250565b3480156103c857600080fd5b506102a96103d7366004612854565b610f91565b3480156103e857600080fd5b506102a96103f73660046128b7565b610fac565b34801561040857600080fd5b506102a9610417366004612929565b610fe3565b34801561042857600080fd5b50610454610437366004612978565b601160209081526000928352604080842090915290825290205481565b604051908152602001610250565b34801561046e57600080fd5b5060085461027990600160a81b900460ff1681565b34801561048f57600080fd5b5061023c61049e36600461275c565b610ff6565b3480156104af57600080fd5b506104546104be366004612978565b611056565b3480156104cf57600080fd5b506104546104de3660046129a6565b6110a9565b3480156104ef57600080fd5b506102a961112f565b34801561050457600080fd5b50610454600c5481565b34801561051a57600080fd5b50600b546001600160a01b031661023c565b34801561053857600080fd5b506102c0611143565b34801561054d57600080fd5b506102a961055c3660046129d1565b611152565b34801561056d57600080fd5b506102a961057c3660046129ee565b6111b2565b34801561058d57600080fd5b506102a961059c3660046129a6565b6111bd565b3480156105ad57600080fd5b506102a96105bc366004612a8a565b611274565b3480156105cd57600080fd5b506102c06105dc36600461275c565b6112ac565b3480156105ed57600080fd5b50610454600d5481565b34801561060357600080fd5b50610454610612366004612b51565b60106020526000908152604090205481565b34801561063057600080fd5b5061027961063f366004612b6e565b611313565b6102a9610652366004612b9c565b611377565b34801561066357600080fd5b506102a96106723660046129a6565b611864565b34801561068357600080fd5b506104546118dd565b34801561069857600080fd5b506102796106a736600461275c565b600f6020526000908152604090205460ff1681565b3480156106c857600080fd5b506104546106d7366004612b51565b61193d565b60006106e78261197c565b92915050565b6106f56119a1565b6106ff82826119a9565b5050565b60606006805461071290612be7565b80601f016020809104026020016040519081016040528092919081815260200182805461073e90612be7565b801561078b5780601f106107605761010080835404028352916020019161078b565b820191906000526020600020905b81548152906001019060200180831161076e57829003601f168201915b5050505050905090565b60006107a0826119fe565b506000908152600460205260409020546001600160a01b031690565b60006107c782610ff6565b9050806001600160a01b0316836001600160a01b0316036108395760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061085557506108558133611313565b6108c75760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610830565b6108d18383611a5d565b505050565b60085461010090046001600160a01b03168061090d5760085460ff1661090d575073721c00182a990771244d7a71b9fa2ea789a3b4335b90565b8260008190036109335760405163162908e360e11b815260040160405180910390fd5b6000807f000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae6001600160a01b031663055ad42e6040518163ffffffff1660e01b815260040160e060405180830381865afa158015610994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b89190612c5a565b909250905060008160068111156109d1576109d1612cff565b14806109ee575060028160068111156109ec576109ec612cff565b115b15610a0c57604051635ce1196360e01b815260040160405180910390fd5b608082015133600090815260116020526040812060ff909216918591846006811115610a3a57610a3a612cff565b6006811115610a4b57610a4b612cff565b815260200190815260200160002054610a649190612d2b565b1115610a8357604051637ab0312d60e11b815260040160405180910390fd5b610dac83610a8f6118dd565b610a999190612d2b565b1115610ab857604051637201d58360e01b815260040160405180910390fd5b60405163f31755b760e01b81526000906001600160a01b037f000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae169063f31755b790610b0d90859033908b908b90600401612d3e565b602060405180830381865afa158015610b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4e9190612dad565b9050808015610b5c57503415155b15610b7a57604051636956f2ab60e11b815260040160405180910390fd5b3360009081526011602052604081208591846006811115610b9d57610b9d612cff565b6006811115610bae57610bae612cff565b81526020019081526020016000206000828254610bcb9190612d2b565b9091555084905060106000846006811115610be857610be8612cff565b6006811115610bf957610bf9612cff565b81526020019081526020016000206000828254610c169190612d2b565b9250508190555083600c6000828254610c2f9190612d2b565b90915550600090505b84811015610dce57337f000000000000000000000000b6b062ce38148ee0a34f8b811330fb80ff66d87d6001600160a01b0316636352211e8b8b85818110610c8257610c82612dca565b905060200201356040518263ffffffff1660e01b8152600401610ca791815260200190565b602060405180830381865afa158015610cc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ce89190612de0565b6001600160a01b031614610d0f576040516330cd747160e01b815260040160405180910390fd5b600f60008a8a84818110610d2557610d25612dca565b602090810292909201358352508101919091526040016000205460ff1615610d6057604051631bbdf5c560e31b815260040160405180910390fd5b6001600f60008b8b85818110610d7857610d78612dca565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550610dc6338a8a84818110610dba57610dba612dca565b90506020020135611acb565b600101610c38565b5080610ea85760008484602001516001600160601b0316610def9190612dfd565b9050803414610e1157604051636956f2ab60e11b815260040160405180910390fd5b60007f00000000000000000000000055baf7c7665ccf5c1856e689741aa340f62984e56001600160a01b03163460405160006040518083038185875af1925050503d8060008114610e7e576040519150601f19603f3d011682016040523d82523d6000602084013e610e83565b606091505b5050905080610ea5576040516312171d8360e31b815260040160405180910390fd5b50505b5050505050505050565b610ebc3382611c6e565b610ed85760405162461bcd60e51b815260040161083090612e14565b6108d1838383611ccd565b6000828152600a602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b0316928201929092528291610f585750604080518082019091526009546001600160a01b0381168252600160a01b90046001600160601b031660208201525b602081015160009061271090610f77906001600160601b031687612dfd565b610f819190612e61565b91519350909150505b9250929050565b6108d183838360405180602001604052806000815250611274565b610fb46119a1565b6000819003610fd657604051633ba0191160e01b815260040160405180910390fd5b600e6108d1828483612eca565b610feb6119a1565b6108d1838383611e46565b6000818152600260205260408120546001600160a01b0316806106e75760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610830565b6001600160a01b03821660009081526011602052604081208183600681111561108157611081612cff565b600681111561109257611092612cff565b815260200190815260200160002054905092915050565b60006001600160a01b0382166111135760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610830565b506001600160a01b031660009081526003602052604090205490565b611137611ea0565b6111416000611efa565b565b60606007805461071290612be7565b61115a6119a1565b60088054821515600160a81b0260ff60a81b199091161790556040517f6787c7f9a80aa0f5ceddab2c54f1f5169c0b88e75dd5e19d5e858a64144c7dbc906111a790831515815260200190565b60405180910390a150565b6106ff338383611f4c565b6111c56119a1565b6001600160a01b038116803b151590158015906111e0575080155b156111fe576040516332483afb60e01b815260040160405180910390fd5b7fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac6112276108d6565b604080516001600160a01b03928316815291851660208301520160405180910390a150600880546001600160a01b03909216610100026001600160a81b0319909216919091176001179055565b61127e3383611c6e565b61129a5760405162461bcd60e51b815260040161083090612e14565b6112a684848484612012565b50505050565b60606112b7826119fe565b60006112c1612045565b905060008151116112e1576040518060200160405280600081525061130c565b806112eb84612054565b6040516020016112fc929190612f89565b6040516020818303038152906040525b9392505050565b6001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff16806106e757600854600160a81b900460ff16156106e75761135b6108d6565b6001600160a01b0316826001600160a01b031614905092915050565b826000036113985760405163162908e360e11b815260040160405180910390fd5b6000807f000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae6001600160a01b031663055ad42e6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156113f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141d9190612c5a565b9092509050600281600681111561143657611436612cff565b116114545760405163268dbf6760e21b815260040160405180910390fd5b608082015133600090815260116020526040812060ff90921691879184600681111561148257611482612cff565b600681111561149357611493612cff565b8152602001908152602001600020546114ac9190612d2b565b11156114cb57604051637ab0312d60e11b815260040160405180910390fd5b61271085600c546114dc9190612d2b565b11156114fb5760405163d05cb60960e01b815260040160405180910390fd5b8160a0015161ffff16856010600084600681111561151b5761151b612cff565b600681111561152c5761152c612cff565b8152602001908152602001600020546115459190612d2b565b11156115645760405163d05cb60960e01b815260040160405180910390fd5b600681600681111561157857611578612cff565b10156116505760008390036115a0576040516309bde33960e01b815260040160405180910390fd5b60405163f31755b760e01b81526001600160a01b037f000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae169063f31755b7906115f2908490339089908990600401612d3e565b602060405180830381865afa15801561160f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116339190612dad565b61165057604051630b094f2760e31b815260040160405180910390fd5b60208201516001600160601b0316156116a65760008583602001516001600160601b031661167e9190612dfd565b90508034146116a057604051636956f2ab60e11b815260040160405180910390fd5b506116c5565b34156116c557604051636956f2ab60e11b815260040160405180910390fd5b33600090815260116020526040812086918360068111156116e8576116e8612cff565b60068111156116f9576116f9612cff565b815260200190815260200160002060008282546117169190612d2b565b909155508590506010600083600681111561173357611733612cff565b600681111561174457611744612cff565b815260200190815260200160002060008282546117619190612d2b565b9250508190555084600c600082825461177a9190612d2b565b909155505060208201516001600160601b0316156118285760007f00000000000000000000000055baf7c7665ccf5c1856e689741aa340f62984e56001600160a01b03163460405160006040518083038185875af1925050503d80600081146117ff576040519150601f19603f3d011682016040523d82523d6000602084013e611804565b606091505b5050905080611826576040516312171d8360e31b815260040160405180910390fd5b505b60005b8581101561185c5761183f33600d54611acb565b600d805490600061184f83612fb8565b909155505060010161182b565b505050505050565b61186c611ea0565b6001600160a01b0381166118d15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610830565b6118da81611efa565b50565b60106020527f853b2fefe141400fef543280f93d98bd49996069f632d0d20236afeeed8e46a254600160009081527f8c6065603763fec3f5742441d3833f3f43b982453612d76adb39a885e3006b5f54909161193891612d2b565b905090565b60006010600083600681111561195557611955612cff565b600681111561196657611966612cff565b8152602001908152602001600020549050919050565b60006001600160e01b0319821663152a902d60e11b14806106e757506106e7826120e6565b611141611ea0565b6119b38282612126565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6000818152600260205260409020546001600160a01b03166118da5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610830565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611a9282610ff6565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b038216611b215760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610830565b6000818152600260205260409020546001600160a01b031615611b865760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610830565b611b946000838360016121e0565b6000818152600260205260409020546001600160a01b031615611bf95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610830565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46106ff60008383600161220e565b600080611c7a83610ff6565b9050806001600160a01b0316846001600160a01b03161480611ca15750611ca18185611313565b80611cc55750836001600160a01b0316611cba84610795565b6001600160a01b0316145b949350505050565b826001600160a01b0316611ce082610ff6565b6001600160a01b031614611d065760405162461bcd60e51b815260040161083090612fd1565b6001600160a01b038216611d685760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610830565b611d7583838360016121e0565b826001600160a01b0316611d8882610ff6565b6001600160a01b031614611dae5760405162461bcd60e51b815260040161083090612fd1565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a46108d1838383600161220e565b611e51838383612235565b6040516001600160601b03821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b600b546001600160a01b031633146111415760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610830565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603611fad5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610830565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101611e93565b61201d848484611ccd565b61202984848484612300565b6112a65760405162461bcd60e51b815260040161083090613016565b6060600e805461071290612be7565b6060600061206183612401565b60010190506000816001600160401b0381111561208057612080612a1c565b6040519080825280601f01601f1916602001820160405280156120aa576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846120b457509392505050565b60006001600160e01b03198216632b435fdb60e21b148061211757506001600160e01b0319821663503e914d60e11b145b806106e757506106e7826124d9565b6127106001600160601b03821611156121515760405162461bcd60e51b815260040161083090613068565b6001600160a01b0382166121a75760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610830565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600955565b60005b81811015612207576121ff85856121fa8487612d2b565b612529565b6001016121e3565b5050505050565b60005b818110156122075761222d85856122288487612d2b565b61257f565b600101612211565b6127106001600160601b03821611156122605760405162461bcd60e51b815260040161083090613068565b6001600160a01b0382166122b65760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610830565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600a90529190942093519051909116600160a01b029116179055565b60006001600160a01b0384163b156123f657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906123449033908990889088906004016130b2565b6020604051808303816000875af192505050801561237f575060408051601f3d908101601f1916820190925261237c918101906130ef565b60015b6123dc573d8080156123ad576040519150601f19603f3d011682016040523d82523d6000602084013e6123b2565b606091505b5080516000036123d45760405162461bcd60e51b815260040161083090613016565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611cc5565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106124405772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061246c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061248a57662386f26fc10000830492506010015b6305f5e10083106124a2576305f5e100830492506008015b61271083106124b657612710830492506004015b606483106124c8576064830492506002015b600a83106106e75760010192915050565b60006001600160e01b031982166380ac58cd60e01b148061250a57506001600160e01b03198216635b5e139f60e01b145b806106e757506301ffc9a760e01b6001600160e01b03198316146106e7565b6001600160a01b0383811615908316158180156125435750805b1561256157604051635cbd944160e01b815260040160405180910390fd5b811561256d575b612207565b806125685761220733868686346125c6565b6001600160a01b0383811615908316158180156125995750805b156125b757604051635cbd944160e01b815260040160405180910390fd5b81612568578061256857612207565b60006125d06108d6565b90506001600160a01b0381161561185c576001600160a01b03811633036125f75750612207565b60405163657711f560e11b81526001600160a01b038781166004830152868116602483015285811660448301526064820185905282169063caee23ea9060840160006040518083038186803b15801561264f57600080fd5b505afa158015610ea5573d6000803e3d6000fd5b6001600160e01b0319811681146118da57600080fd5b60006020828403121561268b57600080fd5b813561130c81612663565b6001600160a01b03811681146118da57600080fd5b6001600160601b03811681146118da57600080fd5b600080604083850312156126d357600080fd5b82356126de81612696565b915060208301356126ee816126ab565b809150509250929050565b60005b838110156127145781810151838201526020016126fc565b50506000910152565b600081518084526127358160208601602086016126f9565b601f01601f19169290920160200192915050565b60208152600061130c602083018461271d565b60006020828403121561276e57600080fd5b5035919050565b6000806040838503121561278857600080fd5b823561279381612696565b946020939093013593505050565b60008083601f8401126127b357600080fd5b5081356001600160401b038111156127ca57600080fd5b6020830191508360208260051b8501011115610f8a57600080fd5b600080600080604085870312156127fb57600080fd5b84356001600160401b0381111561281157600080fd5b61281d878288016127a1565b90955093505060208501356001600160401b0381111561283c57600080fd5b612848878288016127a1565b95989497509550505050565b60008060006060848603121561286957600080fd5b833561287481612696565b9250602084013561288481612696565b929592945050506040919091013590565b600080604083850312156128a857600080fd5b50508035926020909101359150565b600080602083850312156128ca57600080fd5b82356001600160401b038111156128e057600080fd5b8301601f810185136128f157600080fd5b80356001600160401b0381111561290757600080fd5b85602082840101111561291957600080fd5b6020919091019590945092505050565b60008060006060848603121561293e57600080fd5b83359250602084013561295081612696565b91506040840135612960816126ab565b809150509250925092565b600781106118da57600080fd5b6000806040838503121561298b57600080fd5b823561299681612696565b915060208301356126ee8161296b565b6000602082840312156129b857600080fd5b813561130c81612696565b80151581146118da57600080fd5b6000602082840312156129e357600080fd5b813561130c816129c3565b60008060408385031215612a0157600080fd5b8235612a0c81612696565b915060208301356126ee816129c3565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715612a5457612a54612a1c565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612a8257612a82612a1c565b604052919050565b60008060008060808587031215612aa057600080fd5b8435612aab81612696565b93506020850135612abb81612696565b92506040850135915060608501356001600160401b03811115612add57600080fd5b8501601f81018713612aee57600080fd5b80356001600160401b03811115612b0757612b07612a1c565b612b1a601f8201601f1916602001612a5a565b818152886020838501011115612b2f57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b600060208284031215612b6357600080fd5b813561130c8161296b565b60008060408385031215612b8157600080fd5b8235612b8c81612696565b915060208301356126ee81612696565b600080600060408486031215612bb157600080fd5b8335925060208401356001600160401b03811115612bce57600080fd5b612bda868287016127a1565b9497909650939450505050565b600181811c90821680612bfb57607f821691505b602082108103612c1b57634e487b7160e01b600052602260045260246000fd5b50919050565b80516001600160401b0381168114612c3857600080fd5b919050565b805161ffff81168114612c3857600080fd5b8051612c388161296b565b60008082840360e0811215612c6e57600080fd5b60c0811215612c7c57600080fd5b50612c85612a32565b835181526020840151612c97816126ab565b6020820152612ca860408501612c21565b6040820152612cb960608501612c21565b6060820152608084015160ff81168114612cd257600080fd5b6080820152612ce360a08501612c3d565b60a08201529150612cf660c08401612c4f565b90509250929050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156106e7576106e7612d15565b600060078610612d5e57634e487b7160e01b600052602160045260246000fd5b8582526001600160a01b038516602083015260606040830181905282018390526001600160fb1b03831115612d9257600080fd5b8260051b808560808501379190910160800195945050505050565b600060208284031215612dbf57600080fd5b815161130c816129c3565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612df257600080fd5b815161130c81612696565b80820281158282048414176106e7576106e7612d15565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600082612e7e57634e487b7160e01b600052601260045260246000fd5b500490565b601f8211156108d157806000526020600020601f840160051c81016020851015612eaa5750805b601f840160051c820191505b818110156122075760008155600101612eb6565b6001600160401b03831115612ee157612ee1612a1c565b612ef583612eef8354612be7565b83612e83565b6000601f841160018114612f295760008515612f115750838201355b600019600387901b1c1916600186901b178355612207565b600083815260209020601f19861690835b82811015612f5a5786850135825560209485019460019092019101612f3a565b5086821015612f775760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60008351612f9b8184602088016126f9565b835190830190612faf8183602088016126f9565b01949350505050565b600060018201612fca57612fca612d15565b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130e59083018461271d565b9695505050505050565b60006020828403121561310157600080fd5b815161130c8161266356fea26469706673582212208af4946a76327b24cf38ea8674e864cae786a4d9c67a824bcad18f9b2a98a0a364736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000055baf7c7665ccf5c1856e689741aa340f62984e500000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000b6b062ce38148ee0a34f8b811330fb80ff66d87d000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae000000000000000000000000000000000000000000000000000000000000000c52494c4c415a204445504958000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054445504958000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : royaltyReceiver_ (address): 0x55baF7c7665cCf5C1856E689741aA340f62984E5
Arg [1] : royaltyFeeNumerator_ (uint96): 500
Arg [2] : name_ (string): RILLAZ DEPIX
Arg [3] : symbol_ (string): DEPIX
Arg [4] : rillaz_ (address): 0xb6b062cE38148ee0A34f8B811330Fb80FF66d87d
Arg [5] : phaseManager_ (address): 0xCFF0d58D233a765f06204989e7CB55FB7eB744ae
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000055baf7c7665ccf5c1856e689741aa340f62984e5
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 000000000000000000000000b6b062ce38148ee0a34f8b811330fb80ff66d87d
Arg [5] : 000000000000000000000000cff0d58d233a765f06204989e7cb55fb7eb744ae
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [7] : 52494c4c415a2044455049580000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [9] : 4445504958000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
98351:5966:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67651:104;;;;;;;;;;;;67712:42;67651:104;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;67651:104:0;;;;;;;;103708:187;;;;;;;;;;-1:-1:-1;103708:187:0;;;;;:::i;:::-;;:::i;:::-;;;773:14:1;;766:22;748:41;;736:2;721:18;103708:187:0;608::1;102914:176:0;;;;;;;;;;-1:-1:-1;102914:176:0;;;;;:::i;:::-;;:::i;:::-;;90548:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;76541:171::-;;;;;;;;;;-1:-1:-1;76541:171:0;;;;;:::i;:::-;;:::i;76059:416::-;;;;;;;;;;-1:-1:-1;76059:416:0;;;;;:::i;:::-;;:::i;69269:298::-;;;;;;;;;;;;;:::i;93866:252::-;;;;;;;;;;-1:-1:-1;93866:252:0;;;-1:-1:-1;;;2994:52:1;;94106:4:0;3077:2:1;3062:18;;3055:50;2967:18;93866:252:0;2828:283:1;99650:1583:0;;;;;;:::i;:::-;;:::i;77241:335::-;;;;;;;;;;-1:-1:-1;77241:335:0;;;;;:::i;:::-;;:::i;59285:442::-;;;;;;;;;;-1:-1:-1;59285:442:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;5317:32:1;;;5299:51;;5381:2;5366:18;;5359:34;;;;5272:18;59285:442:0;5125:274:1;77647:185:0;;;;;;;;;;-1:-1:-1;77647:185:0;;;;;:::i;:::-;;:::i;103338:199::-;;;;;;;;;;-1:-1:-1;103338:199:0;;;;;:::i;:::-;;:::i;103098:232::-;;;;;;;;;;-1:-1:-1;103098:232:0;;;;;:::i;:::-;;:::i;98855:75::-;;;;;;;;;;-1:-1:-1;98855:75:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;7180:25:1;;;7168:2;7153:18;98855:75:0;7034:177:1;55935:45:0;;;;;;;;;;-1:-1:-1;55935:45:0;;;;-1:-1:-1;;;55935:45:0;;;;;;74739:223;;;;;;;;;;-1:-1:-1;74739:223:0;;;;;:::i;:::-;;:::i;104155:159::-;;;;;;;;;;-1:-1:-1;104155:159:0;;;;;:::i;:::-;;:::i;74470:207::-;;;;;;;;;;-1:-1:-1;74470:207:0;;;;;:::i;:::-;;:::i;45143:103::-;;;;;;;;;;;;;:::i;98631:28::-;;;;;;;;;;;;;;;;44495:87;;;;;;;;;;-1:-1:-1;44568:6:0;;-1:-1:-1;;;;;44568:6:0;44495:87;;90664:112;;;;;;;;;;;;;:::i;56360:257::-;;;;;;;;;;-1:-1:-1;56360:257:0;;;;;:::i;:::-;;:::i;76784:155::-;;;;;;;;;;-1:-1:-1;76784:155:0;;;;;:::i;:::-;;:::i;68610:544::-;;;;;;;;;;-1:-1:-1;68610:544:0;;;;;:::i;:::-;;:::i;77903:322::-;;;;;;;;;;-1:-1:-1;77903:322:0;;;;;:::i;:::-;;:::i;75373:281::-;;;;;;;;;;-1:-1:-1;75373:281:0;;;;;:::i;:::-;;:::i;98666:35::-;;;;;;;;;;;;;;;;98797:51;;;;;;;;;;-1:-1:-1;98797:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;92733:370;;;;;;;;;;-1:-1:-1;92733:370:0;;;;;:::i;:::-;;:::i;101241:1665::-;;;;;;:::i;:::-;;:::i;45401:201::-;;;;;;;;;;-1:-1:-1;45401:201:0;;;;;:::i;:::-;;:::i;103545:155::-;;;;;;;;;;;;;:::i;98742:42::-;;;;;;;;;;-1:-1:-1;98742:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;104016:131;;;;;;;;;;-1:-1:-1;104016:131:0;;;;;:::i;:::-;;:::i;103708:187::-;103827:4;103851:36;103875:11;103851:23;:36::i;:::-;103844:43;103708:187;-1:-1:-1;;103708:187:0:o;102914:176::-;102998:31;:29;:31::i;:::-;103040:42;103059:8;103069:12;103040:18;:42::i;:::-;102914:176;;:::o;90548:108::-;90602:13;90635;90628:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90548:108;:::o;76541:171::-;76617:7;76637:23;76652:7;76637:14;:23::i;:::-;-1:-1:-1;76680:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;76680:24:0;;76541:171::o;76059:416::-;76140:13;76156:23;76171:7;76156:14;:23::i;:::-;76140:39;;76204:5;-1:-1:-1;;;;;76198:11:0;:2;-1:-1:-1;;;;;76198:11:0;;76190:57;;;;-1:-1:-1;;;76190:57:0;;11870:2:1;76190:57:0;;;11852:21:1;11909:2;11889:18;;;11882:30;11948:34;11928:18;;;11921:62;-1:-1:-1;;;11999:18:1;;;11992:31;12040:19;;76190:57:0;;;;;;;;;13136:10;-1:-1:-1;;;;;76282:21:0;;;;:62;;-1:-1:-1;76307:37:0;76324:5;13136:10;92733:370;:::i;76307:37::-;76260:173;;;;-1:-1:-1;;;76260:173:0;;12272:2:1;76260:173:0;;;12254:21:1;12311:2;12291:18;;;12284:30;12350:34;12330:18;;;12323:62;12421:31;12401:18;;;12394:59;12470:19;;76260:173:0;12070:425:1;76260:173:0;76446:21;76455:2;76459:7;76446:8;:21::i;:::-;76129:346;76059:416;;:::o;69269:298::-;69373:17;;;;;-1:-1:-1;;;;;69373:17:0;;69403:157;;69452:22;;;;69447:102;;-1:-1:-1;67712:42:0;69447:102;69269:298;:::o;99650:1583::-;99796:8;99782:11;99826:8;;;99822:36;;99843:15;;-1:-1:-1;;;99843:15:0;;;;;;;;;;;99822:36;99880:31;99913:19;99936:12;-1:-1:-1;;;;;99936:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99879:84;;-1:-1:-1;99879:84:0;-1:-1:-1;99991:14:0;99978:9;:27;;;;;;;;:::i;:::-;;:64;;;-1:-1:-1;100021:21:0;100009:9;:33;;;;;;;;:::i;:::-;;99978:64;99974:104;;;100065:13;;-1:-1:-1;;;100065:13:0;;;;;;;;;;;99974:104;100145:18;;;;100114:10;100095:30;;;;:18;:30;;;;;:68;;;;;100139:3;;100126:9;100095:41;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:47;;;;:::i;:::-;:68;100091:117;;;100186:22;;-1:-1:-1;;;100186:22:0;;;;;;;;;;;100091:117;98614:4;100238:3;100223:12;:10;:12::i;:::-;:18;;;;:::i;:::-;:36;100219:82;;;100282:19;;-1:-1:-1;;;100282:19:0;;;;;;;;;;;100219:82;100344:70;;-1:-1:-1;;;100344:70:0;;100323:18;;-1:-1:-1;;;;;100344:12:0;:34;;;;:70;;100379:9;;100390:10;;100402:11;;;;100344:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100323:91;;100429:13;:31;;;;-1:-1:-1;100446:9:0;:14;;100429:31;100425:74;;;100483:16;;-1:-1:-1;;;100483:16:0;;;;;;;;;;;100425:74;100531:10;100512:30;;;;:18;:30;;;;;100557:3;;100543:9;100512:41;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:48;;;;;;;:::i;:::-;;;;-1:-1:-1;100600:3:0;;-1:-1:-1;100571:14:0;:25;100586:9;100571:25;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:32;;;;;;;:::i;:::-;;;;;;;;100631:3;100614:13;;:20;;;;;;;:::i;:::-;;;;-1:-1:-1;100660:9:0;;-1:-1:-1;100655:281:0;100679:3;100675:1;:7;100655:281;;;100739:10;100708:6;-1:-1:-1;;;;;100708:14:0;;100723:8;;100732:1;100723:11;;;;;;;:::i;:::-;;;;;;;100708:27;;;;;;;;;;;;;7180:25:1;;7168:2;7153:18;;7034:177;100708:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;100708:41:0;;100704:64;;100758:10;;-1:-1:-1;;;100758:10:0;;;;;;;;;;;100704:64;100787:10;:23;100798:8;;100807:1;100798:11;;;;;;;:::i;:::-;;;;;;;;;;100787:23;;-1:-1:-1;100787:23:0;;;;;;;;-1:-1:-1;100787:23:0;;;;100783:51;;;100819:15;;-1:-1:-1;;;100819:15:0;;;;;;;;;;;100783:51;100875:4;100849:10;:23;100860:8;;100869:1;100860:11;;;;;;;:::i;:::-;;;;;;;100849:23;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;100894;100900:10;100912:8;;100921:1;100912:11;;;;;;;:::i;:::-;;;;;;;100894:5;:30::i;:::-;100684:3;;100655:281;;;;100951:13;100946:280;;100981:16;101014:3;101000:5;:11;;;-1:-1:-1;;;;;101000:17:0;;;;;:::i;:::-;100981:36;;101049:8;101036:9;:21;101032:50;;101066:16;;-1:-1:-1;;;101066:16:0;;;;;;;;;;;101032:50;101098:12;101116:19;-1:-1:-1;;;;;101116:24:0;101148:9;101116:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101097:65;;;101182:7;101177:37;;101198:16;;-1:-1:-1;;;101198:16:0;;;;;;;;;;;101177:37;100966:260;;100946:280;99771:1462;;;;99650:1583;;;;:::o;77241:335::-;77436:41;13136:10;77469:7;77436:18;:41::i;:::-;77428:99;;;;-1:-1:-1;;;77428:99:0;;;;;;;:::i;:::-;77540:28;77550:4;77556:2;77560:7;77540:9;:28::i;59285:442::-;59382:7;59440:27;;;:17;:27;;;;;;;;59411:56;;;;;;;;;-1:-1:-1;;;;;59411:56:0;;;;;-1:-1:-1;;;59411:56:0;;;-1:-1:-1;;;;;59411:56:0;;;;;;;;59382:7;;59480:92;;-1:-1:-1;59531:29:0;;;;;;;;;59541:19;59531:29;-1:-1:-1;;;;;59531:29:0;;;;-1:-1:-1;;;59531:29:0;;-1:-1:-1;;;;;59531:29:0;;;;;59480:92;59622:23;;;;59584:21;;60093:5;;59609:36;;-1:-1:-1;;;;;59609:36:0;:10;:36;:::i;:::-;59608:58;;;;:::i;:::-;59687:16;;;-1:-1:-1;59584:82:0;;-1:-1:-1;;59285:442:0;;;;;;:::o;77647:185::-;77785:39;77802:4;77808:2;77812:7;77785:39;;;;;;;;;;;;:16;:39::i;103338:199::-;103403:31;:29;:31::i;:::-;103474:1;103449:26;;;103445:51;;103484:12;;-1:-1:-1;;;103484:12:0;;;;;;;;;;;103445:51;103507:12;:22;103522:7;;103507:12;:22;:::i;103098:232::-;103231:31;:29;:31::i;:::-;103273:49;103290:7;103299:8;103309:12;103273:16;:49::i;74739:223::-;74811:7;79626:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79626:16:0;;74875:56;;;;-1:-1:-1;;;74875:56:0;;19195:2:1;74875:56:0;;;19177:21:1;19234:2;19214:18;;;19207:30;-1:-1:-1;;;19253:18:1;;;19246:54;19317:18;;74875:56:0;18993:348:1;104155:159:0;-1:-1:-1;;;;;104271:24:0;;104244:7;104271:24;;;:18;:24;;;;;104244:7;104296:9;104271:35;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;104264:42;;104155:159;;;;:::o;74470:207::-;74542:7;-1:-1:-1;;;;;74570:19:0;;74562:73;;;;-1:-1:-1;;;74562:73:0;;19548:2:1;74562:73:0;;;19530:21:1;19587:2;19567:18;;;19560:30;19626:34;19606:18;;;19599:62;-1:-1:-1;;;19677:18:1;;;19670:39;19726:19;;74562:73:0;19346:405:1;74562:73:0;-1:-1:-1;;;;;;74653:16:0;;;;;:9;:16;;;;;;;74470:207::o;45143:103::-;44381:13;:11;:13::i;:::-;45208:30:::1;45235:1;45208:18;:30::i;:::-;45143:103::o:0;90664:112::-;90720:13;90753:15;90746:22;;;;;:::i;56360:257::-;56452:31;:29;:31::i;:::-;56494:33;:47;;;;;-1:-1:-1;;;56494:47:0;-1:-1:-1;;;;56494:47:0;;;;;;56557:52;;;;;;56530:11;773:14:1;766:22;748:41;;736:2;721:18;;608:187;56557:52:0;;;;;;;;56360:257;:::o;76784:155::-;76879:52;13136:10;76912:8;76922;76879:18;:52::i;68610:544::-;68686:31;:29;:31::i;:::-;-1:-1:-1;;;;;68762:30:0;;;;:34;;;68812:32;;;;:61;;;68849:24;68848:25;68812:61;68809:152;;;68897:52;;-1:-1:-1;;;68897:52:0;;;;;;;;;;;68809:152;68978:77;69011:22;:20;:22::i;:::-;68978:77;;;-1:-1:-1;;;;;19948:32:1;;;19930:51;;20017:32;;;20012:2;19997:18;;19990:60;19903:18;68978:77:0;;;;;;;-1:-1:-1;69068:22:0;:29;;-1:-1:-1;;;;;69108:38:0;;;69068:29;69108:38;-1:-1:-1;;;;;;69108:38:0;;;;;;;69093:4;69108:38;;;68610:544::o;77903:322::-;78077:41;13136:10;78110:7;78077:18;:41::i;:::-;78069:99;;;;-1:-1:-1;;;78069:99:0;;;;;;;:::i;:::-;78179:38;78193:4;78199:2;78203:7;78212:4;78179:13;:38::i;:::-;77903:322;;;;:::o;75373:281::-;75446:13;75472:23;75487:7;75472:14;:23::i;:::-;75508:21;75532:10;:8;:10::i;:::-;75508:34;;75584:1;75566:7;75560:21;:25;:86;;;;;;;;;;;;;;;;;75612:7;75621:18;:7;:16;:18::i;:::-;75595:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75560:86;75553:93;75373:281;-1:-1:-1;;;75373:281:0:o;92733:370::-;-1:-1:-1;;;;;77131:25:0;;;92830:15;77131:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;92923:173;;92959:33;;-1:-1:-1;;;92959:33:0;;;;92955:130;;;93046:22;:20;:22::i;:::-;-1:-1:-1;;;;;93026:43:0;:8;-1:-1:-1;;;;;93026:43:0;;93013:56;;92733:370;;;;:::o;101241:1665::-;101366:6;101376:1;101366:11;101362:39;;101386:15;;-1:-1:-1;;;101386:15:0;;;;;;;;;;;101362:39;101413:31;101446:19;101469:12;-1:-1:-1;;;;;101469:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101412:84;;-1:-1:-1;101412:84:0;-1:-1:-1;101524:21:0;101511:9;:34;;;;;;;;:::i;:::-;;101507:61;;101554:14;;-1:-1:-1;;;101554:14:0;;;;;;;;;;;101507:61;101646:18;;;;101612:10;101593:30;;;;:18;:30;;;;;:71;;;;;101637:6;;101624:9;101593:41;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:50;;;;:::i;:::-;:71;101589:120;;;101687:22;;-1:-1:-1;;;101687:22:0;;;;;;;;;;;101589:120;98567:5;101740:6;101724:13;;:22;;;;:::i;:::-;:35;101720:80;;;101782:18;;-1:-1:-1;;;101782:18:0;;;;;;;;;;;101720:80;101852:5;:23;;;101815:60;;101843:6;101815:14;:25;101830:9;101815:25;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:34;;;;:::i;:::-;:60;101811:104;;;101897:18;;-1:-1:-1;;;101897:18:0;;;;;;;;;;;101811:104;101944:21;101932:9;:33;;;;;;;;:::i;:::-;;101928:249;;;102008:1;101986:23;;;101982:50;;102018:14;;-1:-1:-1;;;102018:14:0;;;;;;;;;;;101982:50;102052:70;;-1:-1:-1;;;102052:70:0;;-1:-1:-1;;;;;102052:12:0;:34;;;;:70;;102087:9;;102098:10;;102110:11;;;;102052:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102047:118;;102149:16;;-1:-1:-1;;;102149:16:0;;;;;;;;;;;102047:118;102193:11;;;;-1:-1:-1;;;;;102193:15:0;;102189:228;;102225:16;102258:6;102244:5;:11;;;-1:-1:-1;;;;;102244:20:0;;;;;:::i;:::-;102225:39;;102296:8;102283:9;:21;102279:50;;102313:16;;-1:-1:-1;;;102313:16:0;;;;;;;;;;;102279:50;102210:131;102189:228;;;102366:9;:14;102362:43;;102389:16;;-1:-1:-1;;;102389:16:0;;;;;;;;;;;102362:43;102473:10;102454:30;;;;:18;:30;;;;;102499:6;;102485:9;102454:41;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:51;;;;;;;:::i;:::-;;;;-1:-1:-1;102545:6:0;;-1:-1:-1;102516:14:0;:25;102531:9;102516:25;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;;;;;102579:6;102562:13;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;102602:11:0;;;;-1:-1:-1;;;;;102602:15:0;;102598:165;;102635:12;102653:19;-1:-1:-1;;;;;102653:24:0;102685:9;102653:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102634:65;;;102719:7;102714:37;;102735:16;;-1:-1:-1;;;102735:16:0;;;;;;;;;;;102714:37;102619:144;102598:165;102780:9;102775:124;102799:6;102795:1;:10;102775:124;;;102827:31;102833:10;102845:12;;102827:5;:31::i;:::-;102873:12;:14;;;:12;:14;;;:::i;:::-;;;;-1:-1:-1;;102807:3:0;;102775:124;;;;101351:1555;;101241:1665;;;:::o;45401:201::-;44381:13;:11;:13::i;:::-;-1:-1:-1;;;;;45490:22:0;::::1;45482:73;;;::::0;-1:-1:-1;;;45482:73:0;;20904:2:1;45482:73:0::1;::::0;::::1;20886:21:1::0;20943:2;20923:18;;;20916:30;20982:34;20962:18;;;20955:62;-1:-1:-1;;;21033:18:1;;;21026:36;21079:19;;45482:73:0::1;20702:402:1::0;45482:73:0::1;45566:28;45585:8;45566:18;:28::i;:::-;45401:201:::0;:::o;103545:155::-;103655:14;:37;;;;103630:21;103588:7;103615:37;;;;;103588:7;;103615:77;;;:::i;:::-;103608:84;;103545:155;:::o;104016:131::-;104087:7;104114:14;:25;104129:9;104114:25;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;104107:32;;104016:131;;;:::o;59015:215::-;59117:4;-1:-1:-1;;;;;;59141:41:0;;-1:-1:-1;;;59141:41:0;;:81;;;59186:36;59210:11;59186:23;:36::i;57544:104::-;57627:13;:11;:13::i;62282:217::-;62386:48;62411:8;62421:12;62386:24;:48::i;:::-;62450:41;;-1:-1:-1;;;;;21271:39:1;;21253:58;;-1:-1:-1;;;;;62450:41:0;;;;;21241:2:1;21226:18;62450:41:0;;;;;;;62282:217;;:::o;86360:135::-;80028:4;79626:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79626:16:0;86434:53;;;;-1:-1:-1;;;86434:53:0;;19195:2:1;86434:53:0;;;19177:21:1;19234:2;19214:18;;;19207:30;-1:-1:-1;;;19253:18:1;;;19246:54;19317:18;;86434:53:0;18993:348:1;85639:174:0;85714:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;85714:29:0;-1:-1:-1;;;;;85714:29:0;;;;;;;;:24;;85768:23;85714:24;85768:14;:23::i;:::-;-1:-1:-1;;;;;85759:46:0;;;;;;;;;;;85639:174;;:::o;81856:942::-;-1:-1:-1;;;;;81936:16:0;;81928:61;;;;-1:-1:-1;;;81928:61:0;;21524:2:1;81928:61:0;;;21506:21:1;;;21543:18;;;21536:30;21602:34;21582:18;;;21575:62;21654:18;;81928:61:0;21322:356:1;81928:61:0;80028:4;79626:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79626:16:0;80052:31;82000:58;;;;-1:-1:-1;;;82000:58:0;;21885:2:1;82000:58:0;;;21867:21:1;21924:2;21904:18;;;21897:30;21963;21943:18;;;21936:58;22011:18;;82000:58:0;21683:352:1;82000:58:0;82071:48;82100:1;82104:2;82108:7;82117:1;82071:20;:48::i;:::-;80028:4;79626:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79626:16:0;80052:31;82209:58;;;;-1:-1:-1;;;82209:58:0;;21885:2:1;82209:58:0;;;21867:21:1;21924:2;21904:18;;;21897:30;21963;21943:18;;;21936:58;22011:18;;82209:58:0;21683:352:1;82209:58:0;-1:-1:-1;;;;;82616:13:0;;;;;;:9;:13;;;;;;;;:18;;82633:1;82616:18;;;82658:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;82658:21:0;;;;;82697:33;82666:7;;82616:13;;82697:33;;82616:13;;82697:33;82743:47;82771:1;82775:2;82779:7;82788:1;82743:19;:47::i;80258:264::-;80351:4;80368:13;80384:23;80399:7;80384:14;:23::i;:::-;80368:39;;80437:5;-1:-1:-1;;;;;80426:16:0;:7;-1:-1:-1;;;;;80426:16:0;;:52;;;;80446:32;80463:5;80470:7;80446:16;:32::i;:::-;80426:87;;;;80506:7;-1:-1:-1;;;;;80482:31:0;:20;80494:7;80482:11;:20::i;:::-;-1:-1:-1;;;;;80482:31:0;;80426:87;80418:96;80258:264;-1:-1:-1;;;;80258:264:0:o;84257:1263::-;84416:4;-1:-1:-1;;;;;84389:31:0;:23;84404:7;84389:14;:23::i;:::-;-1:-1:-1;;;;;84389:31:0;;84381:81;;;;-1:-1:-1;;;84381:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;84481:16:0;;84473:65;;;;-1:-1:-1;;;84473:65:0;;22648:2:1;84473:65:0;;;22630:21:1;22687:2;22667:18;;;22660:30;22726:34;22706:18;;;22699:62;-1:-1:-1;;;22777:18:1;;;22770:34;22821:19;;84473:65:0;22446:400:1;84473:65:0;84551:42;84572:4;84578:2;84582:7;84591:1;84551:20;:42::i;:::-;84723:4;-1:-1:-1;;;;;84696:31:0;:23;84711:7;84696:14;:23::i;:::-;-1:-1:-1;;;;;84696:31:0;;84688:81;;;;-1:-1:-1;;;84688:81:0;;;;;;;:::i;:::-;84841:24;;;;:15;:24;;;;;;;;84834:31;;-1:-1:-1;;;;;;84834:31:0;;;;;;-1:-1:-1;;;;;85317:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;85317:20:0;;;85352:13;;;;;;;;;:18;;84834:31;85352:18;;;85392:16;;;:7;:16;;;;;;:21;;;;;;;;;;85431:27;;84857:7;;85431:27;;;85471:41;85491:4;85497:2;85501:7;85510:1;85471:19;:41::i;62507:246::-;62626:55;62649:7;62658:8;62668:12;62626:22;:55::i;:::-;62697:48;;-1:-1:-1;;;;;21271:39:1;;21253:58;;-1:-1:-1;;;;;62697:48:0;;;62713:7;;62697:48;;21241:2:1;21226:18;62697:48:0;;;;;;;;62507:246;;;:::o;44660:132::-;44568:6;;-1:-1:-1;;;;;44568:6:0;13136:10;44724:23;44716:68;;;;-1:-1:-1;;;44716:68:0;;23053:2:1;44716:68:0;;;23035:21:1;;;23072:18;;;23065:30;23131:34;23111:18;;;23104:62;23183:18;;44716:68:0;22851:356:1;45762:191:0;45855:6;;;-1:-1:-1;;;;;45872:17:0;;;-1:-1:-1;;;;;;45872:17:0;;;;;;;45905:40;;45855:6;;;45872:17;45855:6;;45905:40;;45836:16;;45905:40;45825:128;45762:191;:::o;85956:315::-;86111:8;-1:-1:-1;;;;;86102:17:0;:5;-1:-1:-1;;;;;86102:17:0;;86094:55;;;;-1:-1:-1;;;86094:55:0;;23414:2:1;86094:55:0;;;23396:21:1;23453:2;23433:18;;;23426:30;23492:27;23472:18;;;23465:55;23537:18;;86094:55:0;23212:349:1;86094:55:0;-1:-1:-1;;;;;86160:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;86160:46:0;;;;;;;;;;86222:41;;748::1;;;86222::0;;721:18:1;86222:41:0;608:187:1;79106:313:0;79262:28;79272:4;79278:2;79282:7;79262:9;:28::i;:::-;79309:47;79332:4;79338:2;79342:7;79351:4;79309:22;:47::i;:::-;79301:110;;;;-1:-1:-1;;;79301:110:0;;;;;;;:::i;103903:105::-;103955:13;103988:12;103981:19;;;;;:::i;52318:716::-;52374:13;52425:14;52442:17;52453:5;52442:10;:17::i;:::-;52462:1;52442:21;52425:38;;52478:20;52512:6;-1:-1:-1;;;;;52501:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52501:18:0;-1:-1:-1;52478:41:0;-1:-1:-1;52643:28:0;;;52659:2;52643:28;52700:288;-1:-1:-1;;52732:5:0;-1:-1:-1;;;52869:2:0;52858:14;;52853:30;52732:5;52840:44;52930:2;52921:11;;;-1:-1:-1;52951:21:0;52700:288;52951:21;-1:-1:-1;53009:6:0;52318:716;-1:-1:-1;;;52318:716:0:o;93397:289::-;93482:4;-1:-1:-1;;;;;;93516:46:0;;-1:-1:-1;;;93516:46:0;;:112;;-1:-1:-1;;;;;;;93576:52:0;;-1:-1:-1;;;93576:52:0;93516:112;:162;;;;93642:36;93666:11;93642:23;:36::i;60377:332::-;60093:5;-1:-1:-1;;;;;60480:33:0;;;;60472:88;;;;-1:-1:-1;;;60472:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;60579:22:0;;60571:60;;;;-1:-1:-1;;;60571:60:0;;24598:2:1;60571:60:0;;;24580:21:1;24637:2;24617:18;;;24610:30;24676:27;24656:18;;;24649:55;24721:18;;60571:60:0;24396:349:1;60571:60:0;60666:35;;;;;;;;;-1:-1:-1;;;;;60666:35:0;;;;;;-1:-1:-1;;;;;60666:35:0;;;;;;;;;;-1:-1:-1;;;60644:57:0;;;;:19;:57;60377:332::o;94232:354::-;94408:9;94403:176;94427:9;94423:1;:13;94403:176;;;94454:51;94478:4;94484:2;94488:16;94503:1;94488:12;:16;:::i;:::-;94454:23;:51::i;:::-;94549:3;;94403:176;;;;94232:354;;;;:::o;94699:352::-;94874:9;94869:175;94893:9;94889:1;:13;94869:175;;;94920:50;94943:4;94949:2;94953:16;94968:1;94953:12;:16;:::i;:::-;94920:22;:50::i;:::-;95014:3;;94869:175;;61160:390;60093:5;-1:-1:-1;;;;;61312:33:0;;;;61304:88;;;;-1:-1:-1;;;61304:88:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;61411:22:0;;61403:62;;;;-1:-1:-1;;;61403:62:0;;24952:2:1;61403:62:0;;;24934:21:1;24991:2;24971:18;;;24964:30;25030:29;25010:18;;;25003:57;25077:18;;61403:62:0;24750:351:1;61403:62:0;61507:35;;;;;;;;-1:-1:-1;;;;;61507:35:0;;;;;-1:-1:-1;;;;;61507:35:0;;;;;;;;;;-1:-1:-1;61478:26:0;;;:17;:26;;;;;;:64;;;;;;;-1:-1:-1;;;61478:64:0;;;;;;61160:390::o;87059:853::-;87213:4;-1:-1:-1;;;;;87234:13:0;;4499:19;:23;87230:675;;87270:71;;-1:-1:-1;;;87270:71:0;;-1:-1:-1;;;;;87270:36:0;;;;;:71;;13136:10;;87321:4;;87327:7;;87336:4;;87270:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;87270:71:0;;;;;;;;-1:-1:-1;;87270:71:0;;;;;;;;;;;;:::i;:::-;;;87266:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87511:6;:13;87528:1;87511:18;87507:328;;87554:60;;-1:-1:-1;;;87554:60:0;;;;;;;:::i;87507:328::-;87785:6;87779:13;87770:6;87766:2;87762:15;87755:38;87266:584;-1:-1:-1;;;;;;87392:51:0;-1:-1:-1;;;87392:51:0;;-1:-1:-1;87385:58:0;;87230:675;-1:-1:-1;87889:4:0;87059:853;;;;;;:::o;33853:922::-;33906:7;;-1:-1:-1;;;33984:15:0;;33980:102;;-1:-1:-1;;;34020:15:0;;;-1:-1:-1;34064:2:0;34054:12;33980:102;34109:6;34100:5;:15;34096:102;;34145:6;34136:15;;;-1:-1:-1;34180:2:0;34170:12;34096:102;34225:6;34216:5;:15;34212:102;;34261:6;34252:15;;;-1:-1:-1;34296:2:0;34286:12;34212:102;34341:5;34332;:14;34328:99;;34376:5;34367:14;;;-1:-1:-1;34410:1:0;34400:11;34328:99;34454:5;34445;:14;34441:99;;34489:5;34480:14;;;-1:-1:-1;34523:1:0;34513:11;34441:99;34567:5;34558;:14;34554:99;;34602:5;34593:14;;;-1:-1:-1;34636:1:0;34626:11;34554:99;34680:5;34671;:14;34667:66;;34716:1;34706:11;34761:6;33853:922;-1:-1:-1;;33853:922:0:o;74101:305::-;74203:4;-1:-1:-1;;;;;;74240:40:0;;-1:-1:-1;;;74240:40:0;;:105;;-1:-1:-1;;;;;;;74297:48:0;;-1:-1:-1;;;74297:48:0;74240:105;:158;;;-1:-1:-1;;;;;;;;;;55162:40:0;;;74362:36;55053:157;37740:623;-1:-1:-1;;;;;37867:18:0;;;;;37917:16;;;37867:18;37949:32;;;;;37968:13;37949:32;37946:410;;;38005:28;;-1:-1:-1;;;38005:28:0;;;;;;;;;;;37946:410;38054:15;38051:305;;;38086:54;38051:305;;;38161:13;38191:56;38158:198;38280:64;13136:10;38315:4;38321:2;38325:7;38334:9;38280:20;:64::i;38496:625::-;-1:-1:-1;;;;;38622:18:0;;;;;38672:16;;;38622:18;38704:32;;;;;38723:13;38704:32;38701:413;;;38760:28;;-1:-1:-1;;;38760:28:0;;;;;;;;;;;38701:413;38809:15;38841:55;38806:308;38917:13;38947:57;38914:200;39037:65;45401:201::o;70527:472::-;70722:17;70742:22;:20;:22::i;:::-;70722:42;-1:-1:-1;;;;;;70781:23:0;;;70777:215;;-1:-1:-1;;;;;70825:23:0;;:10;:23;70821:70;;70869:7;;;70821:70;70907:73;;-1:-1:-1;;;70907:73:0;;-1:-1:-1;;;;;26099:32:1;;;70907:73:0;;;26081:51:1;26168:32;;;26148:18;;;26141:60;26237:32;;;26217:18;;;26210:60;26286:18;;;26279:34;;;70907:46:0;;;;;26053:19:1;;70907:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;222:131:1;-1:-1:-1;;;;;;296:32:1;;286:43;;276:71;;343:1;340;333:12;358:245;416:6;469:2;457:9;448:7;444:23;440:32;437:52;;;485:1;482;475:12;437:52;524:9;511:23;543:30;567:5;543:30;:::i;800:131::-;-1:-1:-1;;;;;875:31:1;;865:42;;855:70;;921:1;918;911:12;936:137;-1:-1:-1;;;;;1014:5:1;1010:38;1003:5;1000:49;990:77;;1063:1;1060;1053:12;1078:386;1145:6;1153;1206:2;1194:9;1185:7;1181:23;1177:32;1174:52;;;1222:1;1219;1212:12;1174:52;1261:9;1248:23;1280:31;1305:5;1280:31;:::i;:::-;1330:5;-1:-1:-1;1387:2:1;1372:18;;1359:32;1400;1359;1400;:::i;:::-;1451:7;1441:17;;;1078:386;;;;;:::o;1469:250::-;1554:1;1564:113;1578:6;1575:1;1572:13;1564:113;;;1654:11;;;1648:18;1635:11;;;1628:39;1600:2;1593:10;1564:113;;;-1:-1:-1;;1711:1:1;1693:16;;1686:27;1469:250::o;1724:271::-;1766:3;1804:5;1798:12;1831:6;1826:3;1819:19;1847:76;1916:6;1909:4;1904:3;1900:14;1893:4;1886:5;1882:16;1847:76;:::i;:::-;1977:2;1956:15;-1:-1:-1;;1952:29:1;1943:39;;;;1984:4;1939:50;;1724:271;-1:-1:-1;;1724:271:1:o;2000:220::-;2149:2;2138:9;2131:21;2112:4;2169:45;2210:2;2199:9;2195:18;2187:6;2169:45;:::i;2225:226::-;2284:6;2337:2;2325:9;2316:7;2312:23;2308:32;2305:52;;;2353:1;2350;2343:12;2305:52;-1:-1:-1;2398:23:1;;2225:226;-1:-1:-1;2225:226:1:o;2456:367::-;2524:6;2532;2585:2;2573:9;2564:7;2560:23;2556:32;2553:52;;;2601:1;2598;2591:12;2553:52;2640:9;2627:23;2659:31;2684:5;2659:31;:::i;:::-;2709:5;2787:2;2772:18;;;;2759:32;;-1:-1:-1;;;2456:367:1:o;3116:::-;3179:8;3189:6;3243:3;3236:4;3228:6;3224:17;3220:27;3210:55;;3261:1;3258;3251:12;3210:55;-1:-1:-1;3284:20:1;;-1:-1:-1;;;;;3316:30:1;;3313:50;;;3359:1;3356;3349:12;3313:50;3396:4;3388:6;3384:17;3372:29;;3456:3;3449:4;3439:6;3436:1;3432:14;3424:6;3420:27;3416:38;3413:47;3410:67;;;3473:1;3470;3463:12;3488:768;3610:6;3618;3626;3634;3687:2;3675:9;3666:7;3662:23;3658:32;3655:52;;;3703:1;3700;3693:12;3655:52;3743:9;3730:23;-1:-1:-1;;;;;3768:6:1;3765:30;3762:50;;;3808:1;3805;3798:12;3762:50;3847:70;3909:7;3900:6;3889:9;3885:22;3847:70;:::i;:::-;3936:8;;-1:-1:-1;3821:96:1;-1:-1:-1;;4024:2:1;4009:18;;3996:32;-1:-1:-1;;;;;4040:32:1;;4037:52;;;4085:1;4082;4075:12;4037:52;4124:72;4188:7;4177:8;4166:9;4162:24;4124:72;:::i;:::-;3488:768;;;;-1:-1:-1;4215:8:1;-1:-1:-1;;;;3488:768:1:o;4261:508::-;4338:6;4346;4354;4407:2;4395:9;4386:7;4382:23;4378:32;4375:52;;;4423:1;4420;4413:12;4375:52;4462:9;4449:23;4481:31;4506:5;4481:31;:::i;:::-;4531:5;-1:-1:-1;4588:2:1;4573:18;;4560:32;4601:33;4560:32;4601:33;:::i;:::-;4261:508;;4653:7;;-1:-1:-1;;;4733:2:1;4718:18;;;;4705:32;;4261:508::o;4774:346::-;4842:6;4850;4903:2;4891:9;4882:7;4878:23;4874:32;4871:52;;;4919:1;4916;4909:12;4871:52;-1:-1:-1;;4964:23:1;;;5084:2;5069:18;;;5056:32;;-1:-1:-1;4774:346:1:o;5404:587::-;5475:6;5483;5536:2;5524:9;5515:7;5511:23;5507:32;5504:52;;;5552:1;5549;5542:12;5504:52;5592:9;5579:23;-1:-1:-1;;;;;5617:6:1;5614:30;5611:50;;;5657:1;5654;5647:12;5611:50;5680:22;;5733:4;5725:13;;5721:27;-1:-1:-1;5711:55:1;;5762:1;5759;5752:12;5711:55;5802:2;5789:16;-1:-1:-1;;;;;5820:6:1;5817:30;5814:50;;;5860:1;5857;5850:12;5814:50;5905:7;5900:2;5891:6;5887:2;5883:15;5879:24;5876:37;5873:57;;;5926:1;5923;5916:12;5873:57;5957:2;5949:11;;;;;5979:6;;-1:-1:-1;5404:587:1;-1:-1:-1;;;5404:587:1:o;5996:506::-;6072:6;6080;6088;6141:2;6129:9;6120:7;6116:23;6112:32;6109:52;;;6157:1;6154;6147:12;6109:52;6202:23;;;-1:-1:-1;6301:2:1;6286:18;;6273:32;6314:33;6273:32;6314:33;:::i;:::-;6366:7;-1:-1:-1;6425:2:1;6410:18;;6397:32;6438;6397;6438;:::i;:::-;6489:7;6479:17;;;5996:506;;;;;:::o;6507:108::-;6589:1;6582:5;6579:12;6569:40;;6605:1;6602;6595:12;6620:409;6702:6;6710;6763:2;6751:9;6742:7;6738:23;6734:32;6731:52;;;6779:1;6776;6769:12;6731:52;6818:9;6805:23;6837:31;6862:5;6837:31;:::i;:::-;6887:5;-1:-1:-1;6944:2:1;6929:18;;6916:32;6957:40;6916:32;6957:40;:::i;7216:247::-;7275:6;7328:2;7316:9;7307:7;7303:23;7299:32;7296:52;;;7344:1;7341;7334:12;7296:52;7383:9;7370:23;7402:31;7427:5;7402:31;:::i;7468:118::-;7554:5;7547:13;7540:21;7533:5;7530:32;7520:60;;7576:1;7573;7566:12;7591:241;7647:6;7700:2;7688:9;7679:7;7675:23;7671:32;7668:52;;;7716:1;7713;7706:12;7668:52;7755:9;7742:23;7774:28;7796:5;7774:28;:::i;7837:382::-;7902:6;7910;7963:2;7951:9;7942:7;7938:23;7934:32;7931:52;;;7979:1;7976;7969:12;7931:52;8018:9;8005:23;8037:31;8062:5;8037:31;:::i;:::-;8087:5;-1:-1:-1;8144:2:1;8129:18;;8116:32;8157:30;8116:32;8157:30;:::i;8224:127::-;8285:10;8280:3;8276:20;8273:1;8266:31;8316:4;8313:1;8306:15;8340:4;8337:1;8330:15;8356:253;8428:2;8422:9;8470:4;8458:17;;-1:-1:-1;;;;;8490:34:1;;8526:22;;;8487:62;8484:88;;;8552:18;;:::i;:::-;8588:2;8581:22;8356:253;:::o;8614:275::-;8685:2;8679:9;8750:2;8731:13;;-1:-1:-1;;8727:27:1;8715:40;;-1:-1:-1;;;;;8770:34:1;;8806:22;;;8767:62;8764:88;;;8832:18;;:::i;:::-;8868:2;8861:22;8614:275;;-1:-1:-1;8614:275:1:o;8894:1162::-;8989:6;8997;9005;9013;9066:3;9054:9;9045:7;9041:23;9037:33;9034:53;;;9083:1;9080;9073:12;9034:53;9122:9;9109:23;9141:31;9166:5;9141:31;:::i;:::-;9191:5;-1:-1:-1;9248:2:1;9233:18;;9220:32;9261:33;9220:32;9261:33;:::i;:::-;9313:7;-1:-1:-1;9393:2:1;9378:18;;9365:32;;-1:-1:-1;9474:2:1;9459:18;;9446:32;-1:-1:-1;;;;;9490:30:1;;9487:50;;;9533:1;9530;9523:12;9487:50;9556:22;;9609:4;9601:13;;9597:27;-1:-1:-1;9587:55:1;;9638:1;9635;9628:12;9587:55;9678:2;9665:16;-1:-1:-1;;;;;9696:6:1;9693:30;9690:56;;;9726:18;;:::i;:::-;9768:57;9815:2;9792:17;;-1:-1:-1;;9788:31:1;9821:2;9784:40;9768:57;:::i;:::-;9848:6;9841:5;9834:21;9896:7;9891:2;9882:6;9878:2;9874:15;9870:24;9867:37;9864:57;;;9917:1;9914;9907:12;9864:57;9972:6;9967:2;9963;9959:11;9954:2;9947:5;9943:14;9930:49;10024:1;10019:2;10010:6;10003:5;9999:18;9995:27;9988:38;10045:5;10035:15;;;;;8894:1162;;;;;;;:::o;10061:268::-;10134:6;10187:2;10175:9;10166:7;10162:23;10158:32;10155:52;;;10203:1;10200;10193:12;10155:52;10242:9;10229:23;10261:38;10293:5;10261:38;:::i;10334:388::-;10402:6;10410;10463:2;10451:9;10442:7;10438:23;10434:32;10431:52;;;10479:1;10476;10469:12;10431:52;10518:9;10505:23;10537:31;10562:5;10537:31;:::i;:::-;10587:5;-1:-1:-1;10644:2:1;10629:18;;10616:32;10657:33;10616:32;10657:33;:::i;10727:551::-;10822:6;10830;10838;10891:2;10879:9;10870:7;10866:23;10862:32;10859:52;;;10907:1;10904;10897:12;10859:52;10952:23;;;-1:-1:-1;11050:2:1;11035:18;;11022:32;-1:-1:-1;;;;;11066:30:1;;11063:50;;;11109:1;11106;11099:12;11063:50;11148:70;11210:7;11201:6;11190:9;11186:22;11148:70;:::i;:::-;10727:551;;11237:8;;-1:-1:-1;11122:96:1;;-1:-1:-1;;;;10727:551:1:o;11283:380::-;11362:1;11358:12;;;;11405;;;11426:61;;11480:4;11472:6;11468:17;11458:27;;11426:61;11533:2;11525:6;11522:14;11502:18;11499:38;11496:161;;11579:10;11574:3;11570:20;11567:1;11560:31;11614:4;11611:1;11604:15;11642:4;11639:1;11632:15;11496:161;;11283:380;;;:::o;12500:175::-;12578:13;;-1:-1:-1;;;;;12620:30:1;;12610:41;;12600:69;;12665:1;12662;12655:12;12600:69;12500:175;;;:::o;12680:163::-;12758:13;;12811:6;12800:18;;12790:29;;12780:57;;12833:1;12830;12823:12;12848:152;12934:13;;12956:38;12934:13;12956:38;:::i;13005:986::-;13121:6;13129;13173:9;13164:7;13160:23;13203:3;13199:2;13195:12;13192:32;;;13220:1;13217;13210:12;13192:32;13244:4;13240:2;13236:13;13233:33;;;13262:1;13259;13252:12;13233:33;;13288:22;;:::i;:::-;13339:9;13333:16;13326:5;13319:31;13395:2;13384:9;13380:18;13374:25;13408:32;13432:7;13408:32;:::i;:::-;13467:2;13456:14;;13449:31;13512:48;13556:2;13541:18;;13512:48;:::i;:::-;13507:2;13500:5;13496:14;13489:72;13593:48;13637:2;13626:9;13622:18;13593:48;:::i;:::-;13588:2;13581:5;13577:14;13570:72;13687:3;13676:9;13672:19;13666:26;13736:4;13727:7;13723:18;13714:7;13711:31;13701:59;;13756:1;13753;13746:12;13701:59;13787:3;13776:15;;13769:32;13834:49;13878:3;13863:19;;13834:49;:::i;:::-;13828:3;13817:15;;13810:74;13821:5;-1:-1:-1;13927:58:1;13979:4;13964:20;;13927:58;:::i;:::-;13917:68;;13005:986;;;;;:::o;13996:127::-;14057:10;14052:3;14048:20;14045:1;14038:31;14088:4;14085:1;14078:15;14112:4;14109:1;14102:15;14128:127;14189:10;14184:3;14180:20;14177:1;14170:31;14220:4;14217:1;14210:15;14244:4;14241:1;14234:15;14260:125;14325:9;;;14346:10;;;14343:36;;;14359:18;;:::i;14390:778::-;14610:4;14650:1;14642:6;14639:13;14629:144;;14695:10;14690:3;14686:20;14683:1;14676:31;14730:4;14727:1;14720:15;14758:4;14755:1;14748:15;14629:144;14782:25;;;-1:-1:-1;;;;;14843:32:1;;14838:2;14823:18;;14816:60;14912:2;14907;14892:18;;14885:30;;;14931:18;;14924:34;;;-1:-1:-1;;;;;14970:31:1;;14967:51;;;15014:1;15011;15004:12;14967:51;15048:6;15045:1;15041:14;15106:6;15098;15092:3;15081:9;15077:19;15064:49;15134:22;;;;15158:3;15130:32;;14390:778;-1:-1:-1;;;;;14390:778:1:o;15173:245::-;15240:6;15293:2;15281:9;15272:7;15268:23;15264:32;15261:52;;;15309:1;15306;15299:12;15261:52;15341:9;15335:16;15360:28;15382:5;15360:28;:::i;15423:127::-;15484:10;15479:3;15475:20;15472:1;15465:31;15515:4;15512:1;15505:15;15539:4;15536:1;15529:15;15555:251;15625:6;15678:2;15666:9;15657:7;15653:23;15649:32;15646:52;;;15694:1;15691;15684:12;15646:52;15726:9;15720:16;15745:31;15770:5;15745:31;:::i;15811:168::-;15884:9;;;15915;;15932:15;;;15926:22;;15912:37;15902:71;;15953:18;;:::i;16194:409::-;16396:2;16378:21;;;16435:2;16415:18;;;16408:30;16474:34;16469:2;16454:18;;16447:62;-1:-1:-1;;;16540:2:1;16525:18;;16518:43;16593:3;16578:19;;16194:409::o;16740:217::-;16780:1;16806;16796:132;;16850:10;16845:3;16841:20;16838:1;16831:31;16885:4;16882:1;16875:15;16913:4;16910:1;16903:15;16796:132;-1:-1:-1;16942:9:1;;16740:217::o;17088:518::-;17190:2;17185:3;17182:11;17179:421;;;17226:5;17223:1;17216:16;17270:4;17267:1;17257:18;17340:2;17328:10;17324:19;17321:1;17317:27;17311:4;17307:38;17376:4;17364:10;17361:20;17358:47;;;-1:-1:-1;17399:4:1;17358:47;17454:2;17449:3;17445:12;17442:1;17438:20;17432:4;17428:31;17418:41;;17509:81;17527:2;17520:5;17517:13;17509:81;;;17586:1;17572:16;;17553:1;17542:13;17509:81;;17782:1206;-1:-1:-1;;;;;17901:3:1;17898:27;17895:53;;;17928:18;;:::i;:::-;17957:94;18047:3;18007:38;18039:4;18033:11;18007:38;:::i;:::-;18001:4;17957:94;:::i;:::-;18077:1;18102:2;18097:3;18094:11;18119:1;18114:616;;;;18774:1;18791:3;18788:93;;;-1:-1:-1;18847:19:1;;;18834:33;18788:93;-1:-1:-1;;17739:1:1;17735:11;;;17731:24;17727:29;17717:40;17763:1;17759:11;;;17714:57;18894:78;;18087:895;;18114:616;17035:1;17028:14;;;17072:4;17059:18;;-1:-1:-1;;18150:17:1;;;18251:9;18273:229;18287:7;18284:1;18281:14;18273:229;;;18376:19;;;18363:33;18348:49;;18483:4;18468:20;;;;18436:1;18424:14;;;;18303:12;18273:229;;;18277:3;18530;18521:7;18518:16;18515:159;;;18654:1;18650:6;18644:3;18638;18635:1;18631:11;18627:21;18623:34;18619:39;18606:9;18601:3;18597:19;18584:33;18580:79;18572:6;18565:95;18515:159;;;18717:1;18711:3;18708:1;18704:11;18700:19;18694:4;18687:33;18087:895;;17782:1206;;;:::o;20061:496::-;20240:3;20278:6;20272:13;20294:66;20353:6;20348:3;20341:4;20333:6;20329:17;20294:66;:::i;:::-;20423:13;;20382:16;;;;20445:70;20423:13;20382:16;20492:4;20480:17;;20445:70;:::i;:::-;20531:20;;20061:496;-1:-1:-1;;;;20061:496:1:o;20562:135::-;20601:3;20622:17;;;20619:43;;20642:18;;:::i;:::-;-1:-1:-1;20689:1:1;20678:13;;20562:135::o;22040:401::-;22242:2;22224:21;;;22281:2;22261:18;;;22254:30;22320:34;22315:2;22300:18;;22293:62;-1:-1:-1;;;22386:2:1;22371:18;;22364:35;22431:3;22416:19;;22040:401::o;23566:414::-;23768:2;23750:21;;;23807:2;23787:18;;;23780:30;23846:34;23841:2;23826:18;;23819:62;-1:-1:-1;;;23912:2:1;23897:18;;23890:48;23970:3;23955:19;;23566:414::o;23985:406::-;24187:2;24169:21;;;24226:2;24206:18;;;24199:30;24265:34;24260:2;24245:18;;24238:62;-1:-1:-1;;;24331:2:1;24316:18;;24309:40;24381:3;24366:19;;23985:406::o;25106:485::-;-1:-1:-1;;;;;25337:32:1;;;25319:51;;25406:32;;25401:2;25386:18;;25379:60;25470:2;25455:18;;25448:34;;;25518:3;25513:2;25498:18;;25491:31;;;-1:-1:-1;;25539:46:1;;25565:19;;25557:6;25539:46;:::i;:::-;25531:54;25106:485;-1:-1:-1;;;;;;25106:485:1:o;25596:249::-;25665:6;25718:2;25706:9;25697:7;25693:23;25689:32;25686:52;;;25734:1;25731;25724:12;25686:52;25766:9;25760:16;25785:30;25809:5;25785:30;:::i
Swarm Source
ipfs://8af4946a76327b24cf38ea8674e864cae786a4d9c67a824bcad18f9b2a98a0a3
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.