|
| 1 | +// SPDX-License-Identifier: Apache-2.0 |
| 2 | +pragma solidity ^0.8.0; |
| 3 | + |
| 4 | +/// @author thirdweb |
| 5 | + |
| 6 | +import "../../extension/interface/ILazyMintWithTier.sol"; |
| 7 | +import "./BatchMintMetadata_V1.sol"; |
| 8 | + |
| 9 | +/** |
| 10 | + * The `LazyMint` is a contract extension for any base NFT contract. It lets you 'lazy mint' any number of NFTs |
| 11 | + * at once. Here, 'lazy mint' means defining the metadata for particular tokenIds of your NFT contract, without actually |
| 12 | + * minting a non-zero balance of NFTs of those tokenIds. |
| 13 | + */ |
| 14 | + |
| 15 | +abstract contract LazyMintWithTier_V1 is ILazyMintWithTier, BatchMintMetadata_V1 { |
| 16 | + struct TokenRange { |
| 17 | + uint256 startIdInclusive; |
| 18 | + uint256 endIdNonInclusive; |
| 19 | + } |
| 20 | + |
| 21 | + struct TierMetadata { |
| 22 | + string tier; |
| 23 | + TokenRange[] ranges; |
| 24 | + string[] baseURIs; |
| 25 | + } |
| 26 | + |
| 27 | + /// @notice The tokenId assigned to the next new NFT to be lazy minted. |
| 28 | + uint256 internal nextTokenIdToLazyMint; |
| 29 | + |
| 30 | + /// @notice Mapping from a tier -> the token IDs grouped under that tier. |
| 31 | + mapping(string => TokenRange[]) internal tokensInTier; |
| 32 | + |
| 33 | + /// @notice A list of tiers used in this contract. |
| 34 | + string[] private tiers; |
| 35 | + |
| 36 | + /** |
| 37 | + * @notice Lets an authorized address lazy mint a given amount of NFTs. |
| 38 | + * |
| 39 | + * @param _amount The number of NFTs to lazy mint. |
| 40 | + * @param _baseURIForTokens The base URI for the 'n' number of NFTs being lazy minted, where the metadata for each |
| 41 | + * of those NFTs is `${baseURIForTokens}/${tokenId}`. |
| 42 | + * @param _data Additional bytes data to be used at the discretion of the consumer of the contract. |
| 43 | + * @return batchId A unique integer identifier for the batch of NFTs lazy minted together. |
| 44 | + */ |
| 45 | + function lazyMint( |
| 46 | + uint256 _amount, |
| 47 | + string calldata _baseURIForTokens, |
| 48 | + string calldata _tier, |
| 49 | + bytes calldata _data |
| 50 | + ) public virtual override returns (uint256 batchId) { |
| 51 | + if (!_canLazyMint()) { |
| 52 | + revert("Not authorized"); |
| 53 | + } |
| 54 | + |
| 55 | + if (_amount == 0) { |
| 56 | + revert("0 amt"); |
| 57 | + } |
| 58 | + |
| 59 | + uint256 startId = nextTokenIdToLazyMint; |
| 60 | + |
| 61 | + (nextTokenIdToLazyMint, batchId) = _batchMintMetadata(startId, _amount, _baseURIForTokens); |
| 62 | + |
| 63 | + // Handle tier info. |
| 64 | + if (!(tokensInTier[_tier].length > 0)) { |
| 65 | + tiers.push(_tier); |
| 66 | + } |
| 67 | + tokensInTier[_tier].push(TokenRange(startId, batchId)); |
| 68 | + |
| 69 | + emit TokensLazyMinted(_tier, startId, startId + _amount - 1, _baseURIForTokens, _data); |
| 70 | + |
| 71 | + return batchId; |
| 72 | + } |
| 73 | + |
| 74 | + /// @notice Returns all metadata lazy minted for the given tier. |
| 75 | + function _getMetadataInTier(string memory _tier) |
| 76 | + private |
| 77 | + view |
| 78 | + returns (TokenRange[] memory tokens, string[] memory baseURIs) |
| 79 | + { |
| 80 | + tokens = tokensInTier[_tier]; |
| 81 | + |
| 82 | + uint256 len = tokens.length; |
| 83 | + baseURIs = new string[](len); |
| 84 | + |
| 85 | + for (uint256 i = 0; i < len; i += 1) { |
| 86 | + baseURIs[i] = _getBaseURI(tokens[i].startIdInclusive); |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + /// @notice Returns all metadata for all tiers created on the contract. |
| 91 | + function getMetadataForAllTiers() external view returns (TierMetadata[] memory metadataForAllTiers) { |
| 92 | + string[] memory allTiers = tiers; |
| 93 | + uint256 len = allTiers.length; |
| 94 | + |
| 95 | + metadataForAllTiers = new TierMetadata[](len); |
| 96 | + |
| 97 | + for (uint256 i = 0; i < len; i += 1) { |
| 98 | + (TokenRange[] memory tokens, string[] memory baseURIs) = _getMetadataInTier(allTiers[i]); |
| 99 | + metadataForAllTiers[i] = TierMetadata(allTiers[i], tokens, baseURIs); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | + * @notice Returns whether any metadata is lazy minted for the given tier. |
| 105 | + * |
| 106 | + * @param _tier We check whether this given tier is empty. |
| 107 | + */ |
| 108 | + function isTierEmpty(string memory _tier) internal view returns (bool) { |
| 109 | + return tokensInTier[_tier].length == 0; |
| 110 | + } |
| 111 | + |
| 112 | + /// @dev Returns whether lazy minting can be performed in the given execution context. |
| 113 | + function _canLazyMint() internal view virtual returns (bool); |
| 114 | +} |
0 commit comments