github.com/diadata-org/diadata@v1.4.593/config/nftContracts/erc1155/erc1155.sol (about) 1 // SPDX-License-Identifier: MIT 2 // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/ERC1155.sol) 3 4 pragma solidity ^0.8.0; 5 6 import "./IERC1155.sol"; 7 import "./IERC1155Receiver.sol"; 8 import "./extensions/IERC1155MetadataURI.sol"; 9 import "../../utils/Address.sol"; 10 import "../../utils/Context.sol"; 11 import "../../utils/introspection/ERC165.sol"; 12 13 /** 14 * @dev Implementation of the basic standard multi-token. 15 * See https://eips.ethereum.org/EIPS/eip-1155 16 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 17 * 18 * _Available since v3.1._ 19 */ 20 contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { 21 using Address for address; 22 23 // Mapping from token ID to account balances 24 mapping(uint256 => mapping(address => uint256)) private _balances; 25 26 // Mapping from account to operator approvals 27 mapping(address => mapping(address => bool)) private _operatorApprovals; 28 29 // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json 30 string private _uri; 31 32 /** 33 * @dev See {_setURI}. 34 */ 35 constructor(string memory uri_) { 36 _setURI(uri_); 37 } 38 39 /** 40 * @dev See {IERC165-supportsInterface}. 41 */ 42 function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { 43 return 44 interfaceId == type(IERC1155).interfaceId || 45 interfaceId == type(IERC1155MetadataURI).interfaceId || 46 super.supportsInterface(interfaceId); 47 } 48 49 /** 50 * @dev See {IERC1155MetadataURI-uri}. 51 * 52 * This implementation returns the same URI for *all* token types. It relies 53 * on the token type ID substitution mechanism 54 * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. 55 * 56 * Clients calling this function must replace the `\{id\}` substring with the 57 * actual token type ID. 58 */ 59 function uri(uint256) public view virtual override returns (string memory) { 60 return _uri; 61 } 62 63 /** 64 * @dev See {IERC1155-balanceOf}. 65 * 66 * Requirements: 67 * 68 * - `account` cannot be the zero address. 69 */ 70 function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { 71 require(account != address(0), "ERC1155: address zero is not a valid owner"); 72 return _balances[id][account]; 73 } 74 75 /** 76 * @dev See {IERC1155-balanceOfBatch}. 77 * 78 * Requirements: 79 * 80 * - `accounts` and `ids` must have the same length. 81 */ 82 function balanceOfBatch(address[] memory accounts, uint256[] memory ids) 83 public 84 view 85 virtual 86 override 87 returns (uint256[] memory) 88 { 89 require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); 90 91 uint256[] memory batchBalances = new uint256[](accounts.length); 92 93 for (uint256 i = 0; i < accounts.length; ++i) { 94 batchBalances[i] = balanceOf(accounts[i], ids[i]); 95 } 96 97 return batchBalances; 98 } 99 100 /** 101 * @dev See {IERC1155-setApprovalForAll}. 102 */ 103 function setApprovalForAll(address operator, bool approved) public virtual override { 104 _setApprovalForAll(_msgSender(), operator, approved); 105 } 106 107 /** 108 * @dev See {IERC1155-isApprovedForAll}. 109 */ 110 function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { 111 return _operatorApprovals[account][operator]; 112 } 113 114 /** 115 * @dev See {IERC1155-safeTransferFrom}. 116 */ 117 function safeTransferFrom( 118 address from, 119 address to, 120 uint256 id, 121 uint256 amount, 122 bytes memory data 123 ) public virtual override { 124 require( 125 from == _msgSender() || isApprovedForAll(from, _msgSender()), 126 "ERC1155: caller is not token owner or approved" 127 ); 128 _safeTransferFrom(from, to, id, amount, data); 129 } 130 131 /** 132 * @dev See {IERC1155-safeBatchTransferFrom}. 133 */ 134 function safeBatchTransferFrom( 135 address from, 136 address to, 137 uint256[] memory ids, 138 uint256[] memory amounts, 139 bytes memory data 140 ) public virtual override { 141 require( 142 from == _msgSender() || isApprovedForAll(from, _msgSender()), 143 "ERC1155: caller is not token owner or approved" 144 ); 145 _safeBatchTransferFrom(from, to, ids, amounts, data); 146 } 147 148 /** 149 * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. 150 * 151 * Emits a {TransferSingle} event. 152 * 153 * Requirements: 154 * 155 * - `to` cannot be the zero address. 156 * - `from` must have a balance of tokens of type `id` of at least `amount`. 157 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the 158 * acceptance magic value. 159 */ 160 function _safeTransferFrom( 161 address from, 162 address to, 163 uint256 id, 164 uint256 amount, 165 bytes memory data 166 ) internal virtual { 167 require(to != address(0), "ERC1155: transfer to the zero address"); 168 169 address operator = _msgSender(); 170 uint256[] memory ids = _asSingletonArray(id); 171 uint256[] memory amounts = _asSingletonArray(amount); 172 173 _beforeTokenTransfer(operator, from, to, ids, amounts, data); 174 175 uint256 fromBalance = _balances[id][from]; 176 require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); 177 unchecked { 178 _balances[id][from] = fromBalance - amount; 179 } 180 _balances[id][to] += amount; 181 182 emit TransferSingle(operator, from, to, id, amount); 183 184 _afterTokenTransfer(operator, from, to, ids, amounts, data); 185 186 _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); 187 } 188 189 /** 190 * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. 191 * 192 * Emits a {TransferBatch} event. 193 * 194 * Requirements: 195 * 196 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the 197 * acceptance magic value. 198 */ 199 function _safeBatchTransferFrom( 200 address from, 201 address to, 202 uint256[] memory ids, 203 uint256[] memory amounts, 204 bytes memory data 205 ) internal virtual { 206 require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); 207 require(to != address(0), "ERC1155: transfer to the zero address"); 208 209 address operator = _msgSender(); 210 211 _beforeTokenTransfer(operator, from, to, ids, amounts, data); 212 213 for (uint256 i = 0; i < ids.length; ++i) { 214 uint256 id = ids[i]; 215 uint256 amount = amounts[i]; 216 217 uint256 fromBalance = _balances[id][from]; 218 require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); 219 unchecked { 220 _balances[id][from] = fromBalance - amount; 221 } 222 _balances[id][to] += amount; 223 } 224 225 emit TransferBatch(operator, from, to, ids, amounts); 226 227 _afterTokenTransfer(operator, from, to, ids, amounts, data); 228 229 _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); 230 } 231 232 /** 233 * @dev Sets a new URI for all token types, by relying on the token type ID 234 * substitution mechanism 235 * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. 236 * 237 * By this mechanism, any occurrence of the `\{id\}` substring in either the 238 * URI or any of the amounts in the JSON file at said URI will be replaced by 239 * clients with the token type ID. 240 * 241 * For example, the `https://token-cdn-domain/\{id\}.json` URI would be 242 * interpreted by clients as 243 * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` 244 * for token type ID 0x4cce0. 245 * 246 * See {uri}. 247 * 248 * Because these URIs cannot be meaningfully represented by the {URI} event, 249 * this function emits no events. 250 */ 251 function _setURI(string memory newuri) internal virtual { 252 _uri = newuri; 253 } 254 255 /** 256 * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. 257 * 258 * Emits a {TransferSingle} event. 259 * 260 * Requirements: 261 * 262 * - `to` cannot be the zero address. 263 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the 264 * acceptance magic value. 265 */ 266 function _mint( 267 address to, 268 uint256 id, 269 uint256 amount, 270 bytes memory data 271 ) internal virtual { 272 require(to != address(0), "ERC1155: mint to the zero address"); 273 274 address operator = _msgSender(); 275 uint256[] memory ids = _asSingletonArray(id); 276 uint256[] memory amounts = _asSingletonArray(amount); 277 278 _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); 279 280 _balances[id][to] += amount; 281 emit TransferSingle(operator, address(0), to, id, amount); 282 283 _afterTokenTransfer(operator, address(0), to, ids, amounts, data); 284 285 _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); 286 } 287 288 /** 289 * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. 290 * 291 * Emits a {TransferBatch} event. 292 * 293 * Requirements: 294 * 295 * - `ids` and `amounts` must have the same length. 296 * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the 297 * acceptance magic value. 298 */ 299 function _mintBatch( 300 address to, 301 uint256[] memory ids, 302 uint256[] memory amounts, 303 bytes memory data 304 ) internal virtual { 305 require(to != address(0), "ERC1155: mint to the zero address"); 306 require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); 307 308 address operator = _msgSender(); 309 310 _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); 311 312 for (uint256 i = 0; i < ids.length; i++) { 313 _balances[ids[i]][to] += amounts[i]; 314 } 315 316 emit TransferBatch(operator, address(0), to, ids, amounts); 317 318 _afterTokenTransfer(operator, address(0), to, ids, amounts, data); 319 320 _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); 321 } 322 323 /** 324 * @dev Destroys `amount` tokens of token type `id` from `from` 325 * 326 * Emits a {TransferSingle} event. 327 * 328 * Requirements: 329 * 330 * - `from` cannot be the zero address. 331 * - `from` must have at least `amount` tokens of token type `id`. 332 */ 333 function _burn( 334 address from, 335 uint256 id, 336 uint256 amount 337 ) internal virtual { 338 require(from != address(0), "ERC1155: burn from the zero address"); 339 340 address operator = _msgSender(); 341 uint256[] memory ids = _asSingletonArray(id); 342 uint256[] memory amounts = _asSingletonArray(amount); 343 344 _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); 345 346 uint256 fromBalance = _balances[id][from]; 347 require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); 348 unchecked { 349 _balances[id][from] = fromBalance - amount; 350 } 351 352 emit TransferSingle(operator, from, address(0), id, amount); 353 354 _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); 355 } 356 357 /** 358 * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. 359 * 360 * Emits a {TransferBatch} event. 361 * 362 * Requirements: 363 * 364 * - `ids` and `amounts` must have the same length. 365 */ 366 function _burnBatch( 367 address from, 368 uint256[] memory ids, 369 uint256[] memory amounts 370 ) internal virtual { 371 require(from != address(0), "ERC1155: burn from the zero address"); 372 require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); 373 374 address operator = _msgSender(); 375 376 _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); 377 378 for (uint256 i = 0; i < ids.length; i++) { 379 uint256 id = ids[i]; 380 uint256 amount = amounts[i]; 381 382 uint256 fromBalance = _balances[id][from]; 383 require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); 384 unchecked { 385 _balances[id][from] = fromBalance - amount; 386 } 387 } 388 389 emit TransferBatch(operator, from, address(0), ids, amounts); 390 391 _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); 392 } 393 394 /** 395 * @dev Approve `operator` to operate on all of `owner` tokens 396 * 397 * Emits an {ApprovalForAll} event. 398 */ 399 function _setApprovalForAll( 400 address owner, 401 address operator, 402 bool approved 403 ) internal virtual { 404 require(owner != operator, "ERC1155: setting approval status for self"); 405 _operatorApprovals[owner][operator] = approved; 406 emit ApprovalForAll(owner, operator, approved); 407 } 408 409 /** 410 * @dev Hook that is called before any token transfer. This includes minting 411 * and burning, as well as batched variants. 412 * 413 * The same hook is called on both single and batched variants. For single 414 * transfers, the length of the `ids` and `amounts` arrays will be 1. 415 * 416 * Calling conditions (for each `id` and `amount` pair): 417 * 418 * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens 419 * of token type `id` will be transferred to `to`. 420 * - When `from` is zero, `amount` tokens of token type `id` will be minted 421 * for `to`. 422 * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` 423 * will be burned. 424 * - `from` and `to` are never both zero. 425 * - `ids` and `amounts` have the same, non-zero length. 426 * 427 * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 428 */ 429 function _beforeTokenTransfer( 430 address operator, 431 address from, 432 address to, 433 uint256[] memory ids, 434 uint256[] memory amounts, 435 bytes memory data 436 ) internal virtual {} 437 438 /** 439 * @dev Hook that is called after any token transfer. This includes minting 440 * and burning, as well as batched variants. 441 * 442 * The same hook is called on both single and batched variants. For single 443 * transfers, the length of the `id` and `amount` arrays will be 1. 444 * 445 * Calling conditions (for each `id` and `amount` pair): 446 * 447 * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens 448 * of token type `id` will be transferred to `to`. 449 * - When `from` is zero, `amount` tokens of token type `id` will be minted 450 * for `to`. 451 * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` 452 * will be burned. 453 * - `from` and `to` are never both zero. 454 * - `ids` and `amounts` have the same, non-zero length. 455 * 456 * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 457 */ 458 function _afterTokenTransfer( 459 address operator, 460 address from, 461 address to, 462 uint256[] memory ids, 463 uint256[] memory amounts, 464 bytes memory data 465 ) internal virtual {} 466 467 function _doSafeTransferAcceptanceCheck( 468 address operator, 469 address from, 470 address to, 471 uint256 id, 472 uint256 amount, 473 bytes memory data 474 ) private { 475 if (to.isContract()) { 476 try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { 477 if (response != IERC1155Receiver.onERC1155Received.selector) { 478 revert("ERC1155: ERC1155Receiver rejected tokens"); 479 } 480 } catch Error(string memory reason) { 481 revert(reason); 482 } catch { 483 revert("ERC1155: transfer to non-ERC1155Receiver implementer"); 484 } 485 } 486 } 487 488 function _doSafeBatchTransferAcceptanceCheck( 489 address operator, 490 address from, 491 address to, 492 uint256[] memory ids, 493 uint256[] memory amounts, 494 bytes memory data 495 ) private { 496 if (to.isContract()) { 497 try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( 498 bytes4 response 499 ) { 500 if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { 501 revert("ERC1155: ERC1155Receiver rejected tokens"); 502 } 503 } catch Error(string memory reason) { 504 revert(reason); 505 } catch { 506 revert("ERC1155: transfer to non-ERC1155Receiver implementer"); 507 } 508 } 509 } 510 511 function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { 512 uint256[] memory array = new uint256[](1); 513 array[0] = element; 514 515 return array; 516 } 517 }