// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)pragmasolidity ^0.8.1;/**
* @dev Collection of functions related to the address type
*/libraryAddress{
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0// for contracts in construction, since the code is only stored at the end// of the constructor execution.return account.code.length>0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/functionfunctionCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target,
bytesmemory data,
uint256 value
) internalreturns (bytesmemory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/functionfunctionCallWithValue(address target,
bytesmemory data,
uint256 value,
stringmemory errorMessage
) internalreturns (bytesmemory) {
require(address(this).balance>= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytesmemory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target, bytesmemory data) internalviewreturns (bytesmemory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/functionfunctionStaticCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalviewreturns (bytesmemory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytesmemory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target, bytesmemory data) internalreturns (bytesmemory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/functionfunctionDelegateCall(address target,
bytesmemory data,
stringmemory errorMessage
) internalreturns (bytesmemory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytesmemory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/functionverifyCallResult(bool success,
bytesmemory returndata,
stringmemory errorMessage
) internalpurereturns (bytesmemory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if presentif (returndata.length>0) {
// The easiest way to bubble the revert reason is using memory via assembly/// @solidity memory-safe-assemblyassembly {
let returndata_size :=mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
Contract Source Code
File 2 of 16: ChampionsArena.sol
// SPDX-License-Identifier: MITpragmasolidity 0.8.13;import"./Common.sol";
import"@openzeppelin/contracts/utils/Address.sol";
import"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import"@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import"@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import"@openzeppelin/contracts/utils/introspection/ERC165.sol";
import"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol";
import"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import"@openzeppelin/contracts/security/Pausable.sol";
import"@openzeppelin/contracts/access/Ownable.sol";
import"@openzeppelin/contracts/utils/Strings.sol";
import"operator-filter-registry/src/UpdatableOperatorFilterer.sol";
contractChampionsArenaisIERC1155, ERC165, Pausable, CommonConstants, Ownable, IERC1155MetadataURI, UpdatableOperatorFilterer{
usingAddressforaddress;
uint256constant TYPE_MASK =uint256(type(uint128).max) <<128;
uint256publicconstant NF_INDEX_MASK =type(uint128).max;
uint256constant TYPE_NF_BIT =1<<255;
uint256 nonce;
stringpublic client;
mapping(uint256=>mapping(address=>uint256)) internal balances; // id => (owner => balance)mapping(address=>mapping(address=>bool)) internal operatorApproval; // owner => (operator => approved)mapping(uint256=>address) public nfOwners;
mapping(uint256=>bool) public nfExists;
mapping(uint256=>uint256) public tokenSupply;
mapping(address=>bool) internal creators;
//URI mappingstringprivate baseContractURI ="";
stringprivate baseURI ="";
eventClient(string _clientName);
eventCreator(address _creator, bool _authorized);
eventBaseURI(string baseURI);
eventContractURI(string contractURI);
eventBaseTypeCreated(uint256 baseType);
addressprivateconstant DEFAULT_REGISTRY =0x000000000000AAeB6D7670E522A718067333cd4E;
addressprivateconstant DEFAULT_SUBSCRIPTION =0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
constructor(stringmemory _client) UpdatableOperatorFilterer(DEFAULT_REGISTRY, DEFAULT_SUBSCRIPTION, true) {
require(bytes(_client).length>0, "Contract client name is required!");
creators[msg.sender] =true;
client = _client;
emit Client(_client);
}
modifiercreatorOnly() {
require(creators[msg.sender], "Creator permission required");
_;
}
functioncreate(bool _isNF) externalwhenNotPausedcreatorOnlyreturns (uint256 _type) {
_type = (++nonce <<128);
if (_isNF)
{
_type = _type | TYPE_NF_BIT;
nfExists[_type] =true;
}
else
{
emit TransferSingle(msg.sender, address(0x0), address(0x0), _type, 0);
}
emit BaseTypeCreated(_type);
return _type;
}
functionmintNonFungible(uint256[] calldata _ids,
address[] calldata _to,
bytescalldata _data
) externalwhenNotPausedcreatorOnly{
require(_ids.length== _to.length, "IDs and recipients must be of same length");
for (uint256 i =0; i < _to.length; ++i) {
uint256 tokenType = getNonFungibleBaseType(_ids[i]);
require(nfExists[tokenType], "NF token must exist");
require(isNonFungible(tokenType), "TokenType not non-fungible");
require(_to[i] !=address(0x0), "Cannot mint to zero address");
require(nfOwners[_ids[i]] ==address(0x0), "Token already owned");
address distributeTo = _to[i];
nfOwners[_ids[i]] = distributeTo;
tokenSupply[tokenType] = tokenSupply[tokenType] +1;
balances[tokenType][distributeTo] = balances[tokenType][distributeTo] +1;
emit TransferSingle(msg.sender, address(0x0), distributeTo, _ids[i], 1);
broadcastURIEvent(_ids[i]);
if (distributeTo.isContract()) {
_doSafeTransferAcceptanceCheck(msg.sender, msg.sender, distributeTo, _ids[i], 1, _data);
}
}
}
functionmintFungible(uint256 _id,
address[] calldata _to,
uint256[] calldata _quantities,
bytescalldata _data
) externalwhenNotPausedcreatorOnly{
require(isFungible(_id), "ID must be a non-fungible ID");
require(_to.length== _quantities.length, "Address and quantity length mismatch");
for (uint256 i =0; i < _to.length; ++i) {
require(_to[i] !=address(0x0), "Recipient address cannot be zero");
balances[_id][_to[i]] = _quantities[i] + balances[_id][_to[i]];
tokenSupply[_id] = tokenSupply[_id] + _quantities[i];
emit TransferSingle(msg.sender, address(0x0), _to[i], _id, _quantities[i]);
if (_to[i].isContract()) {
_doSafeTransferAcceptanceCheck(msg.sender, msg.sender, _to[i], _id, _quantities[i], _data);
}
}
}
functionsafeTransferFrom(address _from,
address _to,
uint256 _id,
uint256 _value,
bytescalldata _data
) externaloverridewhenNotPausedonlyAllowedOperator(_from) {
require(_to !=address(0x0), "cannot send to zero address");
require(_from ==msg.sender|| operatorApproval[_from][msg.sender] ==true, "Need operator approval for 3rd party transfers");
if (isNonFungible(_id)) {
require(nfOwners[_id] == _from, "Invalid owner");
require(_value >0, "quantity must be greater than zero");
nfOwners[_id] = _to;
// You could keep balance of NF type in base type id like so:uint256 baseType = getNonFungibleBaseType(_id);
balances[baseType][_from] = balances[baseType][_from] - _value;
balances[baseType][_to] = balances[baseType][_to] + _value;
} else {
balances[_id][_from] = balances[_id][_from] - _value;
balances[_id][_to] = balances[_id][_to] + _value;
}
emit TransferSingle(msg.sender, _from, _to, _id, _value);
if (_to.isContract()) {
_doSafeTransferAcceptanceCheck(msg.sender, _from, _to, _id, _value, _data);
}
}
functionsafeBatchTransferFrom(address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytescalldata _data
) externaloverridewhenNotPausedonlyAllowedOperator(_from) {
require(_to !=address(0x0), "Cannot send to zero address");
require(_ids.length== _values.length, "Array length must match");
require(_from ==msg.sender|| operatorApproval[_from][msg.sender] ==true, "Need operator approval for 3rd party transfers");
for (uint256 i =0; i < _ids.length; ++i) {
if (isNonFungible(_ids[i])) {
require(nfOwners[_ids[i]] == _from, "Invalid owner");
require(_values[i] >0, "quantity must be greater than zero");
nfOwners[_ids[i]] = _to;
balances[getNonFungibleBaseType(_ids[i])][_from] = balances[getNonFungibleBaseType(_ids[i])][_from] - _values[i];
balances[getNonFungibleBaseType(_ids[i])][_to] = balances[getNonFungibleBaseType(_ids[i])][_to] + _values[i];
} else {
balances[_ids[i]][_from] = balances[_ids[i]][_from] - _values[i];
balances[_ids[i]][_to] = _values[i] + balances[_ids[i]][_to];
}
}
emit TransferBatch(msg.sender, _from, _to, _ids, _values);
if (_to.isContract()) {
_doSafeBatchTransferAcceptanceCheck(msg.sender, _from, _to, _ids, _values, _data);
}
}
functionbalanceOf(address _owner, uint256 _id) externalviewoverridereturns (uint256) {
if (isNonFungibleItem(_id)) return nfOwners[_id] == _owner ? 1 : 0;
return balances[_id][_owner];
}
functionbalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) externalviewoverridereturns (uint256[] memory) {
require(_owners.length== _ids.length, "Owners and ids length mismatch");
uint256[] memory balances_ =newuint256[](_owners.length);
for (uint256 i =0; i < _owners.length; ++i) {
uint256 id = _ids[i];
if (isNonFungibleItem(id)) {
balances_[i] = nfOwners[id] == _owners[i] ? 1 : 0;
} else {
balances_[i] = balances[id][_owners[i]];
}
}
return balances_;
}
functionsetApprovalForAll(address _operator, bool _approved) externaloverridewhenNotPausedonlyAllowedOperatorApproval(_operator) {
require(msg.sender!= _operator, "ERC1155: setting approval status for self");
operatorApproval[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
functionisApprovedForAll(address _owner, address _operator) externalviewoverridereturns (bool) {
return operatorApproval[_owner][_operator];
}
functionisNonFungible(uint256 _id) publicpurereturns (bool) {
return _id & TYPE_NF_BIT == TYPE_NF_BIT;
}
functionisFungible(uint256 _id) publicpurereturns (bool) {
return _id & TYPE_NF_BIT ==0;
}
functiongetNonFungibleIndex(uint256 _id) publicpurereturns (uint256) {
return _id & NF_INDEX_MASK;
}
functiongetNonFungibleBaseType(uint256 _id) publicpurereturns (uint256) {
return _id & TYPE_MASK;
}
functionisNonFungibleBaseType(uint256 _id) externalpurereturns (bool) {
// A base type has the NF bit but does not have an index.return (_id & TYPE_NF_BIT == TYPE_NF_BIT) && (_id & NF_INDEX_MASK ==0);
}
functionisNonFungibleItem(uint256 _id) publicpurereturns (bool) {
// A base type has the NF bit but does has an index.return (_id & TYPE_NF_BIT == TYPE_NF_BIT) && (_id & NF_INDEX_MASK !=0);
}
functionownerOf(uint256 _id) externalviewreturns (address) {
return nfOwners[_id];
}
function_doSafeTransferAcceptanceCheck(address _operator,
address _from,
address _to,
uint256 _id,
uint256 _value,
bytesmemory _data
) internal{
require(
ERC1155Receiver(_to).onERC1155Received(_operator, _from, _id, _value, _data) == ERC1155_ACCEPTED,
"contract returned an unknown value from onERC1155Received"
);
}
function_doSafeBatchTransferAcceptanceCheck(address _operator,
address _from,
address _to,
uint256[] memory _ids,
uint256[] memory _values,
bytesmemory _data
) internal{
require(
ERC1155Receiver(_to).onERC1155BatchReceived(_operator, _from, _ids, _values, _data) == ERC1155_BATCH_ACCEPTED,
"contract returned an unknown value from onERC1155BatchReceived"
);
}
functionbatchAuthorizeCreators(address[] calldata _addresses) externalwhenNotPausedonlyOwner{
for (uint256 i =0; i < _addresses.length; ++i) {
emit Creator(_addresses[i], true);
creators[_addresses[i]] =true;
}
}
functionbatchDeauthorizeCreators(address[] calldata _addresses) externalwhenNotPausedonlyOwner{
for (uint256 i =0; i < _addresses.length; ++i) {
delete creators[_addresses[i]];
emit Creator(_addresses[i], false);
}
}
functionburn(address _from,
uint256[] calldata _ids,
uint256[] calldata _values
) externalwhenNotPaused{
require(_from ==msg.sender|| operatorApproval[_from][msg.sender] ==true, "Need operator approval for 3rd party burn");
require(_ids.length>0&& _ids.length== _values.length, "Ids and values mismatch");
for (uint256 i =0; i < _ids.length; i++) {
if (isFungible(_ids[i])) {
require(balances[_ids[i]][_from] >= _values[i],"balance must be greater than value");
balances[_ids[i]][_from] = balances[_ids[i]][_from] - _values[i];
tokenSupply[_ids[i]] = tokenSupply[_ids[i]] - _values[i];
} else {
require(isNonFungible(_ids[i]), "Id must be non fungible");
require(_values[i] ==1,"value must be 1");
uint256 baseType = getNonFungibleBaseType(_ids[i]);
balances[baseType][_from] = balances[baseType][_from] -1;
tokenSupply[baseType] = tokenSupply[baseType] - _values[i];
delete nfOwners[_ids[i]];
}
emit TransferSingle(msg.sender, _from, address(0x0), _ids[i], _values[i]);
}
}
functionuri(uint256 _tokenId) publicoverrideviewreturns (stringmemory) {
if (isNonFungible(_tokenId)) {
uint256 baseType = getNonFungibleBaseType(_tokenId);
uint256 instanceId = getNonFungibleIndex(_tokenId);
returnstring(abi.encodePacked(baseURI, Strings.toString(baseType), "/", Strings.toString(instanceId)));
} else {
returnstring(abi.encodePacked(baseURI, Strings.toString(_tokenId)));
}
}
functionbroadcastURIEvent(uint256 _tokenId) publiccreatorOnly{
stringmemory _uri = uri(_tokenId);
emit URI(_uri, _tokenId);
}
functionsetBaseURI(stringmemory _baseURI) externalcreatorOnly{
baseURI = _baseURI;
emit BaseURI(baseURI);
}
functioncontractURI() externalviewreturns (stringmemory) {
return baseContractURI;
}
functionsetContractURI(stringmemory _contractUri) externalonlyOwner{
baseContractURI = _contractUri;
emit ContractURI(baseContractURI);
}
functionupdateClientName(stringcalldata _newClientName) externalwhenNotPausedonlyOwner{
require(bytes(_newClientName).length>0, "Client name cannot be empty");
client = _newClientName;
emit Client(_newClientName);
}
functionpause() externalonlyOwner{
_pause();
}
functionunpause() externalonlyOwner{
_unpause();
}
functionsupportsInterface(bytes4 _interfaceId) publicviewvirtualoverride(ERC165, IERC165) returns (bool) {
return _interfaceId ==type(IERC1155).interfaceId|| _interfaceId ==type(IERC1155MetadataURI).interfaceId||super.supportsInterface(_interfaceId);
}
functionowner() publicoverride(Ownable, UpdatableOperatorFilterer) viewvirtualreturns (address) {
return Ownable.owner();
}
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)pragmasolidity ^0.8.0;/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
returnmsg.data;
}
}
Contract Source Code
File 5 of 16: ERC1155Holder.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)pragmasolidity ^0.8.0;import"./ERC1155Receiver.sol";
/**
* Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
*
* IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
* stuck.
*
* @dev _Available since v3.1._
*/contractERC1155HolderisERC1155Receiver{
functiononERC1155Received(address,
address,
uint256,
uint256,
bytesmemory) publicvirtualoverridereturns (bytes4) {
returnthis.onERC1155Received.selector;
}
functiononERC1155BatchReceived(address,
address,
uint256[] memory,
uint256[] memory,
bytesmemory) publicvirtualoverridereturns (bytes4) {
returnthis.onERC1155BatchReceived.selector;
}
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)pragmasolidity ^0.8.0;import"./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/abstractcontractERC165isIERC165{
/**
* @dev See {IERC165-supportsInterface}.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualoverridereturns (bool) {
return interfaceId ==type(IERC165).interfaceId;
}
}
Contract Source Code
File 8 of 16: IERC1155.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)pragmasolidity ^0.8.0;import"../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/interfaceIERC1155isIERC165{
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/eventTransferSingle(addressindexed operator, addressindexedfrom, addressindexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/eventTransferBatch(addressindexed operator,
addressindexedfrom,
addressindexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/eventApprovalForAll(addressindexed account, addressindexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/eventURI(string value, uint256indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/functionbalanceOf(address account, uint256 id) externalviewreturns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/functionbalanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
externalviewreturns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/functionsetApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/functionisApprovedForAll(address account, address operator) externalviewreturns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/functionsafeTransferFrom(addressfrom,
address to,
uint256 id,
uint256 amount,
bytescalldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/functionsafeBatchTransferFrom(addressfrom,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytescalldata data
) external;
}
Contract Source Code
File 9 of 16: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)pragmasolidity ^0.8.0;import"../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/interfaceIERC1155MetadataURIisIERC1155{
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/functionuri(uint256 id) externalviewreturns (stringmemory);
}
Contract Source Code
File 10 of 16: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)pragmasolidity ^0.8.0;import"../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/interfaceIERC1155ReceiverisIERC165{
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/functiononERC1155Received(address operator,
addressfrom,
uint256 id,
uint256 value,
bytescalldata data
) externalreturns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/functiononERC1155BatchReceived(address operator,
addressfrom,
uint256[] calldata ids,
uint256[] calldata values,
bytescalldata data
) externalreturns (bytes4);
}
Contract Source Code
File 11 of 16: IERC165.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/interfaceIERC165{
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/functionsupportsInterface(bytes4 interfaceId) externalviewreturns (bool);
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)pragmasolidity ^0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/function_checkOwner() internalviewvirtual{
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/function_transferOwnership(address newOwner) internalvirtual{
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Contract Source Code
File 14 of 16: Pausable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)pragmasolidity ^0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/abstractcontractPausableisContext{
/**
* @dev Emitted when the pause is triggered by `account`.
*/eventPaused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/eventUnpaused(address account);
boolprivate _paused;
/**
* @dev Initializes the contract in unpaused state.
*/constructor() {
_paused =false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/modifierwhenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/modifierwhenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/functionpaused() publicviewvirtualreturns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/function_requireNotPaused() internalviewvirtual{
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/function_requirePaused() internalviewvirtual{
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/function_pause() internalvirtualwhenNotPaused{
_paused =true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/function_unpause() internalvirtualwhenPaused{
_paused =false;
emit Unpaused(_msgSender());
}
}
Contract Source Code
File 15 of 16: Strings.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)pragmasolidity ^0.8.0;/**
* @dev String operations.
*/libraryStrings{
bytes16privateconstant _HEX_SYMBOLS ="0123456789abcdef";
uint8privateconstant _ADDRESS_LENGTH =20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/functiontoString(uint256 value) internalpurereturns (stringmemory) {
// Inspired by OraclizeAPI's implementation - MIT licence// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.solif (value ==0) {
return"0";
}
uint256 temp = value;
uint256 digits;
while (temp !=0) {
digits++;
temp /=10;
}
bytesmemory buffer =newbytes(digits);
while (value !=0) {
digits -=1;
buffer[digits] =bytes1(uint8(48+uint256(value %10)));
value /=10;
}
returnstring(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/functiontoHexString(uint256 value) internalpurereturns (stringmemory) {
if (value ==0) {
return"0x00";
}
uint256 temp = value;
uint256 length =0;
while (temp !=0) {
length++;
temp >>=8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/functiontoHexString(uint256 value, uint256 length) internalpurereturns (stringmemory) {
bytesmemory buffer =newbytes(2* length +2);
buffer[0] ="0";
buffer[1] ="x";
for (uint256 i =2* length +1; i >1; --i) {
buffer[i] = _HEX_SYMBOLS[value &0xf];
value >>=4;
}
require(value ==0, "Strings: hex length insufficient");
returnstring(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/functiontoHexString(address addr) internalpurereturns (stringmemory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
Contract Source Code
File 16 of 16: UpdatableOperatorFilterer.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.13;import {IOperatorFilterRegistry} from"./IOperatorFilterRegistry.sol";
/**
* @title UpdatableOperatorFilterer
* @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
* registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
* OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
* which will bypass registry checks.
* Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders
* on-chain, eg, if the registry is revoked or bypassed.
* @dev This smart contract is meant to be inherited by token contracts so they can use the following:
* - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
* - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
*/abstractcontractUpdatableOperatorFilterer{
errorOperatorNotAllowed(address operator);
errorOnlyOwner();
IOperatorFilterRegistry public operatorFilterRegistry;
constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) {
IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry);
operatorFilterRegistry = registry;
// If an inheriting token contract is deployed to a network without the registry deployed, the modifier// will not revert, but the contract will need to be registered with the registry once it is deployed in// order for the modifier to filter addresses.if (address(registry).code.length>0) {
if (subscribe) {
registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
} else {
if (subscriptionOrRegistrantToCopy !=address(0)) {
registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
} else {
registry.register(address(this));
}
}
}
}
modifieronlyAllowedOperator(addressfrom) virtual{
// Allow spending tokens from addresses with balance// Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred// from an EOA.if (from!=msg.sender) {
_checkFilterOperator(msg.sender);
}
_;
}
modifieronlyAllowedOperatorApproval(address operator) virtual{
_checkFilterOperator(operator);
_;
}
/**
* @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
* address, checks will be bypassed. OnlyOwner.
*/functionupdateOperatorFilterRegistryAddress(address newRegistry) publicvirtual{
if (msg.sender!= owner()) {
revert OnlyOwner();
}
operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
}
/**
* @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract
*/functionowner() publicviewvirtualreturns (address);
function_checkFilterOperator(address operator) internalviewvirtual{
IOperatorFilterRegistry registry = operatorFilterRegistry;
// Check registry code length to facilitate testing in environments without a deployed registry.if (address(registry) !=address(0) &&address(registry).code.length>0) {
if (!registry.isOperatorAllowed(address(this), operator)) {
revert OperatorNotAllowed(operator);
}
}
}
}