This repository was archived by the owner on Dec 3, 2025. It is now read-only.
forked from ZTX-Foundation/tuxedo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathERC1155MaxSupplyMintable.sol
More file actions
155 lines (124 loc) · 5.92 KB
/
ERC1155MaxSupplyMintable.sol
File metadata and controls
155 lines (124 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.18;
import {ERC1155, ERC1155Supply} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
import {ERC1155Burnable} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Roles} from "@protocol/core/Roles.sol";
import {CoreRef} from "@protocol/refs/CoreRef.sol";
/// Base ERC 1155 NFT with total supply
/// Inherits CoreRef for roles and access
contract ERC1155MaxSupplyMintable is ERC1155Supply, ERC1155Burnable, CoreRef {
/// @notice contract name
string private _name;
/// @notice contract symbol
string private _symbol;
/// @notice an event emitted when a token's supply cap is updated
event SupplyCapUpdated(uint256 tokenId, uint256 previousMaxSupply, uint256 maxSupply);
/// @notice an event emitted when the URI is updated for a token
event URIUpdated(string newuri);
/// @notice an event emitted when a token is minted
event TokenMinted(address indexed account, uint256 indexed tokenId, uint256 amount);
/// @notice an event emitted when a token is burned
event TokenBurned(address indexed account, uint256 indexed tokenId, uint256 amount);
/// @notice an event emitted when a batch of tokens are minted
event BatchMinted(address indexed account, uint256[] tokenIds, uint256[] amounts);
/// @notice the maximum supply of a given token
mapping(uint256 tokenId => uint256 tokenMaxSupply) public maxTokenSupply;
/// @notice construct the ERC1155 with total supply and CoreRef
constructor(
address _core,
string memory _uri,
string memory name_,
string memory symbol_
) CoreRef(_core) ERC1155(_uri) {
_name = name_;
_symbol = symbol_;
}
/// @notice set the supply cap for a given token, cannot be less than current supply
/// @param tokenId the id of the token to update
/// @param maxSupply the new max supply of the token
function setSupplyCap(uint256 tokenId, uint256 maxSupply) external onlyRole(Roles.ADMIN) {
_setSupplyCap(tokenId, maxSupply);
}
/// @dev internal function to set the supply cap for a given token, cannot be less than current supply
/// @param tokenId the id of the token to update
/// @param maxSupply the new max supply of the token
function _setSupplyCap(uint256 tokenId, uint256 maxSupply) internal {
require(maxSupply >= totalSupply(tokenId), "BaseERC1155NFT: maxSupply cannot be less than current supply");
uint256 oldSupplyCap = maxTokenSupply[tokenId];
maxTokenSupply[tokenId] = maxSupply;
emit SupplyCapUpdated(tokenId, oldSupplyCap, maxSupply);
}
/// @notice set the URI for the token
/// @param newuri the new URI
/// callable by admin
function setURI(string memory newuri) external onlyRole(Roles.ADMIN) {
_setURI(newuri);
emit URIUpdated(newuri);
}
/// @notice mint tokens, can only mint as many exist left to be minted from the max token supply
/// @param recipient the address to mint to
/// @param tokenId the id of the token to mint
/// @param amount the amount of tokens to mint
/// callable only by minter role
/// can only be accessed if global lock is at level 1
/// @dev pauseable
function mint(
address recipient,
uint256 tokenId,
uint256 amount
) external onlyRole(Roles.MINTER_PROTOCOL_ROLE) whenNotPaused globalLock(2) {
require(totalSupply(tokenId) + amount <= maxTokenSupply[tokenId], "BaseERC1155NFT: supply exceeded");
/// no bytes passed on mint
_mint(recipient, tokenId, amount, "");
/// check for SMT solver and echidna
assert(totalSupply(tokenId) <= maxTokenSupply[tokenId]);
emit TokenMinted(recipient, tokenId, amount);
}
/// @notice mint tokens in a batch, can only mint as many exist left to be minted from the max token supply
/// @param recipient the address to mint to
/// @param tokenIds the ids of the tokens to mint
/// @param amounts the amounts of tokens to mint
function mintBatch(
address recipient,
uint256[] calldata tokenIds,
uint256[] calldata amounts
) external onlyRole(Roles.MINTER_PROTOCOL_ROLE) whenNotPaused globalLock(2) {
/// arity check on tokenIds.length and amounts.length done in ERC1155 _mintBatch
_mintBatch(recipient, tokenIds, amounts, "");
for (uint256 i = 0; i < tokenIds.length; i++) {
require(totalSupply(tokenIds[i]) <= maxTokenSupply[tokenIds[i]], "BaseERC1155NFT: supply exceeded");
}
emit BatchMinted(recipient, tokenIds, amounts);
}
/// ----------- VIEW ONLY API ------------
/// @notice returns the amount of tokens left to mint from the max supply
/// @param tokenId the id of the token to query
function getMintAmountLeft(uint256 tokenId) public view returns (uint256) {
return maxTokenSupply[tokenId] - totalSupply(tokenId);
}
/// @notice returns the name of the token
function name() public view returns (string memory) {
return _name;
}
/// @notice returns the symbol of the token
function symbol() public view returns (string memory) {
return _symbol;
}
/// ----------- INTERNAL OVERRIDES ------------
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory
) internal override(ERC1155, ERC1155Supply) {
ERC1155Supply._beforeTokenTransfer(operator, from, to, ids, amounts, "");
}
// Needed for openSea with ERC1155
function uri(uint256 _id) public view virtual override(ERC1155) returns (string memory) {
//slither-disable-next-line encode-packed-collision
return string(abi.encodePacked(super.uri(_id), Strings.toString(_id)));
}
}