// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../utils/EnumerableSet.sol";
import"../utils/Address.sol";
import"../utils/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it.
*/abstractcontractAccessControlisContext{
usingEnumerableSetforEnumerableSet.AddressSet;
usingAddressforaddress;
structRoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32=> RoleData) private _roles;
bytes32publicconstant DEFAULT_ADMIN_ROLE =0x00;
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/eventRoleAdminChanged(bytes32indexed role, bytes32indexed previousAdminRole, bytes32indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {_setupRole}.
*/eventRoleGranted(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/eventRoleRevoked(bytes32indexed role, addressindexed account, addressindexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/functionhasRole(bytes32 role, address account) publicviewreturns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/functiongetRoleMemberCount(bytes32 role) publicviewreturns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/functiongetRoleMember(bytes32 role, uint256 index) publicviewreturns (address) {
return _roles[role].members.at(index);
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/functiongetRoleAdmin(bytes32 role) publicviewreturns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functiongrantRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/functionrevokeRole(bytes32 role, address account) publicvirtual{
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/functionrenounceRole(bytes32 role, address account) publicvirtual{
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*/function_setupRole(bytes32 role, address account) internalvirtual{
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/function_setRoleAdmin(bytes32 role, bytes32 adminRole) internalvirtual{
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function_grantRole(bytes32 role, address account) private{
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function_revokeRole(bytes32 role, address account) private{
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}
Contract Source Code
File 2 of 28: Address.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.2 <0.8.0;/**
* @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
* ====
*/functionisContract(address account) internalviewreturns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in// construction, since the code is only stored at the end of the// constructor execution.uint256 size;
// solhint-disable-next-line no-inline-assemblyassembly { size :=extcodesize(account) }
return size >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");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(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");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function_verifyCallResult(bool success, bytesmemory returndata, stringmemory errorMessage) privatepurereturns(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// solhint-disable-next-line no-inline-assemblyassembly {
let returndata_size :=mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <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 GSN 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 (addresspayable) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytesmemory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691returnmsg.data;
}
}
Contract Source Code
File 6 of 28: ERC165.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/abstractcontractERC165isIERC165{
/*
* bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
*/bytes4privateconstant _INTERFACE_ID_ERC165 =0x01ffc9a7;
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/mapping(bytes4=>bool) private _supportedInterfaces;
constructor () internal{
// Derived contracts need only register support for their own interfaces,// we register support for ERC165 itself here
_registerInterface(_INTERFACE_ID_ERC165);
}
/**
* @dev See {IERC165-supportsInterface}.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/functionsupportsInterface(bytes4 interfaceId) publicviewvirtualoverridereturns (bool) {
return _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/function_registerInterface(bytes4 interfaceId) internalvirtual{
require(interfaceId !=0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] =true;
}
}
Contract Source Code
File 7 of 28: EnumerableSet.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/libraryEnumerableSet{
// To implement this library for multiple types with as little code// repetition as possible, we write it in terms of a generic Set type with// bytes32 values.// The Set implementation uses private functions, and user-facing// implementations (such as AddressSet) are just wrappers around the// underlying Set.// This means that we can only create new EnumerableSets for types that fit// in bytes32.structSet {
// Storage of set valuesbytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0// means a value is not in the set.mapping (bytes32=>uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/function_add(Set storage set, bytes32 value) privatereturns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/function_remove(Set storage set, bytes32 value) privatereturns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slotuint256 valueIndex = set._indexes[value];
if (valueIndex !=0) { // Equivalent to contains(set, value)// To delete an element from the _values array in O(1), we swap the element to delete with the last one in// the array, and then remove the last element (sometimes called as 'swap and pop').// This modifies the order of the array, as noted in {at}.uint256 toDeleteIndex = valueIndex -1;
uint256 lastIndex = set._values.length-1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex +1; // All indexes are 1-based// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slotdelete set._indexes[value];
returntrue;
} else {
returnfalse;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/function_contains(Set storage set, bytes32 value) privateviewreturns (bool) {
return set._indexes[value] !=0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/function_length(Set storage set) privateviewreturns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/function_at(Set storage set, uint256 index) privateviewreturns (bytes32) {
require(set._values.length> index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32SetstructBytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(Bytes32Set storage set, bytes32 value) internalreturns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(Bytes32Set storage set, bytes32 value) internalviewreturns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(Bytes32Set storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(Bytes32Set storage set, uint256 index) internalviewreturns (bytes32) {
return _at(set._inner, index);
}
// AddressSetstructAddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(AddressSet storage set, address value) internalreturns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(AddressSet storage set, address value) internalreturns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(AddressSet storage set, address value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/functionlength(AddressSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(AddressSet storage set, uint256 index) internalviewreturns (address) {
returnaddress(uint160(uint256(_at(set._inner, index))));
}
// UintSetstructUintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/functionadd(UintSet storage set, uint256 value) internalreturns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/functionremove(UintSet storage set, uint256 value) internalreturns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/functioncontains(UintSet storage set, uint256 value) internalviewreturns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/functionlength(UintSet storage set) internalviewreturns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/functionat(UintSet storage set, uint256 index) internalviewreturns (uint256) {
returnuint256(_at(set._inner, index));
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.2 <0.8.0;import"../../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 be 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 11 of 28: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.2 <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 12 of 28: IERC1155Receiver.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"../../introspection/IERC165.sol";
/**
* _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.
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. 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 13 of 28: IERC165.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <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);
}
Contract Source Code
File 14 of 28: IERC2981.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;interfaceIERC2981{
/// @notice Called with the sale price to determine how much royalty// is owed and to whom./// @param _tokenId - the NFT asset queried for royalty information/// @param _salePrice - the sale price of the NFT asset specified by _tokenId/// @return receiver - address of who should be sent the royalty payment/// @return royaltyAmount - the royalty payment amount for _salePricefunctionroyaltyInfo(uint256 _tokenId,
uint256 _salePrice
) externalviewreturns (address receiver,
uint256 royaltyAmount
);
}
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;import"@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import"@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol";
import"@openzeppelin/contracts/utils/Address.sol";
import"@openzeppelin/contracts/utils/Context.sol";
import"@openzeppelin/contracts/introspection/ERC165.sol";
import"@openzeppelin/contracts/math/SafeMath.sol";
/**
*
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/abstractcontractNFTAssetCollectionBaseisContext,
ERC165,
IERC1155,
IERC1155MetadataURI{
usingSafeMathforuint256;
usingAddressforaddress;
// Mapping from token ID to account balancesmapping(uint256=>mapping(address=>uint256)) private _balances;
// Mapping from account to operator approvalsmapping(address=>mapping(address=>bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.jsonstringinternal _uri;
/*
* bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
* bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
* bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
* bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
* bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
* bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
*
* => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
* 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
*/bytes4privateconstant _INTERFACE_ID_ERC1155 =0xd9b67a26;
/*
* bytes4(keccak256('uri(uint256)')) == 0x0e89341c
*/bytes4privateconstant _INTERFACE_ID_ERC1155_METADATA_URI =0x0e89341c;
/**
* @dev See {_setURI}.
*/constructor(stringmemory uri_) {
_setURI(uri_);
// register the supported interfaces to conform to ERC1155 via ERC165
_registerInterface(_INTERFACE_ID_ERC1155);
// register the supported interfaces to conform to ERC1155MetadataURI via ERC165
_registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/functionbalanceOf(address account, uint256 id)
publicviewvirtualoverridereturns (uint256)
{
_checkNotZeroAddress(account);
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/functionbalanceOfBatch(address[] memory accounts, uint256[] memory ids)
publicviewvirtualoverridereturns (uint256[] memory)
{
_checkArrayLengths(accounts.length, ids.length);
uint256[] memory batchBalances =newuint256[](accounts.length);
for (uint256 i =0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/functionsetApprovalForAll(address operator, bool approved)
publicvirtualoverride{
require(_msgSender() != operator, "operator must not be sender");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/functionisApprovedForAll(address account, address operator)
publicviewvirtualoverridereturns (bool)
{
return _operatorApprovals[account][operator];
}
function_safeTransferFrom(addressfrom,
address to,
uint256 id,
uint256 amount,
bytesmemory data
) internal{
_checkNotZeroAddress(to);
address operator = _msgSender();
_balances[id][from] = _balances[id][from].sub(
amount,
_insufficientBalanceErrorMessage()
);
_balances[id][to] = _balances[id][to].add(amount);
emit TransferSingle(operator, from, to, id, amount);
_doSafeTransferAcceptanceCheck(
operator,
from,
to,
id,
amount,
data
);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/functionsafeBatchTransferFrom(addressfrom,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytesmemory data
) publicvirtualoverride{
_checkArrayLengths(ids.length, amounts.length);
_checkNotZeroAddress(to);
// _checkTransferIsApproved(from);address operator = _msgSender();
for (uint256 i =0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
_balances[id][from] = _balances[id][from].sub(
amount,
_insufficientBalanceErrorMessage()
);
_balances[id][to] = _balances[id][to].add(amount);
}
emit TransferBatch(operator, from, to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(
operator,
from,
to,
ids,
amounts,
data
);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/function_setURI(stringmemory newuri) internalvirtual{
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - If `account` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/function_mint(address account,
uint256 id,
uint256 amount,
bytesmemory data
) internalvirtual{
_checkNotZeroAddress(account);
address operator = _msgSender();
_balances[id][account] = _balances[id][account].add(amount);
emit TransferSingle(operator, address(0), account, id, amount);
_doSafeTransferAcceptanceCheck(
operator,
address(0),
account,
id,
amount,
data
);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* 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.
*/function_mintBatch(address to,
uint256[] memory ids,
uint256[] memory amounts,
bytesmemory data
) internalvirtual{
_checkNotZeroAddress(to);
_checkArrayLengths(ids.length, amounts.length);
address operator = _msgSender();
for (uint256 i =0; i < ids.length; i++) {
_balances[ids[i]][to] = _balances[ids[i]][to].add(amounts[i]);
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_doSafeBatchTransferAcceptanceCheck(
operator,
address(0),
to,
ids,
amounts,
data
);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `account`
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens of token type `id`.
*/function_burn(address account,
uint256 id,
uint256 amount
) internalvirtual{
_checkNotZeroAddress(account);
_balances[id][account] = _balances[id][account].sub(
amount,
_insufficientBalanceErrorMessage()
);
emit TransferSingle(_msgSender(), account, address(0), id, amount);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/function_burnBatch(address account,
uint256[] memory ids,
uint256[] memory amounts
) internalvirtual{
_checkNotZeroAddress(account);
_checkArrayLengths(ids.length, amounts.length);
for (uint256 i =0; i < ids.length; i++) {
_balances[ids[i]][account] = _balances[ids[i]][account].sub(
amounts[i],
_insufficientBalanceErrorMessage()
);
}
emit TransferBatch(_msgSender(), account, address(0), ids, amounts);
}
function_doSafeTransferAcceptanceCheck(address operator,
addressfrom,
address to,
uint256 id,
uint256 amount,
bytesmemory data
) private{
if (to.isContract()) {
try
IERC1155Receiver(to).onERC1155Received(
operator,
from,
id,
amount,
data
)
returns (bytes4 response) {
if (
response != IERC1155Receiver(to).onERC1155Received.selector
) {
_revertTokenRejected();
}
} catchError(stringmemory reason) {
revert(reason);
} catch {
_revertNotERC1155Receiver();
}
}
}
function_doSafeBatchTransferAcceptanceCheck(address operator,
addressfrom,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytesmemory data
) private{
if (to.isContract()) {
try
IERC1155Receiver(to).onERC1155BatchReceived(
operator,
from,
ids,
amounts,
data
)
returns (bytes4 response) {
if (
response !=
IERC1155Receiver(to).onERC1155BatchReceived.selector
) {
_revertTokenRejected();
}
} catchError(stringmemory reason) {
revert(reason);
} catch {
_revertNotERC1155Receiver();
}
}
}
function_checkArrayLengths(uint256 _array1Length, uint256 _array2Length)
privatepure{
require(_array1Length == _array2Length, "Array length mismatch");
}
function_checkNotZeroAddress(address _adr) internalpure{
require(_adr !=address(0), "Zero address");
}
function_revertNotERC1155Receiver() internalpure{
revert("Transfer to non ERC1155Receiver");
}
function_revertTokenRejected() internalpure{
revert("ERC1155Receiver rejected tokens");
}
function_insufficientBalanceErrorMessage()
internalpurereturns (stringmemory)
{
return"Insufficient balance";
}
// s
}
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;import"../base/NFTAssetCollection.sol";
abstractcontractNFTAssetCollectionCappedisNFTAssetCollection{
usingSafeMathforuint256;
uint256private _collectionCap;
/**
* @dev Sets the value of the `cap`. This value is immutable, it can only be
* set once during construction. If cap is 0, the NFTCollection is not capped.
*/constructor(uint256 collectionCap_) {
_collectionCap = collectionCap_;
}
/**
* @dev Returns the cap of the collection.
*/functioncollectionCap() publicviewvirtualreturns (uint256) {
return _collectionCap;
}
/**
* @dev Overrides NFTAssetCollection.createAsset. Checks if collection cap would be exceeded
*/functioncreateAsset(CreateAssetCommand calldata _cmd)
publicvirtualoverride{
if(_collectionCap !=0) _checkCollectionCap();
super.createAsset(_cmd);
}
/**
* @dev Checks if collection cap would be exceeded
*/function_checkCollectionCap() internalview{
require(
_assetIds.length.add(1) <= _collectionCap,
"Cap exceeded"
);
}
}
Contract Source Code
File 21 of 28: NFTAssetCollectionMintable.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;import"./NFTAssetCollectionCapped.sol";
abstractcontractNFTAssetCollectionMintableisNFTAssetCollectionCapped{
usingSafeMathforuint256;
mapping(string=>uint256) private _assetSupply;
mapping(uint256=>bool) internal _tokenAssetExists;
mapping(string=>mapping(address=>uint256)) private _assetAmountByUsers;
mapping(uint256=>uint256) internal _internalTokenIdToAssetIdIndex;
uint256public collectionMintLimit;
constructor(NFTCollectionData memory _data)
NFTAssetCollectionCapped(_data.collectionCap)
NFTAssetCollection(_data)
{
collectionMintLimit = _data.collectionMintLimit;
}
functionassetBalanceOf(stringmemory _assetId, address _to)
externalviewoverridereturns (NFTAssetBalance memory)
{
NFTAssetBalance memory assetBalance;
assetBalance.id = _assetId;
assetBalance.weight = _assets[_assetId].weight;
assetBalance.balance= _assetAmountByUsers[_assetId][_to];
return assetBalance;
}
functionassetBalanceBatchOf(address _to)
externalviewoverridereturns (NFTAssetBalance[] memory)
{
NFTAssetBalance[] memory assetBalances =new NFTAssetBalance[](
_assetIds.length
);
for (uint256 i =0; i < _assetIds.length; i++) {
assetBalances[i].id = _assetIds[i];
assetBalances[i].balance= _assetAmountByUsers[_assetIds[i]][_to];
assetBalances[i].weight = _assets[_assetIds[i]].weight;
}
return assetBalances;
}
functionbalanceOf(address _account,
stringmemory _assetId,
uint256 _tokenId
) publicviewreturns (uint256 balance) {
returnsuper.balanceOf(
_account,
calculateNftCollectionTokenId(_assetId, _tokenId)
);
}
functionbalanceOf(address _account, stringmemory _assetId)
publicviewreturns (uint256 balance)
{
return _assetAmountByUsers[_assetId][_account];
}
functionbalanceOfBatch(address[] memory _accounts,
stringmemory _assetId,
uint256[] memory _tokenIds
) publicviewreturns (uint256[] memory balances) {
uint256[] memory internalTokenIds =newuint256[](_tokenIds.length);
for (uint256 i =0; i < _tokenIds.length; i++) {
internalTokenIds[i] = calculateNftCollectionTokenId(
_assetId,
_tokenIds[i]
);
}
return balanceOfBatch(_accounts, internalTokenIds);
}
/**
* @dev Returns the total quantity for a asset ID
* @param _assetId string ID of the asset to query
* @return amount of asset in existence
*/functiontotalSupply(stringmemory _assetId) publicviewreturns (uint256) {
return _assetSupply[_assetId];
}
// TODO: revisarfunctionassetsOf(address _account)
externalviewreturns (string[] memory)
{
uint256 _numberOfAssetsOfAccount;
// first we need to iterate over all asset ids to calculate how big the resulting array needs to befor (uint256 i =0; i < _assetIds.length; i++) {
if (balanceOf(_account, _assetIds[i]) >0) {
_numberOfAssetsOfAccount = _numberOfAssetsOfAccount.add(1);
}
}
string[] memory _assetsOfAccount =newstring[](
_numberOfAssetsOfAccount
);
uint256 _assetsOfAccountIndex;
// now we iterate again over the asset ids to fill the resulting arrayfor (uint256 i =0; i < _assetIds.length; i++) {
if (balanceOf(_account, _assetIds[i]) >0) {
_assetsOfAccount[_assetsOfAccountIndex] = _assetIds[i];
_assetsOfAccountIndex = _assetsOfAccountIndex.add(1);
}
}
return _assetsOfAccount;
}
functionassetIdByInternalTokenId(uint256 _internalTokenId)
externalviewoverridereturns (stringmemory)
{
uint256 _assetIdIndex = _internalTokenIdToAssetIdIndex[
_internalTokenId
];
return _assetIds[_assetIdIndex];
}
function_mintAsset(address _to,
stringmemory _assetId,
uint256 _tokenId,
bytesmemory _data
) internalreturns (uint256 id, uint256 internalId) {
uint256 nftCollectionTokenId = calculateNftCollectionTokenId(
_assetId,
_tokenId
);
_checkTokenNotExist(nftCollectionTokenId);
_beforeAssetTokenTransfer(address(0), _to, _assetId, 1);
_internalTokenIdToAssetIdIndex[nftCollectionTokenId] = _assetIdToIndex[
_assetId
];
_tokenAssetExists[nftCollectionTokenId] =true;
_mint(_to, nftCollectionTokenId, 1, _data);
id = _tokenId;
internalId = nftCollectionTokenId;
emit NFTCollectionMint(_to, _assetId, _tokenId, nftCollectionTokenId);
}
function_mintBatchAsset(address _to,
stringmemory _assetId,
uint256[] memory _ids,
uint256[] memory _nftCollectionTokenIds,
uint256[] memory _quantities,
bytesmemory _data
) internalreturns (uint256[] memory, uint256[] memory) {
_mintBatch(_to, _nftCollectionTokenIds, _quantities, _data);
emit NFTCollectionMintBatch(
_to,
_assetId,
_ids,
_nftCollectionTokenIds
);
return (_ids, _nftCollectionTokenIds);
}
function_checkTokenNotExist(uint256 _nftCollectionTokenId) internalview{
require(!_tokenAssetExists[_nftCollectionTokenId], "Already minted");
}
function_checkCapNotExceeded(stringmemory _assetId,
uint256 _totalNewTokens
) internalview{
require(
totalSupply(_assetId).add(_totalNewTokens) <= _assets[_assetId].cap,
"Cap exceeded"
);
}
function_beforeAssetTokenTransfer(addressfrom,
address to,
stringmemory assetId,
uint256 amount
) internalvirtualoverride{
super._beforeAssetTokenTransfer(from, to, assetId, amount);
// burnif (to ==address(0)) {
_decreaseBalances(assetId, from, amount);
}
// mintif (from==address(0)) {
_onlyMinter();
_checkCollectionMintLimit(to, amount);
_increaseBalances(assetId, to, amount);
}
// transferif (from!=address(0) && to !=address(0)) {
_checkTransferIsApproved(from);
// decrease sender
_decreaseBalances(assetId, from, amount);
// increase receiver
_increaseBalances(assetId, to, amount);
}
}
function_decreaseBalances(stringmemory assetId,
addressfrom,
uint256 amount
) private{
_assetAmountByUsers[assetId][from] = _assetAmountByUsers[assetId][from]
.sub(amount, _insufficientBalanceErrorMessage());
_assetSupply[assetId] = _assetSupply[assetId].sub(
amount,
_insufficientBalanceErrorMessage()
);
}
function_increaseBalances(stringmemory assetId,
address to,
uint256 amount
) private{
_checkCapNotExceeded(assetId, amount);
_assetAmountByUsers[assetId][to] = _assetAmountByUsers[assetId][to].add(
amount
);
_assetSupply[assetId] = _assetSupply[assetId].add(amount);
}
function_checkCollectionMintLimit(address _to, uint256 _amount) privateview{
if (collectionMintLimit ==0) {
return;
}
uint256 accumulatedBalance;
for (uint256 i =0; i < _assetIds.length; i++) {
accumulatedBalance = accumulatedBalance.add(
_assetAmountByUsers[_assetIds[i]][_to]
);
}
require(accumulatedBalance.add(_amount) <= collectionMintLimit, "Mint limit reached");
}
}
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;import"./extensions/NFTAssetCollectionPausable.sol";
import"./extensions/NFTAssetCollectionBurnable.sol";
import"./extensions/NFTAssetCollectionRoyaltyFee.sol";
import"./extensions/NFTAssetCollectionMintable.sol";
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*
* _Available since v3.1._
*/abstractcontractNFTCollectionisNFTAssetCollectionPausable,
NFTAssetCollectionBurnable,
NFTAssetCollectionRoyaltyFee,
NFTAssetCollectionMintable{
usingSafeMathforuint256;
//solhint-disable no-empty-blocksconstructor(NFTCollectionData memory _data)
NFTAssetCollectionMintable(_data)
{}
functioncreateAsset(CreateAssetCommand calldata _cmd)
publicoverride(
NFTAssetCollection,
NFTAssetCollectionRoyaltyFee,
NFTAssetCollectionCapped
)
{
super.createAsset(_cmd);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/functionuri(uint256 nftCollectionId)
publicviewoverridereturns (stringmemory)
{
uint256 assetIdIndex = _internalTokenIdToAssetIdIndex[nftCollectionId];
stringmemory assetId = _assetIds[assetIdIndex];
stringmemory assetUri = _assets[assetId].uri;
if (!_isEmptyString(assetUri)) {
return assetUri;
}
returnstring(abi.encodePacked(_uri, "/", assetId));
}
functionauthorizeAssetBurner(address _burner)
publicvirtualoverride(IDATSNFTCollection, NFTAssetCollectionBurnable)
returns (bool)
{
returnsuper.authorizeAssetBurner(_burner);
}
functionburn(address _account,
stringmemory _assetId,
uint256 _tokenId
) publicoverride(NFTAssetCollectionBurnable, IDATSNFTCollection) {
uint256 nftCollectionTokenId = calculateNftCollectionTokenId(
_assetId,
_tokenId
);
_beforeAssetTokenTransfer(_account, address(0), _assetId, 1);
super.burn(_account, _assetId, _tokenId);
emit NFTCollectionBurn(
_account,
_assetId,
_tokenId,
nftCollectionTokenId
);
}
functionburnBatch(address _account,
stringmemory _assetId,
uint256[] memory _tokenIds
) publicoverride(NFTAssetCollectionBurnable, IDATSNFTCollection) {
uint256[] memory nftCollectionTokenIds =newuint256[](
_tokenIds.length
);
_beforeAssetTokenTransfer(
_account,
address(0),
_assetId,
_tokenIds.length
);
for (uint256 i =0; i < _tokenIds.length; i++) {
nftCollectionTokenIds[i] = calculateNftCollectionTokenId(
_assetId,
_tokenIds[i]
);
}
super.burnBatch(_account, _assetId, _tokenIds);
emit NFTCollectionBurnBatch(
_account,
_assetId,
_tokenIds,
nftCollectionTokenIds
);
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/functionsafeTransferFrom(address _from,
address _to,
uint256 _nftCollectionTokenId,
uint256 _amount,
bytesmemory _data
) publicoverride{
require(_amount ==1, "amount not 1");
uint256 _assetIdIndex = _internalTokenIdToAssetIdIndex[
_nftCollectionTokenId
];
_beforeAssetTokenTransfer(_from, _to, _assetIds[_assetIdIndex], 1);
_safeTransferFrom(_from, _to, _nftCollectionTokenId, 1, _data);
}
functionsafeTransferFrom(address _from,
address _to,
stringmemory _assetId,
uint256 _tokenId,
bytesmemory _data
) publicoverride{
_beforeAssetTokenTransfer(_from, _to, _assetId, 1);
uint256 nftCollectionTokenId = calculateNftCollectionTokenId(
_assetId,
_tokenId
);
_safeTransferFrom(_from, _to, nftCollectionTokenId, 1, _data);
emit NFTCollectionTransfer(
_from,
_to,
_assetId,
_tokenId,
nftCollectionTokenId
);
}
functionsafeBatchTransferFrom(address _from,
address _to,
stringmemory _assetId,
uint256[] memory _tokenIds,
bytesmemory _data
) publicoverride{
_beforeAssetTokenTransfer(_from, _to, _assetId, _tokenIds.length);
uint256[] memory nftCollectionTokenIds =newuint256[](
_tokenIds.length
);
uint256[] memory amounts =newuint256[](_tokenIds.length);
for (uint256 i =0; i < _tokenIds.length; i++) {
nftCollectionTokenIds[i] = calculateNftCollectionTokenId(
_assetId,
_tokenIds[i]
);
amounts[i] =1;
}
super.safeBatchTransferFrom(
_from,
_to,
nftCollectionTokenIds,
amounts,
_data
);
emit NFTCollectionTransferBatch(
_from,
_to,
_assetId,
_tokenIds,
nftCollectionTokenIds
);
}
functionsafeBatchTransferFrom(addressfrom,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytesmemory data
) publicoverride{
_checkNotPaused();
_checkTransferIsApproved(from);
super.safeBatchTransferFrom(from, to, ids, amounts, data);
}
functionwithdraw(NFTCollectionWithdrawCommand calldata withdrawCommand)
externaloverride{
safeTransferFrom(
withdrawCommand.from,
withdrawCommand.to,
withdrawCommand.assetId,
withdrawCommand.tokenId,
bytes("")
);
emit Withdraw(
withdrawCommand.operationId,
withdrawCommand.from,
withdrawCommand.to,
withdrawCommand.assetId,
withdrawCommand.tokenId
);
}
function_beforeAssetTokenTransfer(addressfrom,
address to,
stringmemory assetId,
uint256 amount
)
internalvirtualoverride(
NFTAssetCollection,
NFTAssetCollectionPausable,
NFTAssetCollectionBurnable,
NFTAssetCollectionMintable
)
{
super._beforeAssetTokenTransfer(from, to, assetId, amount);
}
}
Contract Source Code
File 25 of 28: NFTCollectionAutoId.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.7.5;pragmaexperimentalABIEncoderV2;import"./NFTCollection.sol";
/**
* @dev Extension of {ERC1155} that allows token holders to destroy both their
* own tokens and those that they have been approved to use.
*
* _Available since v3.1._
*/contractNFTCollectionAutoIdisNFTCollection{
usingSafeMathforuint256;
mapping(string=>uint256) internal _tokenIdsTracker;
//solhint-disable no-empty-blocksconstructor(NFTCollectionData memory _data) NFTCollection(_data) {}
functionisAutoIncrementalCollection()
externalpureoverridereturns (bool)
{
returntrue;
}
/**
* @dev Mints some amount of assets to an address
* @param _to Address of the future owner of the asset
* @param _assetId ID of the asset
* @param _data Data to pass if receiver is contract
*/functionmint(address _to,
stringmemory _assetId,
bytesmemory _data
) externalvirtualoverridereturns (uint256 id, uint256 internalId) {
_checkAssetExists(_assetId);
uint256 tokenId = _tokenIdsTracker[_assetId];
_tokenIdsTracker[_assetId] = _tokenIdsTracker[_assetId].add(1);
return _mintAsset(_to, _assetId, tokenId, _data);
}
/**
* @dev Mint assets for each id in _ids
* @param _to The address to mint assets to
* @param _assetId Id of the asset where new tokens will be minted
* @param _totalTokens Total of new tokens to mint
* @param _data Data to pass if receiver is contract
*/functionmintBatch(address _to,
stringmemory _assetId,
uint256 _totalTokens,
bytesmemory _data
)
publicvirtualreturns (uint256[] memory ids, uint256[] memory internalIds)
{
_checkAssetExists(_assetId);
_beforeAssetTokenTransfer(address(0), _to, _assetId, _totalTokens);
uint256[] memory nftCollectionTokenIds =newuint256[](_totalTokens);
uint256[] memory quantities =newuint256[](_totalTokens);
uint256[] memory tokenIds =newuint256[](_totalTokens);
for (uint256 i =0; i < _totalTokens; i++) {
tokenIds[i] = _tokenIdsTracker[_assetId];
nftCollectionTokenIds[i] = calculateNftCollectionTokenId(
_assetId,
tokenIds[i]
);
_tokenAssetExists[nftCollectionTokenIds[i]] =true;
quantities[i] =1;
_tokenIdsTracker[_assetId] = _tokenIdsTracker[_assetId].add(1);
}
return
_mintBatchAsset(
_to,
_assetId,
tokenIds,
nftCollectionTokenIds,
quantities,
_data
);
}
// solhint-disable no-unused-varsfunctionmint(address _to,
stringmemory _assetId,
uint256 _tokenId,
bytesmemory _data
) externaloverridereturns (uint256 id, uint256 internalId) {
revert("not supported");
}
function_beforeAssetTokenTransfer(addressfrom,
address to,
stringmemory assetId,
uint256 amount
) internalvirtualoverride{
super._beforeAssetTokenTransfer(from, to, assetId, amount);
}
}
Contract Source Code
File 26 of 28: Pausable.sol
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;import"./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 () internal{
_paused =false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/functionpaused() publicviewvirtualreturns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/modifierwhenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/modifierwhenPaused() {
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());
}
}
// SPDX-License-Identifier: MITpragmasolidity >=0.6.0 <0.8.0;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
if (b ==0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
if (a ==0) return0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
require(b >0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
return a % b;
}
}