1
1
// SPDX-License-Identifier: Apache-2.0
2
2
pragma solidity ^ 0.8.0 ;
3
3
4
- import "./ERC1155Base.sol " ;
4
+ import { ERC1155 } from "../eip/ERC1155.sol " ;
5
+
6
+ import "../extension/ContractMetadata.sol " ;
7
+ import "../extension/Multicall.sol " ;
8
+ import "../extension/Ownable.sol " ;
9
+ import "../extension/Royalty.sol " ;
10
+ import "../extension/BatchMintMetadata.sol " ;
5
11
import "../extension/LazyMint.sol " ;
6
12
13
+ import "../lib/TWStrings.sol " ;
14
+
7
15
/**
8
16
* BASE: ERC1155Base
9
17
* EXTENSION: LazyMint
10
18
*
11
- * The `ERC1155LazyMint` contract uses the `ERC1155Base` contract, along with the `LazyMint` extension.
19
+ * The `ERC1155LazyMint` smart contract implements the ERC1155 NFT standard.
20
+ * It includes the following additions to standard ERC1155 logic:
21
+ *
22
+ * - Lazy minting
23
+ *
24
+ * - Ability to mint NFTs via the provided `mintTo` and `batchMintTo` functions.
25
+ *
26
+ * - Contract metadata for royalty support on platforms such as OpenSea that use
27
+ * off-chain information to distribute roaylties.
28
+ *
29
+ * - Ownership of the contract, with the ability to restrict certain functions to
30
+ * only be called by the contract's owner.
31
+ *
32
+ * - Multicall capability to perform multiple actions atomically
33
+ *
34
+ * - EIP 2981 compliance for royalty support on NFT marketplaces.
35
+ *
36
+ *
37
+ * The `ERC1155LazyMint` contract uses the `LazyMint` extension.
12
38
*
13
39
* 'Lazy minting' means defining the metadata of NFTs without minting it to an address. Regular 'minting'
14
40
* of NFTs means actually assigning an owner to an NFT.
@@ -18,7 +44,19 @@ import "../extension/LazyMint.sol";
18
44
*
19
45
*/
20
46
21
- contract ERC1155LazyMint is ERC1155Base , LazyMint {
47
+ contract ERC1155LazyMint is ERC1155 , ContractMetadata , Ownable , Royalty , Multicall , BatchMintMetadata , LazyMint {
48
+ using TWStrings for uint256 ;
49
+
50
+ /*//////////////////////////////////////////////////////////////
51
+ Mappings
52
+ //////////////////////////////////////////////////////////////*/
53
+
54
+ /**
55
+ * @notice Returns the total supply of NFTs of a given tokenId
56
+ * @dev Mapping from tokenId => total circulating supply of NFTs of that tokenId.
57
+ */
58
+ mapping (uint256 => uint256 ) public totalSupply;
59
+
22
60
/*//////////////////////////////////////////////////////////////
23
61
Constructor
24
62
//////////////////////////////////////////////////////////////*/
@@ -28,59 +66,127 @@ contract ERC1155LazyMint is ERC1155Base, LazyMint {
28
66
string memory _symbol ,
29
67
address _royaltyRecipient ,
30
68
uint128 _royaltyBps
31
- ) ERC1155Base (_name, _symbol, _royaltyRecipient, _royaltyBps) {}
69
+ ) ERC1155 (_name, _symbol) {
70
+ _setupOwner (msg .sender );
71
+ _setupDefaultRoyaltyInfo (_royaltyRecipient, _royaltyBps);
72
+ }
73
+
74
+ /*//////////////////////////////////////////////////////////////
75
+ Overriden metadata logic
76
+ //////////////////////////////////////////////////////////////*/
77
+
78
+ /// @notice Returns the metadata URI for the given tokenId.
79
+ function uri (uint256 _tokenId ) public view virtual override returns (string memory ) {
80
+ string memory batchUri = getBaseURI (_tokenId);
81
+ return string (abi.encodePacked (batchUri, _tokenId.toString ()));
82
+ }
32
83
33
84
/*//////////////////////////////////////////////////////////////
34
- OVERRIDEN MINT LOGIC
85
+ CLAIM LOGIC
35
86
//////////////////////////////////////////////////////////////*/
36
87
37
88
/**
38
- * @notice Lets an authorized address mint lazy minted NFTs to a recipient.
39
- * @dev - The logic in the `_canMint` function determines whether the caller is authorized to mint NFTs.
89
+ * @notice Lets an address claim multiple lazy minted NFTs at once to a recipient.
90
+ * Contract creators should override this function to create custom logic for claiming,
91
+ * for e.g. price collection, allowlist, max quantity, etc.
40
92
*
41
- * @param _to The recipient of the NFTs to mint.
42
- * @param _tokenId The tokenId of the lazy minted NFT to mint.
43
- * @param _amount The amount of the same NFT to mint.
93
+ * @dev The logic in the `verifyClaim` function determines whether the caller is authorized to mint NFTs.
94
+ *
95
+ * @param _receiver The recipient of the tokens to mint.
96
+ * @param _tokenId The tokenId of the lazy minted NFT to mint.
97
+ * @param _quantity The number of tokens to mint.
44
98
*/
45
- function mintTo (
46
- address _to ,
99
+ function claim (
100
+ address _receiver ,
47
101
uint256 _tokenId ,
48
- string memory ,
49
- uint256 _amount
50
- ) public virtual override {
51
- require ( _canMint (), " Not authorized to mint. " );
102
+ uint256 _quantity
103
+ ) public payable virtual {
104
+ verifyClaim ( msg . sender , _tokenId, _quantity); // add your claim verification logic by overriding this function
105
+
52
106
require (_tokenId < nextTokenIdToMint (), "invalid id " );
53
107
54
- _mint (_to , _tokenId, _amount , "" );
108
+ _mint (_receiver , _tokenId, _quantity , "" );
55
109
}
56
110
57
111
/**
58
- * @notice Lets an authorized address mint multiple lazy minted NFTs at once to a recipient.
59
- * @dev The logic in the `_canMint` function determines whether the caller is authorized to mint NFTs.
112
+ * @notice Override this function to add logic for claim verification, based on conditions
113
+ * such as allowlist, price, max quantity etc.
114
+ *
115
+ * @dev Checks a request to claim NFTs against a custom condition.
116
+ *
117
+ * @param _claimer Caller of the claim function.
118
+ * @param _tokenId The tokenId of the lazy minted NFT to mint.
119
+ * @param _quantity The number of NFTs being claimed.
120
+ */
121
+ function verifyClaim (
122
+ address _claimer ,
123
+ uint256 _tokenId ,
124
+ uint256 _quantity
125
+ ) public view virtual {}
126
+
127
+ /**
128
+ * @notice Lets an owner or approved operator burn NFTs of the given tokenId.
60
129
*
61
- * @param _to The recipient of the NFT to mint .
62
- * @param _tokenIds The tokenIds of the NFTs to mint .
63
- * @param _amounts The amounts of each NFT to mint .
130
+ * @param _owner The owner of the NFT to burn .
131
+ * @param _tokenId The tokenId of the NFT to burn .
132
+ * @param _amount The amount of the NFT to burn .
64
133
*/
65
- function batchMintTo (
66
- address _to ,
134
+ function burn (
135
+ address _owner ,
136
+ uint256 _tokenId ,
137
+ uint256 _amount
138
+ ) external virtual {
139
+ address caller = msg .sender ;
140
+
141
+ require (caller == _owner || isApprovedForAll[_owner][caller], "Unapproved caller " );
142
+ require (balanceOf[_owner][_tokenId] >= _amount, "Not enough tokens owned " );
143
+
144
+ _burn (_owner, _tokenId, _amount);
145
+ }
146
+
147
+ /**
148
+ * @notice Lets an owner or approved operator burn NFTs of the given tokenIds.
149
+ *
150
+ * @param _owner The owner of the NFTs to burn.
151
+ * @param _tokenIds The tokenIds of the NFTs to burn.
152
+ * @param _amounts The amounts of the NFTs to burn.
153
+ */
154
+ function burnBatch (
155
+ address _owner ,
67
156
uint256 [] memory _tokenIds ,
68
- uint256 [] memory _amounts ,
69
- string memory
70
- ) public virtual override {
71
- require ( _canMint (), " Not authorized to mint. " );
72
- require (_amounts. length > 0 , "Minting zero tokens. " );
157
+ uint256 [] memory _amounts
158
+ ) external virtual {
159
+ address caller = msg . sender ;
160
+
161
+ require (caller == _owner || isApprovedForAll[_owner][caller] , "Unapproved caller " );
73
162
require (_tokenIds.length == _amounts.length , "Length mismatch " );
74
163
75
164
for (uint256 i = 0 ; i < _tokenIds.length ; i += 1 ) {
76
- require (_tokenIds[i] < nextTokenIdToMint () , "invalid id " );
165
+ require (balanceOf[_owner][ _tokenIds[i]] >= _amounts[i] , "Not enough tokens owned " );
77
166
}
78
167
79
- _mintBatch (_to, _tokenIds, _amounts, "" );
168
+ _burnBatch (_owner, _tokenIds, _amounts);
169
+ }
170
+
171
+ /*//////////////////////////////////////////////////////////////
172
+ ERC165 Logic
173
+ //////////////////////////////////////////////////////////////*/
174
+
175
+ /// @notice Returns whether this contract supports the given interface.
176
+ function supportsInterface (bytes4 interfaceId ) public view virtual override (ERC1155 , IERC165 ) returns (bool ) {
177
+ return
178
+ interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
179
+ interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
180
+ interfaceId == 0x0e89341c || // ERC165 Interface ID for ERC1155MetadataURI
181
+ interfaceId == type (IERC2981 ).interfaceId; // ERC165 ID for ERC2981
80
182
}
81
183
184
+ /*//////////////////////////////////////////////////////////////
185
+ View functions
186
+ //////////////////////////////////////////////////////////////*/
187
+
82
188
/// @notice The tokenId assigned to the next new NFT to be lazy minted.
83
- function nextTokenIdToMint () public view virtual override returns (uint256 ) {
189
+ function nextTokenIdToMint () public view virtual returns (uint256 ) {
84
190
return nextTokenIdToLazyMint;
85
191
}
86
192
@@ -92,4 +198,43 @@ contract ERC1155LazyMint is ERC1155Base, LazyMint {
92
198
function _canLazyMint () internal view virtual override returns (bool ) {
93
199
return msg .sender == owner ();
94
200
}
201
+
202
+ /// @dev Returns whether contract metadata can be set in the given execution context.
203
+ function _canSetContractURI () internal view virtual override returns (bool ) {
204
+ return msg .sender == owner ();
205
+ }
206
+
207
+ /// @dev Returns whether owner can be set in the given execution context.
208
+ function _canSetOwner () internal view virtual override returns (bool ) {
209
+ return msg .sender == owner ();
210
+ }
211
+
212
+ /// @dev Returns whether royalty info can be set in the given execution context.
213
+ function _canSetRoyaltyInfo () internal view virtual override returns (bool ) {
214
+ return msg .sender == owner ();
215
+ }
216
+
217
+ /// @dev Runs before every token transfer / mint / burn.
218
+ function _beforeTokenTransfer (
219
+ address operator ,
220
+ address from ,
221
+ address to ,
222
+ uint256 [] memory ids ,
223
+ uint256 [] memory amounts ,
224
+ bytes memory data
225
+ ) internal virtual override {
226
+ super ._beforeTokenTransfer (operator, from, to, ids, amounts, data);
227
+
228
+ if (from == address (0 )) {
229
+ for (uint256 i = 0 ; i < ids.length ; ++ i) {
230
+ totalSupply[ids[i]] += amounts[i];
231
+ }
232
+ }
233
+
234
+ if (to == address (0 )) {
235
+ for (uint256 i = 0 ; i < ids.length ; ++ i) {
236
+ totalSupply[ids[i]] -= amounts[i];
237
+ }
238
+ }
239
+ }
95
240
}
0 commit comments