Skip to content
ApeChain: Checking updates
ApeChain

Checking updates

Checking for new indexed heads.

Latest block
52,551,459
Updated

Code Reader

Read and search verified source.

Input

Try example

Verified source

Depix · Partial match

Contract
0xa128ecdb362786512af9e8b16fc3bb5f96ff78e8
File
Depix.sol

Verified source files

Depix.sol(contract Depix)2,734 lines
1// SPDX-License-Identifier: MIT
2pragma solidity ^0.8.28;
3
4// lib/creator-token-standards/src/interfaces/ICreatorToken.sol
5
6interface ICreatorToken {
7    event TransferValidatorUpdated(address oldValidator, address newValidator);
8    function getTransferValidator() external view returns (address validator);
9    function setTransferValidator(address validator) external;
10    function getTransferValidationFunction() external view returns (bytes4 functionSignature, bool isViewFunction);
11}
12
13// lib/creator-token-standards/src/interfaces/ICreatorTokenLegacy.sol
14
15interface ICreatorTokenLegacy {
16    event TransferValidatorUpdated(address oldValidator, address newValidator);
17    function getTransferValidator() external view returns (address validator);
18    function setTransferValidator(address validator) external;
19}
20
21// lib/creator-token-standards/src/interfaces/ITransferValidator.sol
22
23interface ITransferValidator {
24    function applyCollectionTransferPolicy(address caller, address from, address to) external view;
25    function validateTransfer(address caller, address from, address to) external view;
26    function validateTransfer(address caller, address from, address to, uint256 tokenId) external view;
27    function validateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount) external;
28
29    function beforeAuthorizedTransfer(address operator, address token, uint256 tokenId) external;
30    function afterAuthorizedTransfer(address token, uint256 tokenId) external;
31    function beforeAuthorizedTransfer(address operator, address token) external;
32    function afterAuthorizedTransfer(address token) external;
33    function beforeAuthorizedTransfer(address token, uint256 tokenId) external;
34    function beforeAuthorizedTransferWithAmount(address token, uint256 tokenId, uint256 amount) external;
35    function afterAuthorizedTransferWithAmount(address token, uint256 tokenId) external;
36}
37
38// lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol
39
40// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
41
42/**
43 * @title ERC721 token receiver interface
44 * @dev Interface for any contract that wants to support safeTransfers
45 * from ERC721 asset contracts.
46 */
47interface IERC721Receiver {
48    /**
49     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
50     * by `operator` from `from`, this function is called.
51     *
52     * It must return its Solidity selector to confirm the token transfer.
53     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
54     *
55     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
56     */
57    function onERC721Received(
58        address operator,
59        address from,
60        uint256 tokenId,
61        bytes calldata data
62    ) external returns (bytes4);
63}
64
65// lib/openzeppelin-contracts/contracts/utils/Address.sol
66
67// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
68
69/**
70 * @dev Collection of functions related to the address type
71 */
72library Address {
73    /**
74     * @dev Returns true if `account` is a contract.
75     *
76     * [IMPORTANT]
77     * ====
78     * It is unsafe to assume that an address for which this function returns
79     * false is an externally-owned account (EOA) and not a contract.
80     *
81     * Among others, `isContract` will return false for the following
82     * types of addresses:
83     *
84     *  - an externally-owned account
85     *  - a contract in construction
86     *  - an address where a contract will be created
87     *  - an address where a contract lived, but was destroyed
88     * ====
89     *
90     * [IMPORTANT]
91     * ====
92     * You shouldn't rely on `isContract` to protect against flash loan attacks!
93     *
94     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
95     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
96     * constructor.
97     * ====
98     */
99    function isContract(address account) internal view returns (bool) {
100        // This method relies on extcodesize/address.code.length, which returns 0
101        // for contracts in construction, since the code is only stored at the end
102        // of the constructor execution.
103
104        return account.code.length > 0;
105    }
106
107    /**
108     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
109     * `recipient`, forwarding all available gas and reverting on errors.
110     *
111     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
112     * of certain opcodes, possibly making contracts go over the 2300 gas limit
113     * imposed by `transfer`, making them unable to receive funds via
114     * `transfer`. {sendValue} removes this limitation.
115     *
116     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
117     *
118     * IMPORTANT: because control is transferred to `recipient`, care must be
119     * taken to not create reentrancy vulnerabilities. Consider using
120     * {ReentrancyGuard} or the
121     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
122     */
123    function sendValue(address payable recipient, uint256 amount) internal {
124        require(address(this).balance >= amount, "Address: insufficient balance");
125
126        (bool success, ) = recipient.call{value: amount}("");
127        require(success, "Address: unable to send value, recipient may have reverted");
128    }
129
130    /**
131     * @dev Performs a Solidity function call using a low level `call`. A
132     * plain `call` is an unsafe replacement for a function call: use this
133     * function instead.
134     *
135     * If `target` reverts with a revert reason, it is bubbled up by this
136     * function (like regular Solidity function calls).
137     *
138     * Returns the raw returned data. To convert to the expected return value,
139     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
140     *
141     * Requirements:
142     *
143     * - `target` must be a contract.
144     * - calling `target` with `data` must not revert.
145     *
146     * _Available since v3.1._
147     */
148    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
149        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
150    }
151
152    /**
153     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
154     * `errorMessage` as a fallback revert reason when `target` reverts.
155     *
156     * _Available since v3.1._
157     */
158    function functionCall(
159        address target,
160        bytes memory data,
161        string memory errorMessage
162    ) internal returns (bytes memory) {
163        return functionCallWithValue(target, data, 0, errorMessage);
164    }
165
166    /**
167     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
168     * but also transferring `value` wei to `target`.
169     *
170     * Requirements:
171     *
172     * - the calling contract must have an ETH balance of at least `value`.
173     * - the called Solidity function must be `payable`.
174     *
175     * _Available since v3.1._
176     */
177    function functionCallWithValue(
178        address target,
179        bytes memory data,
180        uint256 value
181    ) internal returns (bytes memory) {
182        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
183    }
184
185    /**
186     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
187     * with `errorMessage` as a fallback revert reason when `target` reverts.
188     *
189     * _Available since v3.1._
190     */
191    function functionCallWithValue(
192        address target,
193        bytes memory data,
194        uint256 value,
195        string memory errorMessage
196    ) internal returns (bytes memory) {
197        require(address(this).balance >= value, "Address: insufficient balance for call");
198        (bool success, bytes memory returndata) = target.call{value: value}(data);
199        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
200    }
201
202    /**
203     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
204     * but performing a static call.
205     *
206     * _Available since v3.3._
207     */
208    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
209        return functionStaticCall(target, data, "Address: low-level static call failed");
210    }
211
212    /**
213     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
214     * but performing a static call.
215     *
216     * _Available since v3.3._
217     */
218    function functionStaticCall(
219        address target,
220        bytes memory data,
221        string memory errorMessage
222    ) internal view returns (bytes memory) {
223        (bool success, bytes memory returndata) = target.staticcall(data);
224        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
225    }
226
227    /**
228     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
229     * but performing a delegate call.
230     *
231     * _Available since v3.4._
232     */
233    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
234        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
235    }
236
237    /**
238     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
239     * but performing a delegate call.
240     *
241     * _Available since v3.4._
242     */
243    function functionDelegateCall(
244        address target,
245        bytes memory data,
246        string memory errorMessage
247    ) internal returns (bytes memory) {
248        (bool success, bytes memory returndata) = target.delegatecall(data);
249        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
250    }
251
252    /**
253     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
254     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
255     *
256     * _Available since v4.8._
257     */
258    function verifyCallResultFromTarget(
259        address target,
260        bool success,
261        bytes memory returndata,
262        string memory errorMessage
263    ) internal view returns (bytes memory) {
264        if (success) {
265            if (returndata.length == 0) {
266                // only check isContract if the call was successful and the return data is empty
267                // otherwise we already know that it was a contract
268                require(isContract(target), "Address: call to non-contract");
269            }
270            return returndata;
271        } else {
272            _revert(returndata, errorMessage);
273        }
274    }
275
276    /**
277     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
278     * revert reason or using the provided one.
279     *
280     * _Available since v4.3._
281     */
282    function verifyCallResult(
283        bool success,
284        bytes memory returndata,
285        string memory errorMessage
286    ) internal pure returns (bytes memory) {
287        if (success) {
288            return returndata;
289        } else {
290            _revert(returndata, errorMessage);
291        }
292    }
293
294    function _revert(bytes memory returndata, string memory errorMessage) private pure {
295        // Look for revert reason and bubble it up if present
296        if (returndata.length > 0) {
297            // The easiest way to bubble the revert reason is using memory via assembly
298            /// @solidity memory-safe-assembly
299            assembly {
300                let returndata_size := mload(returndata)
301                revert(add(32, returndata), returndata_size)
302            }
303        } else {
304            revert(errorMessage);
305        }
306    }
307}
308
309// lib/openzeppelin-contracts/contracts/utils/Context.sol
310
311// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
312
313/**
314 * @dev Provides information about the current execution context, including the
315 * sender of the transaction and its data. While these are generally available
316 * via msg.sender and msg.data, they should not be accessed in such a direct
317 * manner, since when dealing with meta-transactions the account sending and
318 * paying for execution may not be the actual sender (as far as an application
319 * is concerned).
320 *
321 * This contract is only required for intermediate, library-like contracts.
322 */
323abstract contract Context {
324    function _msgSender() internal view virtual returns (address) {
325        return msg.sender;
326    }
327
328    function _msgData() internal view virtual returns (bytes calldata) {
329        return msg.data;
330    }
331}
332
333// lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol
334
335// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)
336
337/**
338 * @dev These functions deal with verification of Merkle Tree proofs.
339 *
340 * The tree and the proofs can be generated using our
341 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
342 * You will find a quickstart guide in the readme.
343 *
344 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
345 * hashing, or use a hash function other than keccak256 for hashing leaves.
346 * This is because the concatenation of a sorted pair of internal nodes in
347 * the merkle tree could be reinterpreted as a leaf value.
348 * OpenZeppelin's JavaScript library generates merkle trees that are safe
349 * against this attack out of the box.
350 */
351library MerkleProof {
352    /**
353     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
354     * defined by `root`. For this, a `proof` must be provided, containing
355     * sibling hashes on the branch from the leaf to the root of the tree. Each
356     * pair of leaves and each pair of pre-images are assumed to be sorted.
357     */
358    function verify(
359        bytes32[] memory proof,
360        bytes32 root,
361        bytes32 leaf
362    ) internal pure returns (bool) {
363        return processProof(proof, leaf) == root;
364    }
365
366    /**
367     * @dev Calldata version of {verify}
368     *
369     * _Available since v4.7._
370     */
371    function verifyCalldata(
372        bytes32[] calldata proof,
373        bytes32 root,
374        bytes32 leaf
375    ) internal pure returns (bool) {
376        return processProofCalldata(proof, leaf) == root;
377    }
378
379    /**
380     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
381     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
382     * hash matches the root of the tree. When processing the proof, the pairs
383     * of leafs & pre-images are assumed to be sorted.
384     *
385     * _Available since v4.4._
386     */
387    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
388        bytes32 computedHash = leaf;
389        for (uint256 i = 0; i < proof.length; i++) {
390            computedHash = _hashPair(computedHash, proof[i]);
391        }
392        return computedHash;
393    }
394
395    /**
396     * @dev Calldata version of {processProof}
397     *
398     * _Available since v4.7._
399     */
400    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
401        bytes32 computedHash = leaf;
402        for (uint256 i = 0; i < proof.length; i++) {
403            computedHash = _hashPair(computedHash, proof[i]);
404        }
405        return computedHash;
406    }
407
408    /**
409     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
410     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
411     *
412     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
413     *
414     * _Available since v4.7._
415     */
416    function multiProofVerify(
417        bytes32[] memory proof,
418        bool[] memory proofFlags,
419        bytes32 root,
420        bytes32[] memory leaves
421    ) internal pure returns (bool) {
422        return processMultiProof(proof, proofFlags, leaves) == root;
423    }
424
425    /**
426     * @dev Calldata version of {multiProofVerify}
427     *
428     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
429     *
430     * _Available since v4.7._
431     */
432    function multiProofVerifyCalldata(
433        bytes32[] calldata proof,
434        bool[] calldata proofFlags,
435        bytes32 root,
436        bytes32[] memory leaves
437    ) internal pure returns (bool) {
438        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
439    }
440
441    /**
442     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
443     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
444     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
445     * respectively.
446     *
447     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
448     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
449     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
450     *
451     * _Available since v4.7._
452     */
453    function processMultiProof(
454        bytes32[] memory proof,
455        bool[] memory proofFlags,
456        bytes32[] memory leaves
457    ) internal pure returns (bytes32 merkleRoot) {
458        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
459        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
460        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
461        // the merkle tree.
462        uint256 leavesLen = leaves.length;
463        uint256 totalHashes = proofFlags.length;
464
465        // Check proof validity.
466        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
467
468        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
469        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
470        bytes32[] memory hashes = new bytes32[](totalHashes);
471        uint256 leafPos = 0;
472        uint256 hashPos = 0;
473        uint256 proofPos = 0;
474        // At each step, we compute the next hash using two values:
475        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
476        //   get the next hash.
477        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
478        //   `proof` array.
479        for (uint256 i = 0; i < totalHashes; i++) {
480            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
481            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
482            hashes[i] = _hashPair(a, b);
483        }
484
485        if (totalHashes > 0) {
486            return hashes[totalHashes - 1];
487        } else if (leavesLen > 0) {
488            return leaves[0];
489        } else {
490            return proof[0];
491        }
492    }
493
494    /**
495     * @dev Calldata version of {processMultiProof}.
496     *
497     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
498     *
499     * _Available since v4.7._
500     */
501    function processMultiProofCalldata(
502        bytes32[] calldata proof,
503        bool[] calldata proofFlags,
504        bytes32[] memory leaves
505    ) internal pure returns (bytes32 merkleRoot) {
506        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
507        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
508        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
509        // the merkle tree.
510        uint256 leavesLen = leaves.length;
511        uint256 totalHashes = proofFlags.length;
512
513        // Check proof validity.
514        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
515
516        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
517        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
518        bytes32[] memory hashes = new bytes32[](totalHashes);
519        uint256 leafPos = 0;
520        uint256 hashPos = 0;
521        uint256 proofPos = 0;
522        // At each step, we compute the next hash using two values:
523        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
524        //   get the next hash.
525        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
526        //   `proof` array.
527        for (uint256 i = 0; i < totalHashes; i++) {
528            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
529            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
530            hashes[i] = _hashPair(a, b);
531        }
532
533        if (totalHashes > 0) {
534            return hashes[totalHashes - 1];
535        } else if (leavesLen > 0) {
536            return leaves[0];
537        } else {
538            return proof[0];
539        }
540    }
541
542    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
543        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
544    }
545
546    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
547        /// @solidity memory-safe-assembly
548        assembly {
549            mstore(0x00, a)
550            mstore(0x20, b)
551            value := keccak256(0x00, 0x40)
552        }
553    }
554}
555
556// lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
557
558// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
559
560/**
561 * @dev Interface of the ERC165 standard, as defined in the
562 * https://eips.ethereum.org/EIPS/eip-165[EIP].
563 *
564 * Implementers can declare support of contract interfaces, which can then be
565 * queried by others ({ERC165Checker}).
566 *
567 * For an implementation, see {ERC165}.
568 */
569interface IERC165 {
570    /**
571     * @dev Returns true if this contract implements the interface defined by
572     * `interfaceId`. See the corresponding
573     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
574     * to learn more about how these ids are created.
575     *
576     * This function call must use less than 30 000 gas.
577     */
578    function supportsInterface(bytes4 interfaceId) external view returns (bool);
579}
580
581// lib/openzeppelin-contracts/contracts/utils/math/Math.sol
582
583// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
584
585/**
586 * @dev Standard math utilities missing in the Solidity language.
587 */
588library Math {
589    enum Rounding {
590        Down, // Toward negative infinity
591        Up, // Toward infinity
592        Zero // Toward zero
593    }
594
595    /**
596     * @dev Returns the largest of two numbers.
597     */
598    function max(uint256 a, uint256 b) internal pure returns (uint256) {
599        return a > b ? a : b;
600    }
601
602    /**
603     * @dev Returns the smallest of two numbers.
604     */
605    function min(uint256 a, uint256 b) internal pure returns (uint256) {
606        return a < b ? a : b;
607    }
608
609    /**
610     * @dev Returns the average of two numbers. The result is rounded towards
611     * zero.
612     */
613    function average(uint256 a, uint256 b) internal pure returns (uint256) {
614        // (a + b) / 2 can overflow.
615        return (a & b) + (a ^ b) / 2;
616    }
617
618    /**
619     * @dev Returns the ceiling of the division of two numbers.
620     *
621     * This differs from standard division with `/` in that it rounds up instead
622     * of rounding down.
623     */
624    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
625        // (a + b - 1) / b can overflow on addition, so we distribute.
626        return a == 0 ? 0 : (a - 1) / b + 1;
627    }
628
629    /**
630     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
631     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
632     * with further edits by Uniswap Labs also under MIT license.
633     */
634    function mulDiv(
635        uint256 x,
636        uint256 y,
637        uint256 denominator
638    ) internal pure returns (uint256 result) {
639        unchecked {
640            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
641            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
642            // variables such that product = prod1 * 2^256 + prod0.
643            uint256 prod0; // Least significant 256 bits of the product
644            uint256 prod1; // Most significant 256 bits of the product
645            assembly {
646                let mm := mulmod(x, y, not(0))
647                prod0 := mul(x, y)
648                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
649            }
650
651            // Handle non-overflow cases, 256 by 256 division.
652            if (prod1 == 0) {
653                return prod0 / denominator;
654            }
655
656            // Make sure the result is less than 2^256. Also prevents denominator == 0.
657            require(denominator > prod1);
658
659            ///////////////////////////////////////////////
660            // 512 by 256 division.
661            ///////////////////////////////////////////////
662
663            // Make division exact by subtracting the remainder from [prod1 prod0].
664            uint256 remainder;
665            assembly {
666                // Compute remainder using mulmod.
667                remainder := mulmod(x, y, denominator)
668
669                // Subtract 256 bit number from 512 bit number.
670                prod1 := sub(prod1, gt(remainder, prod0))
671                prod0 := sub(prod0, remainder)
672            }
673
674            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
675            // See https://cs.stackexchange.com/q/138556/92363.
676
677            // Does not overflow because the denominator cannot be zero at this stage in the function.
678            uint256 twos = denominator & (~denominator + 1);
679            assembly {
680                // Divide denominator by twos.
681                denominator := div(denominator, twos)
682
683                // Divide [prod1 prod0] by twos.
684                prod0 := div(prod0, twos)
685
686                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
687                twos := add(div(sub(0, twos), twos), 1)
688            }
689
690            // Shift in bits from prod1 into prod0.
691            prod0 |= prod1 * twos;
692
693            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
694            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
695            // four bits. That is, denominator * inv = 1 mod 2^4.
696            uint256 inverse = (3 * denominator) ^ 2;
697
698            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
699            // in modular arithmetic, doubling the correct bits in each step.
700            inverse *= 2 - denominator * inverse; // inverse mod 2^8
701            inverse *= 2 - denominator * inverse; // inverse mod 2^16
702            inverse *= 2 - denominator * inverse; // inverse mod 2^32
703            inverse *= 2 - denominator * inverse; // inverse mod 2^64
704            inverse *= 2 - denominator * inverse; // inverse mod 2^128
705            inverse *= 2 - denominator * inverse; // inverse mod 2^256
706
707            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
708            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
709            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
710            // is no longer required.
711            result = prod0 * inverse;
712            return result;
713        }
714    }
715
716    /**
717     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
718     */
719    function mulDiv(
720        uint256 x,
721        uint256 y,
722        uint256 denominator,
723        Rounding rounding
724    ) internal pure returns (uint256) {
725        uint256 result = mulDiv(x, y, denominator);
726        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
727            result += 1;
728        }
729        return result;
730    }
731
732    /**
733     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
734     *
735     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
736     */
737    function sqrt(uint256 a) internal pure returns (uint256) {
738        if (a == 0) {
739            return 0;
740        }
741
742        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
743        //
744        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
745        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
746        //
747        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
748        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
749        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
750        //
751        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
752        uint256 result = 1 << (log2(a) >> 1);
753
754        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
755        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
756        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
757        // into the expected uint128 result.
758        unchecked {
759            result = (result + a / result) >> 1;
760            result = (result + a / result) >> 1;
761            result = (result + a / result) >> 1;
762            result = (result + a / result) >> 1;
763            result = (result + a / result) >> 1;
764            result = (result + a / result) >> 1;
765            result = (result + a / result) >> 1;
766            return min(result, a / result);
767        }
768    }
769
770    /**
771     * @notice Calculates sqrt(a), following the selected rounding direction.
772     */
773    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
774        unchecked {
775            uint256 result = sqrt(a);
776            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
777        }
778    }
779
780    /**
781     * @dev Return the log in base 2, rounded down, of a positive value.
782     * Returns 0 if given 0.
783     */
784    function log2(uint256 value) internal pure returns (uint256) {
785        uint256 result = 0;
786        unchecked {
787            if (value >> 128 > 0) {
788                value >>= 128;
789                result += 128;
790            }
791            if (value >> 64 > 0) {
792                value >>= 64;
793                result += 64;
794            }
795            if (value >> 32 > 0) {
796                value >>= 32;
797                result += 32;
798            }
799            if (value >> 16 > 0) {
800                value >>= 16;
801                result += 16;
802            }
803            if (value >> 8 > 0) {
804                value >>= 8;
805                result += 8;
806            }
807            if (value >> 4 > 0) {
808                value >>= 4;
809                result += 4;
810            }
811            if (value >> 2 > 0) {
812                value >>= 2;
813                result += 2;
814            }
815            if (value >> 1 > 0) {
816                result += 1;
817            }
818        }
819        return result;
820    }
821
822    /**
823     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
824     * Returns 0 if given 0.
825     */
826    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
827        unchecked {
828            uint256 result = log2(value);
829            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
830        }
831    }
832
833    /**
834     * @dev Return the log in base 10, rounded down, of a positive value.
835     * Returns 0 if given 0.
836     */
837    function log10(uint256 value) internal pure returns (uint256) {
838        uint256 result = 0;
839        unchecked {
840            if (value >= 10**64) {
841                value /= 10**64;
842                result += 64;
843            }
844            if (value >= 10**32) {
845                value /= 10**32;
846                result += 32;
847            }
848            if (value >= 10**16) {
849                value /= 10**16;
850                result += 16;
851            }
852            if (value >= 10**8) {
853                value /= 10**8;
854                result += 8;
855            }
856            if (value >= 10**4) {
857                value /= 10**4;
858                result += 4;
859            }
860            if (value >= 10**2) {
861                value /= 10**2;
862                result += 2;
863            }
864            if (value >= 10**1) {
865                result += 1;
866            }
867        }
868        return result;
869    }
870
871    /**
872     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
873     * Returns 0 if given 0.
874     */
875    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
876        unchecked {
877            uint256 result = log10(value);
878            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
879        }
880    }
881
882    /**
883     * @dev Return the log in base 256, rounded down, of a positive value.
884     * Returns 0 if given 0.
885     *
886     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
887     */
888    function log256(uint256 value) internal pure returns (uint256) {
889        uint256 result = 0;
890        unchecked {
891            if (value >> 128 > 0) {
892                value >>= 128;
893                result += 16;
894            }
895            if (value >> 64 > 0) {
896                value >>= 64;
897                result += 8;
898            }
899            if (value >> 32 > 0) {
900                value >>= 32;
901                result += 4;
902            }
903            if (value >> 16 > 0) {
904                value >>= 16;
905                result += 2;
906            }
907            if (value >> 8 > 0) {
908                result += 1;
909            }
910        }
911        return result;
912    }
913
914    /**
915     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
916     * Returns 0 if given 0.
917     */
918    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
919        unchecked {
920            uint256 result = log256(value);
921            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
922        }
923    }
924}
925
926// lib/creator-token-standards/src/access/OwnablePermissions.sol
927
928abstract contract OwnablePermissions is Context {
929    function _requireCallerIsContractOwner() internal view virtual;
930}
931
932// lib/creator-token-standards/src/utils/TransferValidation.sol
933
934/**
935 * @title TransferValidation
936 * @author Limit Break, Inc.
937 * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks.
938 * Openzeppelin's ERC721 contract only provides hooks for before and after transfer.  This allows
939 * developers to validate or customize transfers within the context of a mint, a burn, or a transfer.
940 */
941abstract contract TransferValidation is Context {
942    
943    /// @dev Thrown when the from and to address are both the zero address.
944    error ShouldNotMintToBurnAddress();
945
946    /*************************************************************************/
947    /*                      Transfers Without Amounts                        */
948    /*************************************************************************/
949
950    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
951    function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual {
952        bool fromZeroAddress = from == address(0);
953        bool toZeroAddress = to == address(0);
954
955        if(fromZeroAddress && toZeroAddress) {
956            revert ShouldNotMintToBurnAddress();
957        } else if(fromZeroAddress) {
958            _preValidateMint(_msgSender(), to, tokenId, msg.value);
959        } else if(toZeroAddress) {
960            _preValidateBurn(_msgSender(), from, tokenId, msg.value);
961        } else {
962            _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
963        }
964    }
965
966    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
967    function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual {
968        bool fromZeroAddress = from == address(0);
969        bool toZeroAddress = to == address(0);
970
971        if(fromZeroAddress && toZeroAddress) {
972            revert ShouldNotMintToBurnAddress();
973        } else if(fromZeroAddress) {
974            _postValidateMint(_msgSender(), to, tokenId, msg.value);
975        } else if(toZeroAddress) {
976            _postValidateBurn(_msgSender(), from, tokenId, msg.value);
977        } else {
978            _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value);
979        }
980    }
981
982    /// @dev Optional validation hook that fires before a mint
983    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}
984
985    /// @dev Optional validation hook that fires after a mint
986    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {}
987
988    /// @dev Optional validation hook that fires before a burn
989    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}
990
991    /// @dev Optional validation hook that fires after a burn
992    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {}
993
994    /// @dev Optional validation hook that fires before a transfer
995    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}
996
997    /// @dev Optional validation hook that fires after a transfer
998    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {}
999
1000    /*************************************************************************/
1001    /*                         Transfers With Amounts                        */
1002    /*************************************************************************/
1003
1004    /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks.
1005    function _validateBeforeTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual {
1006        bool fromZeroAddress = from == address(0);
1007        bool toZeroAddress = to == address(0);
1008
1009        if(fromZeroAddress && toZeroAddress) {
1010            revert ShouldNotMintToBurnAddress();
1011        } else if(fromZeroAddress) {
1012            _preValidateMint(_msgSender(), to, tokenId, amount, msg.value);
1013        } else if(toZeroAddress) {
1014            _preValidateBurn(_msgSender(), from, tokenId, amount, msg.value);
1015        } else {
1016            _preValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value);
1017        }
1018    }
1019
1020    /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks.
1021    function _validateAfterTransfer(address from, address to, uint256 tokenId, uint256 amount) internal virtual {
1022        bool fromZeroAddress = from == address(0);
1023        bool toZeroAddress = to == address(0);
1024
1025        if(fromZeroAddress && toZeroAddress) {
1026            revert ShouldNotMintToBurnAddress();
1027        } else if(fromZeroAddress) {
1028            _postValidateMint(_msgSender(), to, tokenId, amount, msg.value);
1029        } else if(toZeroAddress) {
1030            _postValidateBurn(_msgSender(), from, tokenId, amount, msg.value);
1031        } else {
1032            _postValidateTransfer(_msgSender(), from, to, tokenId, amount, msg.value);
1033        }
1034    }
1035
1036    /// @dev Optional validation hook that fires before a mint
1037    function _preValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1038
1039    /// @dev Optional validation hook that fires after a mint
1040    function _postValidateMint(address caller, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1041
1042    /// @dev Optional validation hook that fires before a burn
1043    function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1044
1045    /// @dev Optional validation hook that fires after a burn
1046    function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1047
1048    /// @dev Optional validation hook that fires before a transfer
1049    function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1050
1051    /// @dev Optional validation hook that fires after a transfer
1052    function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 amount, uint256 value) internal virtual {}
1053}
1054
1055// lib/openzeppelin-contracts/contracts/access/Ownable.sol
1056
1057// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
1058
1059/**
1060 * @dev Contract module which provides a basic access control mechanism, where
1061 * there is an account (an owner) that can be granted exclusive access to
1062 * specific functions.
1063 *
1064 * By default, the owner account will be the one that deploys the contract. This
1065 * can later be changed with {transferOwnership}.
1066 *
1067 * This module is used through inheritance. It will make available the modifier
1068 * `onlyOwner`, which can be applied to your functions to restrict their use to
1069 * the owner.
1070 */
1071abstract contract Ownable is Context {
1072    address private _owner;
1073
1074    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
1075
1076    /**
1077     * @dev Initializes the contract setting the deployer as the initial owner.
1078     */
1079    constructor() {
1080        _transferOwnership(_msgSender());
1081    }
1082
1083    /**
1084     * @dev Throws if called by any account other than the owner.
1085     */
1086    modifier onlyOwner() {
1087        _checkOwner();
1088        _;
1089    }
1090
1091    /**
1092     * @dev Returns the address of the current owner.
1093     */
1094    function owner() public view virtual returns (address) {
1095        return _owner;
1096    }
1097
1098    /**
1099     * @dev Throws if the sender is not the owner.
1100     */
1101    function _checkOwner() internal view virtual {
1102        require(owner() == _msgSender(), "Ownable: caller is not the owner");
1103    }
1104
1105    /**
1106     * @dev Leaves the contract without owner. It will not be possible to call
1107     * `onlyOwner` functions anymore. Can only be called by the current owner.
1108     *
1109     * NOTE: Renouncing ownership will leave the contract without an owner,
1110     * thereby removing any functionality that is only available to the owner.
1111     */
1112    function renounceOwnership() public virtual onlyOwner {
1113        _transferOwnership(address(0));
1114    }
1115
1116    /**
1117     * @dev Transfers ownership of the contract to a new account (`newOwner`).
1118     * Can only be called by the current owner.
1119     */
1120    function transferOwnership(address newOwner) public virtual onlyOwner {
1121        require(newOwner != address(0), "Ownable: new owner is the zero address");
1122        _transferOwnership(newOwner);
1123    }
1124
1125    /**
1126     * @dev Transfers ownership of the contract to a new account (`newOwner`).
1127     * Internal function without access restriction.
1128     */
1129    function _transferOwnership(address newOwner) internal virtual {
1130        address oldOwner = _owner;
1131        _owner = newOwner;
1132        emit OwnershipTransferred(oldOwner, newOwner);
1133    }
1134}
1135
1136// lib/openzeppelin-contracts/contracts/interfaces/IERC2981.sol
1137
1138// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
1139
1140/**
1141 * @dev Interface for the NFT Royalty Standard.
1142 *
1143 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
1144 * support for royalty payments across all NFT marketplaces and ecosystem participants.
1145 *
1146 * _Available since v4.5._
1147 */
1148interface IERC2981 is IERC165 {
1149    /**
1150     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
1151     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
1152     */
1153    function royaltyInfo(uint256 tokenId, uint256 salePrice)
1154        external
1155        view
1156        returns (address receiver, uint256 royaltyAmount);
1157}
1158
1159// lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol
1160
1161// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)
1162
1163/**
1164 * @dev Required interface of an ERC721 compliant contract.
1165 */
1166interface IERC721 is IERC165 {
1167    /**
1168     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
1169     */
1170    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
1171
1172    /**
1173     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
1174     */
1175    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
1176
1177    /**
1178     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
1179     */
1180    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
1181
1182    /**
1183     * @dev Returns the number of tokens in ``owner``'s account.
1184     */
1185    function balanceOf(address owner) external view returns (uint256 balance);
1186
1187    /**
1188     * @dev Returns the owner of the `tokenId` token.
1189     *
1190     * Requirements:
1191     *
1192     * - `tokenId` must exist.
1193     */
1194    function ownerOf(uint256 tokenId) external view returns (address owner);
1195
1196    /**
1197     * @dev Safely transfers `tokenId` token from `from` to `to`.
1198     *
1199     * Requirements:
1200     *
1201     * - `from` cannot be the zero address.
1202     * - `to` cannot be the zero address.
1203     * - `tokenId` token must exist and be owned by `from`.
1204     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
1205     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
1206     *
1207     * Emits a {Transfer} event.
1208     */
1209    function safeTransferFrom(
1210        address from,
1211        address to,
1212        uint256 tokenId,
1213        bytes calldata data
1214    ) external;
1215
1216    /**
1217     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
1218     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
1219     *
1220     * Requirements:
1221     *
1222     * - `from` cannot be the zero address.
1223     * - `to` cannot be the zero address.
1224     * - `tokenId` token must exist and be owned by `from`.
1225     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
1226     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
1227     *
1228     * Emits a {Transfer} event.
1229     */
1230    function safeTransferFrom(
1231        address from,
1232        address to,
1233        uint256 tokenId
1234    ) external;
1235
1236    /**
1237     * @dev Transfers `tokenId` token from `from` to `to`.
1238     *
1239     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
1240     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
1241     * understand this adds an external call which potentially creates a reentrancy vulnerability.
1242     *
1243     * Requirements:
1244     *
1245     * - `from` cannot be the zero address.
1246     * - `to` cannot be the zero address.
1247     * - `tokenId` token must be owned by `from`.
1248     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
1249     *
1250     * Emits a {Transfer} event.
1251     */
1252    function transferFrom(
1253        address from,
1254        address to,
1255        uint256 tokenId
1256    ) external;
1257
1258    /**
1259     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
1260     * The approval is cleared when the token is transferred.
1261     *
1262     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
1263     *
1264     * Requirements:
1265     *
1266     * - The caller must own the token or be an approved operator.
1267     * - `tokenId` must exist.
1268     *
1269     * Emits an {Approval} event.
1270     */
1271    function approve(address to, uint256 tokenId) external;
1272
1273    /**
1274     * @dev Approve or remove `operator` as an operator for the caller.
1275     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
1276     *
1277     * Requirements:
1278     *
1279     * - The `operator` cannot be the caller.
1280     *
1281     * Emits an {ApprovalForAll} event.
1282     */
1283    function setApprovalForAll(address operator, bool _approved) external;
1284
1285    /**
1286     * @dev Returns the account approved for `tokenId` token.
1287     *
1288     * Requirements:
1289     *
1290     * - `tokenId` must exist.
1291     */
1292    function getApproved(uint256 tokenId) external view returns (address operator);
1293
1294    /**
1295     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
1296     *
1297     * See {setApprovalForAll}
1298     */
1299    function isApprovedForAll(address owner, address operator) external view returns (bool);
1300}
1301
1302// lib/openzeppelin-contracts/contracts/utils/Strings.sol
1303
1304// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
1305
1306/**
1307 * @dev String operations.
1308 */
1309library Strings {
1310    bytes16 private constant _SYMBOLS = "0123456789abcdef";
1311    uint8 private constant _ADDRESS_LENGTH = 20;
1312
1313    /**
1314     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
1315     */
1316    function toString(uint256 value) internal pure returns (string memory) {
1317        unchecked {
1318            uint256 length = Math.log10(value) + 1;
1319            string memory buffer = new string(length);
1320            uint256 ptr;
1321            /// @solidity memory-safe-assembly
1322            assembly {
1323                ptr := add(buffer, add(32, length))
1324            }
1325            while (true) {
1326                ptr--;
1327                /// @solidity memory-safe-assembly
1328                assembly {
1329                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
1330                }
1331                value /= 10;
1332                if (value == 0) break;
1333            }
1334            return buffer;
1335        }
1336    }
1337
1338    /**
1339     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
1340     */
1341    function toHexString(uint256 value) internal pure returns (string memory) {
1342        unchecked {
1343            return toHexString(value, Math.log256(value) + 1);
1344        }
1345    }
1346
1347    /**
1348     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
1349     */
1350    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
1351        bytes memory buffer = new bytes(2 * length + 2);
1352        buffer[0] = "0";
1353        buffer[1] = "x";
1354        for (uint256 i = 2 * length + 1; i > 1; --i) {
1355            buffer[i] = _SYMBOLS[value & 0xf];
1356            value >>= 4;
1357        }
1358        require(value == 0, "Strings: hex length insufficient");
1359        return string(buffer);
1360    }
1361
1362    /**
1363     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
1364     */
1365    function toHexString(address addr) internal pure returns (string memory) {
1366        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
1367    }
1368}
1369
1370// lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol
1371
1372// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
1373
1374/**
1375 * @dev Implementation of the {IERC165} interface.
1376 *
1377 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
1378 * for the additional interface id that will be supported. For example:
1379 *
1380 * ```solidity
1381 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
1382 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
1383 * }
1384 * ```
1385 *
1386 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
1387 */
1388abstract contract ERC165 is IERC165 {
1389    /**
1390     * @dev See {IERC165-supportsInterface}.
1391     */
1392    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
1393        return interfaceId == type(IERC165).interfaceId;
1394    }
1395}
1396
1397// lib/creator-token-standards/src/utils/AutomaticValidatorTransferApproval.sol
1398
1399/**
1400 * @title AutomaticValidatorTransferApproval
1401 * @author Limit Break, Inc.
1402 * @notice Base contract mix-in that provides boilerplate code giving the contract owner the
1403 *         option to automatically approve a 721-C transfer validator implementation for transfers.
1404 */
1405abstract contract AutomaticValidatorTransferApproval is OwnablePermissions {
1406
1407    /// @dev Emitted when the automatic approval flag is modified by the creator.
1408    event AutomaticApprovalOfTransferValidatorSet(bool autoApproved);
1409
1410    /// @dev If true, the collection's transfer validator is automatically approved to transfer holder's tokens.
1411    bool public autoApproveTransfersFromValidator;
1412
1413    /**
1414     * @notice Sets if the transfer validator is automatically approved as an operator for all token owners.
1415     * 
1416     * @dev    Throws when the caller is not the contract owner.
1417     * 
1418     * @param autoApprove If true, the collection's transfer validator will be automatically approved to
1419     *                    transfer holder's tokens.
1420     */
1421    function setAutomaticApprovalOfTransfersFromValidator(bool autoApprove) external {
1422        _requireCallerIsContractOwner();
1423        autoApproveTransfersFromValidator = autoApprove;
1424        emit AutomaticApprovalOfTransferValidatorSet(autoApprove);
1425    }
1426}
1427
1428// lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol
1429
1430// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
1431
1432/**
1433 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
1434 * @dev See https://eips.ethereum.org/EIPS/eip-721
1435 */
1436interface IERC721Metadata is IERC721 {
1437    /**
1438     * @dev Returns the token collection name.
1439     */
1440    function name() external view returns (string memory);
1441
1442    /**
1443     * @dev Returns the token collection symbol.
1444     */
1445    function symbol() external view returns (string memory);
1446
1447    /**
1448     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
1449     */
1450    function tokenURI(uint256 tokenId) external view returns (string memory);
1451}
1452
1453// lib/creator-token-standards/src/access/OwnableBasic.sol
1454
1455abstract contract OwnableBasic is OwnablePermissions, Ownable {
1456    function _requireCallerIsContractOwner() internal view virtual override {
1457        _checkOwner();
1458    }
1459}
1460
1461// lib/openzeppelin-contracts/contracts/token/common/ERC2981.sol
1462
1463// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)
1464
1465/**
1466 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
1467 *
1468 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
1469 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
1470 *
1471 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
1472 * fee is specified in basis points by default.
1473 *
1474 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
1475 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
1476 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
1477 *
1478 * _Available since v4.5._
1479 */
1480abstract contract ERC2981 is IERC2981, ERC165 {
1481    struct RoyaltyInfo {
1482        address receiver;
1483        uint96 royaltyFraction;
1484    }
1485
1486    RoyaltyInfo private _defaultRoyaltyInfo;
1487    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
1488
1489    /**
1490     * @dev See {IERC165-supportsInterface}.
1491     */
1492    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
1493        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
1494    }
1495
1496    /**
1497     * @inheritdoc IERC2981
1498     */
1499    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
1500        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
1501
1502        if (royalty.receiver == address(0)) {
1503            royalty = _defaultRoyaltyInfo;
1504        }
1505
1506        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
1507
1508        return (royalty.receiver, royaltyAmount);
1509    }
1510
1511    /**
1512     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
1513     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
1514     * override.
1515     */
1516    function _feeDenominator() internal pure virtual returns (uint96) {
1517        return 10000;
1518    }
1519
1520    /**
1521     * @dev Sets the royalty information that all ids in this contract will default to.
1522     *
1523     * Requirements:
1524     *
1525     * - `receiver` cannot be the zero address.
1526     * - `feeNumerator` cannot be greater than the fee denominator.
1527     */
1528    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
1529        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
1530        require(receiver != address(0), "ERC2981: invalid receiver");
1531
1532        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
1533    }
1534
1535    /**
1536     * @dev Removes default royalty information.
1537     */
1538    function _deleteDefaultRoyalty() internal virtual {
1539        delete _defaultRoyaltyInfo;
1540    }
1541
1542    /**
1543     * @dev Sets the royalty information for a specific token id, overriding the global default.
1544     *
1545     * Requirements:
1546     *
1547     * - `receiver` cannot be the zero address.
1548     * - `feeNumerator` cannot be greater than the fee denominator.
1549     */
1550    function _setTokenRoyalty(
1551        uint256 tokenId,
1552        address receiver,
1553        uint96 feeNumerator
1554    ) internal virtual {
1555        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
1556        require(receiver != address(0), "ERC2981: Invalid parameters");
1557
1558        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
1559    }
1560
1561    /**
1562     * @dev Resets royalty information for the token id back to the global default.
1563     */
1564    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
1565        delete _tokenRoyaltyInfo[tokenId];
1566    }
1567}
1568
1569// lib/creator-token-standards/src/programmable-royalties/BasicRoyalties.sol
1570
1571/**
1572 * @title BasicRoyaltiesBase
1573 * @author Limit Break, Inc.
1574 * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties.
1575 */
1576abstract contract BasicRoyaltiesBase is ERC2981 {
1577
1578    event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator);
1579    event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator);
1580
1581    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override {
1582        super._setDefaultRoyalty(receiver, feeNumerator);
1583        emit DefaultRoyaltySet(receiver, feeNumerator);
1584    }
1585
1586    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override {
1587        super._setTokenRoyalty(tokenId, receiver, feeNumerator);
1588        emit TokenRoyaltySet(tokenId, receiver, feeNumerator);
1589    }
1590}
1591
1592/**
1593 * @title BasicRoyalties
1594 * @author Limit Break, Inc.
1595 * @notice Constructable BasicRoyalties Contract implementation.
1596 */
1597abstract contract BasicRoyalties is BasicRoyaltiesBase {
1598    constructor(address receiver, uint96 feeNumerator) {
1599        _setDefaultRoyalty(receiver, feeNumerator);
1600    }
1601}
1602
1603/**
1604 * @title BasicRoyaltiesInitializable
1605 * @author Limit Break, Inc.
1606 * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. 
1607 */
1608abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {}
1609
1610// src/PhaseManager.sol
1611
1612error NoActivePhase();
1613error InvalidTimestamps();
1614error InvalidLimits();
1615error InvalidPhaseType();
1616error NoTwinPhase();
1617error NotWhitelisted();
1618error InvalidPhaseConfiguration();
1619
1620enum PhaseType {
1621    NONE,
1622    TWIN_PHASE1,
1623    TWIN_PHASE2,
1624    ALBARRA_OG_WL,
1625    RILLAZ_HOLDER_WL,
1626    COMMUNITY_WL,
1627    PUBLIC_SALE
1628}
1629
1630contract PhaseManager is OwnableBasic {
1631    struct Phase {
1632        bytes32 merkleRoot;
1633        uint96 price;
1634        uint64 start;
1635        uint64 end;
1636        uint8 maxPerWallet;
1637        uint16 maxSupplyPerPhase;
1638    }
1639
1640    // State variables
1641    mapping(PhaseType => Phase) public phases;
1642
1643    function configurePhase(
1644        PhaseType phaseType,
1645        bytes32 merkleRoot,
1646        uint96 price,
1647        uint64 start,
1648        uint64 end,
1649        uint8 maxPerWallet,
1650        uint16 maxSupplyPerPhase
1651    ) external {
1652        _requireCallerIsContractOwner();
1653        if (phaseType == PhaseType.NONE) revert InvalidPhaseType();
1654        if (end <= start) revert InvalidTimestamps();
1655        if (maxPerWallet == 0) revert InvalidLimits();
1656        if (maxSupplyPerPhase == 0) revert InvalidLimits();
1657
1658        phases[phaseType] = Phase({
1659            merkleRoot: merkleRoot,
1660            price: price,
1661            start: start,
1662            end: end,
1663            maxPerWallet: maxPerWallet,
1664            maxSupplyPerPhase: maxSupplyPerPhase
1665        });
1666    }
1667
1668    function currentPhase() public view returns (Phase memory, PhaseType) {
1669        uint256 currentTimestamp = block.timestamp;
1670        for (
1671            PhaseType i = PhaseType.TWIN_PHASE1;
1672            i <= type(PhaseType).max;
1673            i = PhaseType(uint8(i) + 1)
1674        ) {
1675            if (
1676                currentTimestamp >= phases[i].start &&
1677                currentTimestamp <= phases[i].end
1678            ) {
1679                return (phases[i], i);
1680            }
1681        }
1682        return (phases[PhaseType.NONE], PhaseType.NONE);
1683    }
1684
1685    function isWhitelistedForPhase(
1686        PhaseType phaseType,
1687        address user,
1688        bytes32[] calldata merkleProof
1689    ) public view returns (bool) {
1690        return MerkleProof.verify(
1691            merkleProof,
1692            phases[phaseType].merkleRoot,
1693            keccak256(abi.encodePacked(user))
1694        );
1695    }
1696}
1697
1698// lib/creator-token-standards/src/utils/CreatorTokenBase.sol
1699
1700/**
1701 * @title CreatorTokenBase
1702 * @author Limit Break, Inc.
1703 * @notice CreatorTokenBaseV3 is an abstract contract that provides basic functionality for managing token 
1704 * transfer policies through an implementation of ICreatorTokenTransferValidator/ICreatorTokenTransferValidatorV2/ICreatorTokenTransferValidatorV3. 
1705 * This contract is intended to be used as a base for creator-specific token contracts, enabling customizable transfer 
1706 * restrictions and security policies.
1707 *
1708 * <h4>Features:</h4>
1709 * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul>
1710 * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul>
1711 *
1712 * <h4>Benefits:</h4>
1713 * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul>
1714 * <ul>Allows creators to enforce policies such as account and codehash blacklists, whitelists, and graylists.</ul>
1715 * <ul>Can be easily integrated into other token contracts as a base contract.</ul>
1716 *
1717 * <h4>Intended Usage:</h4>
1718 * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and 
1719 *   security policies.</ul>
1720 * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the 
1721 *   creator token.</ul>
1722 *
1723 * <h4>Compatibility:</h4>
1724 * <ul>Backward and Forward Compatible - V1/V2/V3 Creator Token Base will work with V1/V2/V3 Transfer Validators.</ul>
1725 */
1726abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken {
1727
1728    /// @dev Thrown when setting a transfer validator address that has no deployed code.
1729    error CreatorTokenBase__InvalidTransferValidatorContract();
1730
1731    /// @dev The default transfer validator that will be used if no transfer validator has been set by the creator.
1732    address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x721C00182a990771244d7A71B9FA2ea789A3b433);
1733
1734    /// @dev Used to determine if the default transfer validator is applied.
1735    /// @dev Set to true when the creator sets a transfer validator address.
1736    bool private isValidatorInitialized;
1737    /// @dev Address of the transfer validator to apply to transactions.
1738    address private transferValidator;
1739
1740    /**
1741     * @notice Sets the transfer validator for the token contract.
1742     *
1743     * @dev    Throws when provided validator contract is not the zero address and does not have code.
1744     * @dev    Throws when the caller is not the contract owner.
1745     *
1746     * @dev    <h4>Postconditions:</h4>
1747     *         1. The transferValidator address is updated.
1748     *         2. The `TransferValidatorUpdated` event is emitted.
1749     *
1750     * @param transferValidator_ The address of the transfer validator contract.
1751     */
1752    function setTransferValidator(address transferValidator_) public {
1753        _requireCallerIsContractOwner();
1754
1755        bool isValidTransferValidator = transferValidator_.code.length > 0;
1756
1757        if(transferValidator_ != address(0) && !isValidTransferValidator) {
1758            revert CreatorTokenBase__InvalidTransferValidatorContract();
1759        }
1760
1761        emit TransferValidatorUpdated(address(getTransferValidator()), transferValidator_);
1762
1763        isValidatorInitialized = true;
1764        transferValidator = transferValidator_;
1765    }
1766
1767    /**
1768     * @notice Returns the transfer validator contract address for this token contract.
1769     */
1770    function getTransferValidator() public view override returns (address validator) {
1771        validator = transferValidator;
1772
1773        if (validator == address(0)) {
1774            if (!isValidatorInitialized) {
1775                validator = DEFAULT_TRANSFER_VALIDATOR;
1776            }
1777        }
1778    }
1779
1780    /**
1781     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
1782     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
1783     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
1784     *
1785     * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the
1786     *      transfer validator is expected to pre-validate the transfer.
1787     *
1788     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
1789     *      set to a non-zero address.
1790     *
1791     * @param caller  The address of the caller.
1792     * @param from    The address of the sender.
1793     * @param to      The address of the receiver.
1794     * @param tokenId The token id being transferred.
1795     */
1796    function _preValidateTransfer(
1797        address caller, 
1798        address from, 
1799        address to, 
1800        uint256 tokenId, 
1801        uint256 /*value*/) internal virtual override {
1802        address validator = getTransferValidator();
1803
1804        if (validator != address(0)) {
1805            if (msg.sender == validator) {
1806                return;
1807            }
1808
1809            ITransferValidator(validator).validateTransfer(caller, from, to, tokenId);
1810        }
1811    }
1812
1813    /**
1814     * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy.
1815     *      Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent
1816     *      and calling _validateBeforeTransfer so that checks can be properly applied during token transfers.
1817     *
1818     * @dev Be aware that if the msg.sender is the transfer validator, the transfer is automatically permitted, as the
1819     *      transfer validator is expected to pre-validate the transfer.
1820     * 
1821     * @dev Used for ERC20 and ERC1155 token transfers which have an amount value to validate in the transfer validator.
1822     * @dev The `tokenId` for ERC20 tokens should be set to `0`.
1823     *
1824     * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is
1825     *      set to a non-zero address.
1826     *
1827     * @param caller  The address of the caller.
1828     * @param from    The address of the sender.
1829     * @param to      The address of the receiver.
1830     * @param tokenId The token id being transferred.
1831     * @param amount  The amount of token being transferred.
1832     */
1833    function _preValidateTransfer(
1834        address caller, 
1835        address from, 
1836        address to, 
1837        uint256 tokenId, 
1838        uint256 amount,
1839        uint256 /*value*/) internal virtual override {
1840        address validator = getTransferValidator();
1841
1842        if (validator != address(0)) {
1843            if (msg.sender == validator) {
1844                return;
1845            }
1846
1847            ITransferValidator(validator).validateTransfer(caller, from, to, tokenId, amount);
1848        }
1849    }
1850}
1851
1852// lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol
1853
1854// OpenZeppelin Contracts (last updated v4.8.2) (token/ERC721/ERC721.sol)
1855
1856/**
1857 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
1858 * the Metadata extension, but not including the Enumerable extension, which is available separately as
1859 * {ERC721Enumerable}.
1860 */
1861contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
1862    using Address for address;
1863    using Strings for uint256;
1864
1865    // Token name
1866    string private _name;
1867
1868    // Token symbol
1869    string private _symbol;
1870
1871    // Mapping from token ID to owner address
1872    mapping(uint256 => address) private _owners;
1873
1874    // Mapping owner address to token count
1875    mapping(address => uint256) private _balances;
1876
1877    // Mapping from token ID to approved address
1878    mapping(uint256 => address) private _tokenApprovals;
1879
1880    // Mapping from owner to operator approvals
1881    mapping(address => mapping(address => bool)) private _operatorApprovals;
1882
1883    /**
1884     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
1885     */
1886    constructor(string memory name_, string memory symbol_) {
1887        _name = name_;
1888        _symbol = symbol_;
1889    }
1890
1891    /**
1892     * @dev See {IERC165-supportsInterface}.
1893     */
1894    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
1895        return
1896            interfaceId == type(IERC721).interfaceId ||
1897            interfaceId == type(IERC721Metadata).interfaceId ||
1898            super.supportsInterface(interfaceId);
1899    }
1900
1901    /**
1902     * @dev See {IERC721-balanceOf}.
1903     */
1904    function balanceOf(address owner) public view virtual override returns (uint256) {
1905        require(owner != address(0), "ERC721: address zero is not a valid owner");
1906        return _balances[owner];
1907    }
1908
1909    /**
1910     * @dev See {IERC721-ownerOf}.
1911     */
1912    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
1913        address owner = _ownerOf(tokenId);
1914        require(owner != address(0), "ERC721: invalid token ID");
1915        return owner;
1916    }
1917
1918    /**
1919     * @dev See {IERC721Metadata-name}.
1920     */
1921    function name() public view virtual override returns (string memory) {
1922        return _name;
1923    }
1924
1925    /**
1926     * @dev See {IERC721Metadata-symbol}.
1927     */
1928    function symbol() public view virtual override returns (string memory) {
1929        return _symbol;
1930    }
1931
1932    /**
1933     * @dev See {IERC721Metadata-tokenURI}.
1934     */
1935    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
1936        _requireMinted(tokenId);
1937
1938        string memory baseURI = _baseURI();
1939        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
1940    }
1941
1942    /**
1943     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
1944     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
1945     * by default, can be overridden in child contracts.
1946     */
1947    function _baseURI() internal view virtual returns (string memory) {
1948        return "";
1949    }
1950
1951    /**
1952     * @dev See {IERC721-approve}.
1953     */
1954    function approve(address to, uint256 tokenId) public virtual override {
1955        address owner = ERC721.ownerOf(tokenId);
1956        require(to != owner, "ERC721: approval to current owner");
1957
1958        require(
1959            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
1960            "ERC721: approve caller is not token owner or approved for all"
1961        );
1962
1963        _approve(to, tokenId);
1964    }
1965
1966    /**
1967     * @dev See {IERC721-getApproved}.
1968     */
1969    function getApproved(uint256 tokenId) public view virtual override returns (address) {
1970        _requireMinted(tokenId);
1971
1972        return _tokenApprovals[tokenId];
1973    }
1974
1975    /**
1976     * @dev See {IERC721-setApprovalForAll}.
1977     */
1978    function setApprovalForAll(address operator, bool approved) public virtual override {
1979        _setApprovalForAll(_msgSender(), operator, approved);
1980    }
1981
1982    /**
1983     * @dev See {IERC721-isApprovedForAll}.
1984     */
1985    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
1986        return _operatorApprovals[owner][operator];
1987    }
1988
1989    /**
1990     * @dev See {IERC721-transferFrom}.
1991     */
1992    function transferFrom(
1993        address from,
1994        address to,
1995        uint256 tokenId
1996    ) public virtual override {
1997        //solhint-disable-next-line max-line-length
1998        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
1999
2000        _transfer(from, to, tokenId);
2001    }
2002
2003    /**
2004     * @dev See {IERC721-safeTransferFrom}.
2005     */
2006    function safeTransferFrom(
2007        address from,
2008        address to,
2009        uint256 tokenId
2010    ) public virtual override {
2011        safeTransferFrom(from, to, tokenId, "");
2012    }
2013
2014    /**
2015     * @dev See {IERC721-safeTransferFrom}.
2016     */
2017    function safeTransferFrom(
2018        address from,
2019        address to,
2020        uint256 tokenId,
2021        bytes memory data
2022    ) public virtual override {
2023        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
2024        _safeTransfer(from, to, tokenId, data);
2025    }
2026
2027    /**
2028     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
2029     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
2030     *
2031     * `data` is additional data, it has no specified format and it is sent in call to `to`.
2032     *
2033     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
2034     * implement alternative mechanisms to perform token transfer, such as signature-based.
2035     *
2036     * Requirements:
2037     *
2038     * - `from` cannot be the zero address.
2039     * - `to` cannot be the zero address.
2040     * - `tokenId` token must exist and be owned by `from`.
2041     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
2042     *
2043     * Emits a {Transfer} event.
2044     */
2045    function _safeTransfer(
2046        address from,
2047        address to,
2048        uint256 tokenId,
2049        bytes memory data
2050    ) internal virtual {
2051        _transfer(from, to, tokenId);
2052        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
2053    }
2054
2055    /**
2056     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
2057     */
2058    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
2059        return _owners[tokenId];
2060    }
2061
2062    /**
2063     * @dev Returns whether `tokenId` exists.
2064     *
2065     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
2066     *
2067     * Tokens start existing when they are minted (`_mint`),
2068     * and stop existing when they are burned (`_burn`).
2069     */
2070    function _exists(uint256 tokenId) internal view virtual returns (bool) {
2071        return _ownerOf(tokenId) != address(0);
2072    }
2073
2074    /**
2075     * @dev Returns whether `spender` is allowed to manage `tokenId`.
2076     *
2077     * Requirements:
2078     *
2079     * - `tokenId` must exist.
2080     */
2081    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
2082        address owner = ERC721.ownerOf(tokenId);
2083        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
2084    }
2085
2086    /**
2087     * @dev Safely mints `tokenId` and transfers it to `to`.
2088     *
2089     * Requirements:
2090     *
2091     * - `tokenId` must not exist.
2092     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
2093     *
2094     * Emits a {Transfer} event.
2095     */
2096    function _safeMint(address to, uint256 tokenId) internal virtual {
2097        _safeMint(to, tokenId, "");
2098    }
2099
2100    /**
2101     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
2102     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
2103     */
2104    function _safeMint(
2105        address to,
2106        uint256 tokenId,
2107        bytes memory data
2108    ) internal virtual {
2109        _mint(to, tokenId);
2110        require(
2111            _checkOnERC721Received(address(0), to, tokenId, data),
2112            "ERC721: transfer to non ERC721Receiver implementer"
2113        );
2114    }
2115
2116    /**
2117     * @dev Mints `tokenId` and transfers it to `to`.
2118     *
2119     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
2120     *
2121     * Requirements:
2122     *
2123     * - `tokenId` must not exist.
2124     * - `to` cannot be the zero address.
2125     *
2126     * Emits a {Transfer} event.
2127     */
2128    function _mint(address to, uint256 tokenId) internal virtual {
2129        require(to != address(0), "ERC721: mint to the zero address");
2130        require(!_exists(tokenId), "ERC721: token already minted");
2131
2132        _beforeTokenTransfer(address(0), to, tokenId, 1);
2133
2134        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
2135        require(!_exists(tokenId), "ERC721: token already minted");
2136
2137        unchecked {
2138            // Will not overflow unless all 2**256 token ids are minted to the same owner.
2139            // Given that tokens are minted one by one, it is impossible in practice that
2140            // this ever happens. Might change if we allow batch minting.
2141            // The ERC fails to describe this case.
2142            _balances[to] += 1;
2143        }
2144
2145        _owners[tokenId] = to;
2146
2147        emit Transfer(address(0), to, tokenId);
2148
2149        _afterTokenTransfer(address(0), to, tokenId, 1);
2150    }
2151
2152    /**
2153     * @dev Destroys `tokenId`.
2154     * The approval is cleared when the token is burned.
2155     * This is an internal function that does not check if the sender is authorized to operate on the token.
2156     *
2157     * Requirements:
2158     *
2159     * - `tokenId` must exist.
2160     *
2161     * Emits a {Transfer} event.
2162     */
2163    function _burn(uint256 tokenId) internal virtual {
2164        address owner = ERC721.ownerOf(tokenId);
2165
2166        _beforeTokenTransfer(owner, address(0), tokenId, 1);
2167
2168        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
2169        owner = ERC721.ownerOf(tokenId);
2170
2171        // Clear approvals
2172        delete _tokenApprovals[tokenId];
2173
2174        unchecked {
2175            // Cannot overflow, as that would require more tokens to be burned/transferred
2176            // out than the owner initially received through minting and transferring in.
2177            _balances[owner] -= 1;
2178        }
2179        delete _owners[tokenId];
2180
2181        emit Transfer(owner, address(0), tokenId);
2182
2183        _afterTokenTransfer(owner, address(0), tokenId, 1);
2184    }
2185
2186    /**
2187     * @dev Transfers `tokenId` from `from` to `to`.
2188     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
2189     *
2190     * Requirements:
2191     *
2192     * - `to` cannot be the zero address.
2193     * - `tokenId` token must be owned by `from`.
2194     *
2195     * Emits a {Transfer} event.
2196     */
2197    function _transfer(
2198        address from,
2199        address to,
2200        uint256 tokenId
2201    ) internal virtual {
2202        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
2203        require(to != address(0), "ERC721: transfer to the zero address");
2204
2205        _beforeTokenTransfer(from, to, tokenId, 1);
2206
2207        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
2208        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
2209
2210        // Clear approvals from the previous owner
2211        delete _tokenApprovals[tokenId];
2212
2213        unchecked {
2214            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
2215            // `from`'s balance is the number of token held, which is at least one before the current
2216            // transfer.
2217            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
2218            // all 2**256 token ids to be minted, which in practice is impossible.
2219            _balances[from] -= 1;
2220            _balances[to] += 1;
2221        }
2222        _owners[tokenId] = to;
2223
2224        emit Transfer(from, to, tokenId);
2225
2226        _afterTokenTransfer(from, to, tokenId, 1);
2227    }
2228
2229    /**
2230     * @dev Approve `to` to operate on `tokenId`
2231     *
2232     * Emits an {Approval} event.
2233     */
2234    function _approve(address to, uint256 tokenId) internal virtual {
2235        _tokenApprovals[tokenId] = to;
2236        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
2237    }
2238
2239    /**
2240     * @dev Approve `operator` to operate on all of `owner` tokens
2241     *
2242     * Emits an {ApprovalForAll} event.
2243     */
2244    function _setApprovalForAll(
2245        address owner,
2246        address operator,
2247        bool approved
2248    ) internal virtual {
2249        require(owner != operator, "ERC721: approve to caller");
2250        _operatorApprovals[owner][operator] = approved;
2251        emit ApprovalForAll(owner, operator, approved);
2252    }
2253
2254    /**
2255     * @dev Reverts if the `tokenId` has not been minted yet.
2256     */
2257    function _requireMinted(uint256 tokenId) internal view virtual {
2258        require(_exists(tokenId), "ERC721: invalid token ID");
2259    }
2260
2261    /**
2262     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
2263     * The call is not executed if the target address is not a contract.
2264     *
2265     * @param from address representing the previous owner of the given token ID
2266     * @param to target address that will receive the tokens
2267     * @param tokenId uint256 ID of the token to be transferred
2268     * @param data bytes optional data to send along with the call
2269     * @return bool whether the call correctly returned the expected magic value
2270     */
2271    function _checkOnERC721Received(
2272        address from,
2273        address to,
2274        uint256 tokenId,
2275        bytes memory data
2276    ) private returns (bool) {
2277        if (to.isContract()) {
2278            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
2279                return retval == IERC721Receiver.onERC721Received.selector;
2280            } catch (bytes memory reason) {
2281                if (reason.length == 0) {
2282                    revert("ERC721: transfer to non ERC721Receiver implementer");
2283                } else {
2284                    /// @solidity memory-safe-assembly
2285                    assembly {
2286                        revert(add(32, reason), mload(reason))
2287                    }
2288                }
2289            }
2290        } else {
2291            return true;
2292        }
2293    }
2294
2295    /**
2296     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
2297     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
2298     *
2299     * Calling conditions:
2300     *
2301     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
2302     * - When `from` is zero, the tokens will be minted for `to`.
2303     * - When `to` is zero, ``from``'s tokens will be burned.
2304     * - `from` and `to` are never both zero.
2305     * - `batchSize` is non-zero.
2306     *
2307     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
2308     */
2309    function _beforeTokenTransfer(
2310        address from,
2311        address to,
2312        uint256 firstTokenId,
2313        uint256 batchSize
2314    ) internal virtual {}
2315
2316    /**
2317     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
2318     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
2319     *
2320     * Calling conditions:
2321     *
2322     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
2323     * - When `from` is zero, the tokens were minted for `to`.
2324     * - When `to` is zero, ``from``'s tokens were burned.
2325     * - `from` and `to` are never both zero.
2326     * - `batchSize` is non-zero.
2327     *
2328     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
2329     */
2330    function _afterTokenTransfer(
2331        address from,
2332        address to,
2333        uint256 firstTokenId,
2334        uint256 batchSize
2335    ) internal virtual {}
2336
2337    /**
2338     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
2339     *
2340     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
2341     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
2342     * that `ownerOf(tokenId)` is `a`.
2343     */
2344    // solhint-disable-next-line func-name-mixedcase
2345    function __unsafe_increaseBalance(address account, uint256 amount) internal {
2346        _balances[account] += amount;
2347    }
2348}
2349
2350// lib/creator-token-standards/src/token/erc721/ERC721OpenZeppelin.sol
2351
2352abstract contract ERC721OpenZeppelinBase is ERC721 {
2353
2354    // Token name
2355    string internal _contractName;
2356
2357    // Token symbol
2358    string internal _contractSymbol;
2359
2360    function name() public view virtual override returns (string memory) {
2361        return _contractName;
2362    }
2363
2364    function symbol() public view virtual override returns (string memory) {
2365        return _contractSymbol;
2366    }
2367
2368    function _setNameAndSymbol(string memory name_, string memory symbol_) internal {
2369        _contractName = name_;
2370        _contractSymbol = symbol_;
2371    }
2372}
2373
2374abstract contract ERC721OpenZeppelin is ERC721OpenZeppelinBase {
2375    constructor(string memory name_, string memory symbol_) ERC721("", "") {
2376        _setNameAndSymbol(name_, symbol_);
2377    }
2378}
2379
2380abstract contract ERC721OpenZeppelinInitializable is OwnablePermissions, ERC721OpenZeppelinBase {
2381
2382    error ERC721OpenZeppelinInitializable__AlreadyInitializedERC721();
2383
2384    /// @notice Specifies whether or not the contract is initialized
2385    bool private _erc721Initialized;
2386
2387    /// @dev Initializes parameters of ERC721 tokens.
2388    /// These cannot be set in the constructor because this contract is optionally compatible with EIP-1167.
2389    function initializeERC721(string memory name_, string memory symbol_) public {
2390        _requireCallerIsContractOwner();
2391
2392        if(_erc721Initialized) {
2393            revert ERC721OpenZeppelinInitializable__AlreadyInitializedERC721();
2394        }
2395
2396        _erc721Initialized = true;
2397
2398        _setNameAndSymbol(name_, symbol_);
2399    }
2400}
2401
2402// lib/creator-token-standards/src/erc721c/ERC721C.sol
2403
2404/**
2405 * @title ERC721C
2406 * @author Limit Break, Inc.
2407 * @notice Extends OpenZeppelin's ERC721 implementation with Creator Token functionality, which
2408 *         allows the contract owner to update the transfer validation logic by managing a security policy in
2409 *         an external transfer validation security policy registry.  See {CreatorTokenTransferValidator}.
2410 */
2411abstract contract ERC721C is ERC721OpenZeppelin, CreatorTokenBase, AutomaticValidatorTransferApproval {
2412
2413    /**
2414     * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved
2415     *         for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers.
2416     */
2417    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) {
2418        isApproved = super.isApprovedForAll(owner, operator);
2419
2420        if (!isApproved) {
2421            if (autoApproveTransfersFromValidator) {
2422                isApproved = operator == address(getTransferValidator());
2423            }
2424        }
2425    }
2426
2427    /**
2428     * @notice Indicates whether the contract implements the specified interface.
2429     * @dev Overrides supportsInterface in ERC165.
2430     * @param interfaceId The interface id
2431     * @return true if the contract implements the specified interface, false otherwise
2432     */
2433    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
2434        return 
2435        interfaceId == type(ICreatorToken).interfaceId || 
2436        interfaceId == type(ICreatorTokenLegacy).interfaceId || 
2437        super.supportsInterface(interfaceId);
2438    }
2439
2440    /**
2441     * @notice Returns the function selector for the transfer validator's validation function to be called 
2442     * @notice for transaction simulation. 
2443     */
2444    function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
2445        functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)"));
2446        isViewFunction = true;
2447    }
2448
2449    /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic
2450    function _beforeTokenTransfer(
2451        address from,
2452        address to,
2453        uint256 firstTokenId,
2454        uint256 batchSize) internal virtual override {
2455        for (uint256 i = 0; i < batchSize;) {
2456            _validateBeforeTransfer(from, to, firstTokenId + i);
2457            unchecked {
2458                ++i;
2459            }
2460        }
2461    }
2462
2463    /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic
2464    function _afterTokenTransfer(
2465        address from,
2466        address to,
2467        uint256 firstTokenId,
2468        uint256 batchSize) internal virtual override {
2469        for (uint256 i = 0; i < batchSize;) {
2470            _validateAfterTransfer(from, to, firstTokenId + i);
2471            unchecked {
2472                ++i;
2473            }
2474        }
2475    }
2476}
2477
2478/**
2479 * @title ERC721CInitializable
2480 * @author Limit Break, Inc.
2481 * @notice Initializable implementation of ERC721C to allow for EIP-1167 proxy clones.
2482 */
2483abstract contract ERC721CInitializable is ERC721OpenZeppelinInitializable, CreatorTokenBase, AutomaticValidatorTransferApproval {
2484
2485    /**
2486     * @notice Overrides behavior of isApprovedFor all such that if an operator is not explicitly approved
2487     *         for all, the contract owner can optionally auto-approve the 721-C transfer validator for transfers.
2488     */
2489    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) {
2490        isApproved = super.isApprovedForAll(owner, operator);
2491
2492        if (!isApproved) {
2493            if (autoApproveTransfersFromValidator) {
2494                isApproved = operator == address(getTransferValidator());
2495            }
2496        }
2497    }
2498
2499    /**
2500     * @notice Indicates whether the contract implements the specified interface.
2501     * @dev Overrides supportsInterface in ERC165.
2502     * @param interfaceId The interface id
2503     * @return true if the contract implements the specified interface, false otherwise
2504     */
2505    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
2506        return 
2507        interfaceId == type(ICreatorToken).interfaceId || 
2508        interfaceId == type(ICreatorTokenLegacy).interfaceId || 
2509        super.supportsInterface(interfaceId);
2510    }
2511
2512    /**
2513     * @notice Returns the function selector for the transfer validator's validation function to be called 
2514     * @notice for transaction simulation. 
2515     */
2516    function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
2517        functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256)"));
2518        isViewFunction = true;
2519    }
2520
2521    /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic
2522    function _beforeTokenTransfer(
2523        address from,
2524        address to,
2525        uint256 firstTokenId,
2526        uint256 batchSize) internal virtual override {
2527        for (uint256 i = 0; i < batchSize;) {
2528            _validateBeforeTransfer(from, to, firstTokenId + i);
2529            unchecked {
2530                ++i;
2531            }
2532        }
2533    }
2534
2535    /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic
2536    function _afterTokenTransfer(
2537        address from,
2538        address to,
2539        uint256 firstTokenId,
2540        uint256 batchSize) internal virtual override {
2541        for (uint256 i = 0; i < batchSize;) {
2542            _validateAfterTransfer(from, to, firstTokenId + i);
2543            unchecked {
2544                ++i;
2545            }
2546        }
2547    }
2548}
2549
2550// src/Depix.sol
2551
2552error IncorrectValue();
2553error AlreadyMinted();
2554error NotOwner();
2555error TransferFailed();
2556error TwinSupplyReached();
2557error MaxSupplyReached();
2558error MaxPerWalletExceeded();
2559error InvalidAmount();
2560error InvalidAddress();
2561error InvalidURI();
2562error InvalidPhase();
2563error InvalidProof();
2564
2565abstract contract RILLAZC {
2566    function ownerOf(uint256 tokenId) public view virtual returns (address);
2567}
2568
2569contract Depix is ERC721C, BasicRoyalties, OwnableBasic {
2570    RILLAZC immutable RILLAZ;
2571    PhaseManager immutable phaseManager;
2572    address immutable MINT_FUNDS_RECEIVER;
2573    
2574    uint256 constant MAX_SUPPLY = 10000;
2575    uint256 constant TWIN_MAX_SUPPLY = 3500;
2576    
2577    uint256 public currentSupply;
2578    uint256 public tokenCounter = 10000;
2579    string private baseTokenURI;
2580    mapping(uint256 => bool) public hasTwinMap;
2581    
2582    mapping(PhaseType => uint256) public mintedPerPhase;
2583    mapping(address => mapping(PhaseType => uint256)) public userMintedPerPhase;
2584
2585    constructor(
2586        address royaltyReceiver_,
2587        uint96 royaltyFeeNumerator_,
2588        string memory name_,
2589        string memory symbol_,
2590        RILLAZC rillaz_,
2591        PhaseManager phaseManager_
2592    )
2593        ERC721OpenZeppelin(name_, symbol_)
2594        BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_)
2595        OwnableBasic()
2596    {
2597        if (royaltyReceiver_ == address(0)) revert InvalidAddress();
2598        if (address(rillaz_) == address(0)) revert InvalidAddress();
2599        if (address(phaseManager_) == address(0)) revert InvalidAddress();
2600        
2601        RILLAZ = rillaz_;
2602        phaseManager = phaseManager_;
2603        MINT_FUNDS_RECEIVER = royaltyReceiver_;
2604    }
2605
2606    function mintTwin(
2607        uint256[] calldata tokenIds,
2608        bytes32[] calldata merkleProof
2609    ) external payable {
2610        uint256 len = tokenIds.length;
2611        if (len == 0) revert InvalidAmount();
2612        
2613        (PhaseManager.Phase memory phase, PhaseType phaseType) = phaseManager.currentPhase();
2614        if (phaseType == PhaseType.NONE || phaseType > PhaseType.TWIN_PHASE2) 
2615            revert NoTwinPhase();
2616
2617        if (userMintedPerPhase[msg.sender][phaseType] + len > phase.maxPerWallet) 
2618            revert MaxPerWalletExceeded();
2619        if (twinSupply() + len > TWIN_MAX_SUPPLY) 
2620            revert TwinSupplyReached();
2621       
2622
2623        bool isWhitelisted = phaseManager.isWhitelistedForPhase(phaseType, msg.sender, merkleProof);
2624        if (isWhitelisted && msg.value != 0) 
2625            revert IncorrectValue();
2626
2627        userMintedPerPhase[msg.sender][phaseType] += len;
2628        mintedPerPhase[phaseType] += len;
2629        currentSupply += len;
2630        
2631        for (uint256 i = 0; i < len; i++) {
2632            if (RILLAZ.ownerOf(tokenIds[i]) != msg.sender) revert NotOwner();
2633            if (hasTwinMap[tokenIds[i]]) revert AlreadyMinted();
2634            hasTwinMap[tokenIds[i]] = true;
2635            _mint(msg.sender, tokenIds[i]);
2636        }
2637        if (!isWhitelisted) {
2638            uint256 mintCost = phase.price * len;
2639            if (msg.value != mintCost) revert IncorrectValue();
2640            (bool success, ) = MINT_FUNDS_RECEIVER.call{value: msg.value}("");
2641            if (!success) revert TransferFailed();
2642        }
2643    }
2644
2645    function publicMint(
2646        uint256 amount,
2647        bytes32[] calldata merkleProof
2648    ) external payable {
2649        if (amount == 0) revert InvalidAmount();
2650        (PhaseManager.Phase memory phase, PhaseType phaseType) = phaseManager.currentPhase();
2651        if (phaseType <= PhaseType.TWIN_PHASE2) revert InvalidPhase();
2652        
2653        if (userMintedPerPhase[msg.sender][phaseType] + amount > phase.maxPerWallet) 
2654            revert MaxPerWalletExceeded();
2655        if (currentSupply + amount > MAX_SUPPLY) 
2656            revert MaxSupplyReached();
2657        if (mintedPerPhase[phaseType] + amount > phase.maxSupplyPerPhase)
2658            revert MaxSupplyReached();
2659
2660        if (phaseType < PhaseType.PUBLIC_SALE) {
2661            if (merkleProof.length == 0) revert InvalidProof();
2662            if (!phaseManager.isWhitelistedForPhase(phaseType, msg.sender, merkleProof)) 
2663                revert NotWhitelisted();
2664        }
2665
2666        if (phase.price > 0) {
2667            uint256 mintCost = phase.price * amount;
2668            if (msg.value != mintCost) revert IncorrectValue();
2669        } else {
2670            if (msg.value != 0) revert IncorrectValue();
2671        }
2672
2673        // Update state
2674        userMintedPerPhase[msg.sender][phaseType] += amount;
2675        mintedPerPhase[phaseType] += amount;
2676        currentSupply += amount;
2677
2678        if (phase.price > 0) {
2679            (bool success, ) = MINT_FUNDS_RECEIVER.call{value: msg.value}("");
2680            if (!success) revert TransferFailed();
2681        }
2682
2683        for (uint256 i = 0; i < amount; i++) {
2684            _mint(msg.sender, tokenCounter);
2685            tokenCounter++;
2686        }
2687    }
2688
2689    function setDefaultRoyalty(address receiver, uint96 feeNumerator) public {
2690        _requireCallerIsContractOwner();
2691        _setDefaultRoyalty(receiver, feeNumerator);
2692    }
2693
2694    function setTokenRoyalty(
2695        uint256 tokenId,
2696        address receiver,
2697        uint96 feeNumerator
2698    ) public {
2699        _requireCallerIsContractOwner();
2700        _setTokenRoyalty(tokenId, receiver, feeNumerator);
2701    }
2702
2703    function setBaseURI(string calldata baseURI) external {
2704        _requireCallerIsContractOwner();
2705        if (bytes(baseURI).length == 0) revert InvalidURI();
2706        baseTokenURI = baseURI;
2707    }
2708
2709    function twinSupply() public view returns (uint256) {
2710        return mintedPerPhase[PhaseType.TWIN_PHASE1] + mintedPerPhase[PhaseType.TWIN_PHASE2];
2711    }
2712
2713    function supportsInterface(
2714        bytes4 interfaceId
2715    ) public view virtual override(ERC721C, ERC2981) returns (bool) {
2716        return super.supportsInterface(interfaceId);
2717    }
2718
2719    function _baseURI() internal view override returns (string memory) {
2720        return baseTokenURI;
2721    }
2722
2723    function getMintedPerPhase(PhaseType phaseType) external view returns (uint256) {
2724        return mintedPerPhase[phaseType];
2725    }
2726
2727    function totalSupply() external view returns (uint256) {
2728        return currentSupply;
2729    }
2730
2731    function getUserMintedPerPhase(address user, PhaseType phaseType) external view returns (uint256) {
2732        return userMintedPerPhase[user][phaseType];
2733    }
2734}
How it works
  • Verified source only.