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  }