commit d2a9f00959466375f1f426a6954ed06ef4dd76fa Author: Jason Date: Tue Nov 8 17:43:45 2022 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..90157b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/node_modules +.DS_Store \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..41df0a6 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "name": "solidities", + "version": "1.0.0", + "main": "index.js", + "author": "Jason.Chen", + "license": "MIT", + "dependencies": { + "@openzeppelin/contracts": "^4.7.3" + } +} \ No newline at end of file diff --git a/src/ERC1155/JZBG-COMPLIE.sol b/src/ERC1155/JZBG-COMPLIE.sol new file mode 100644 index 0000000..8643adc --- /dev/null +++ b/src/ERC1155/JZBG-COMPLIE.sol @@ -0,0 +1,1114 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +abstract contract Symbolable { + string private _name; + + string private _symbol; + + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + function name() public view virtual returns (string memory) { + return _name; + } + + function symbol() public view virtual returns (string memory) { + return _symbol; + } +} + +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } +} + +interface IERC165 { + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} + +abstract contract ERC165 is IERC165 { + /** + * @dev See {IERC165-supportsInterface}. + */ + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override + returns (bool) + { + return interfaceId == type(IERC165).interfaceId; + } +} + +interface IERC1155 is IERC165 { + event TransferSingle( + address indexed operator, + address indexed from, + address indexed to, + uint256 id, + uint256 value + ); + + event TransferBatch( + address indexed operator, + address indexed from, + address indexed to, + uint256[] ids, + uint256[] values + ); + + event ApprovalForAll( + address indexed account, + address indexed operator, + bool approved + ); + + event URI(string value, uint256 indexed id); + + function balanceOf(address account, uint256 id) + external + view + returns (uint256); + + function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) + external + view + returns (uint256[] memory); + + function setApprovalForAll(address operator, bool approved) external; + + function isApprovedForAll(address account, address operator) + external + view + returns (bool); + + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes calldata data + ) external; + + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) external; +} + +interface IERC1155MetadataURI is IERC1155 { + function uri(uint256 id) external view returns (string memory); +} + +library Address { + function isContract(address account) internal view returns (bool) { + return account.code.length > 0; + } + + function sendValue(address payable 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" + ); + } + + function functionCall(address target, bytes memory data) + internal + returns (bytes memory) + { + return functionCall(target, data, "Address: low-level call failed"); + } + + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0, errorMessage); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return + functionCallWithValue( + target, + data, + value, + "Address: low-level call with value failed" + ); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + require( + address(this).balance >= value, + "Address: insufficient balance for call" + ); + require(isContract(target), "Address: call to non-contract"); + + (bool success, bytes memory returndata) = target.call{value: value}( + data + ); + return verifyCallResult(success, returndata, errorMessage); + } + + function functionStaticCall(address target, bytes memory data) + internal + view + returns (bytes memory) + { + return + functionStaticCall( + target, + data, + "Address: low-level static call failed" + ); + } + + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { + require(isContract(target), "Address: static call to non-contract"); + + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + function functionDelegateCall(address target, bytes memory data) + internal + returns (bytes memory) + { + return + functionDelegateCall( + target, + data, + "Address: low-level delegate call failed" + ); + } + + function functionDelegateCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + require(isContract(target), "Address: delegate call to non-contract"); + + (bool success, bytes memory returndata) = target.delegatecall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { + if (success) { + return returndata; + } else { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } + } +} + +interface IERC1155Receiver is IERC165 { + function onERC1155Received( + address operator, + address from, + uint256 id, + uint256 value, + bytes calldata data + ) external returns (bytes4); + + function onERC1155BatchReceived( + address operator, + address from, + uint256[] calldata ids, + uint256[] calldata values, + bytes calldata data + ) external returns (bytes4); +} + +abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC165, IERC165) + returns (bool) + { + return + interfaceId == type(IERC1155Receiver).interfaceId || + super.supportsInterface(interfaceId); + } +} + +contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { + using Address for address; + + mapping(uint256 => mapping(address => uint256)) private _balances; + + mapping(address => mapping(address => bool)) private _operatorApprovals; + + string private _uri; + + constructor(string memory uri_) { + _setURI(uri_); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC165, IERC165) + returns (bool) + { + return + interfaceId == type(IERC1155).interfaceId || + interfaceId == type(IERC1155MetadataURI).interfaceId || + super.supportsInterface(interfaceId); + } + + function uri(uint256) public view virtual override returns (string memory) { + return _uri; + } + + function balanceOf(address account, uint256 id) + public + view + virtual + override + returns (uint256) + { + require( + account != address(0), + "ERC1155: address zero is not a valid owner" + ); + return _balances[id][account]; + } + + function balanceOfBatch(address[] memory accounts, uint256[] memory ids) + public + view + virtual + override + returns (uint256[] memory) + { + require( + accounts.length == ids.length, + "ERC1155: accounts and ids length mismatch" + ); + + uint256[] memory batchBalances = new uint256[](accounts.length); + + for (uint256 i = 0; i < accounts.length; ++i) { + batchBalances[i] = balanceOf(accounts[i], ids[i]); + } + + return batchBalances; + } + + function setApprovalForAll(address operator, bool approved) + public + virtual + override + { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function isApprovedForAll(address account, address operator) + public + view + virtual + override + returns (bool) + { + return _operatorApprovals[account][operator]; + } + + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) public virtual override { + require( + from == _msgSender() || isApprovedForAll(from, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + _safeTransferFrom(from, to, id, amount, data); + } + + function safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) public virtual override { + require( + from == _msgSender() || isApprovedForAll(from, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + _safeBatchTransferFrom(from, to, ids, amounts, data); + } + + function _safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) internal virtual { + require(to != address(0), "ERC1155: transfer to the zero address"); + + address operator = _msgSender(); + uint256[] memory ids = _asSingletonArray(id); + uint256[] memory amounts = _asSingletonArray(amount); + + _beforeTokenTransfer(operator, from, to, ids, amounts, data); + + uint256 fromBalance = _balances[id][from]; + require( + fromBalance >= amount, + "ERC1155: insufficient balance for transfer" + ); + unchecked { + _balances[id][from] = fromBalance - amount; + } + _balances[id][to] += amount; + + emit TransferSingle(operator, from, to, id, amount); + + _afterTokenTransfer(operator, from, to, ids, amounts, data); + + _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); + } + + function _safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual { + require( + ids.length == amounts.length, + "ERC1155: ids and amounts length mismatch" + ); + require(to != address(0), "ERC1155: transfer to the zero address"); + + address operator = _msgSender(); + + _beforeTokenTransfer(operator, from, to, ids, amounts, data); + + for (uint256 i = 0; i < ids.length; ++i) { + uint256 id = ids[i]; + uint256 amount = amounts[i]; + + uint256 fromBalance = _balances[id][from]; + require( + fromBalance >= amount, + "ERC1155: insufficient balance for transfer" + ); + unchecked { + _balances[id][from] = fromBalance - amount; + } + _balances[id][to] += amount; + } + + emit TransferBatch(operator, from, to, ids, amounts); + + _afterTokenTransfer(operator, from, to, ids, amounts, data); + + _doSafeBatchTransferAcceptanceCheck( + operator, + from, + to, + ids, + amounts, + data + ); + } + + function _setURI(string memory newuri) internal virtual { + _uri = newuri; + } + + function _mint( + address to, + uint256 id, + uint256 amount, + bytes memory data + ) internal virtual { + require(to != address(0), "ERC1155: mint to the zero address"); + + address operator = _msgSender(); + uint256[] memory ids = _asSingletonArray(id); + uint256[] memory amounts = _asSingletonArray(amount); + + _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); + + _balances[id][to] += amount; + emit TransferSingle(operator, address(0), to, id, amount); + + _afterTokenTransfer(operator, address(0), to, ids, amounts, data); + + _doSafeTransferAcceptanceCheck( + operator, + address(0), + to, + id, + amount, + data + ); + } + + function _mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual { + require(to != address(0), "ERC1155: mint to the zero address"); + require( + ids.length == amounts.length, + "ERC1155: ids and amounts length mismatch" + ); + + address operator = _msgSender(); + + _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); + + for (uint256 i = 0; i < ids.length; i++) { + _balances[ids[i]][to] += amounts[i]; + } + + emit TransferBatch(operator, address(0), to, ids, amounts); + + _afterTokenTransfer(operator, address(0), to, ids, amounts, data); + + _doSafeBatchTransferAcceptanceCheck( + operator, + address(0), + to, + ids, + amounts, + data + ); + } + + function _burn( + address from, + uint256 id, + uint256 amount + ) internal virtual { + require(from != address(0), "ERC1155: burn from the zero address"); + + address operator = _msgSender(); + uint256[] memory ids = _asSingletonArray(id); + uint256[] memory amounts = _asSingletonArray(amount); + + _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); + + uint256 fromBalance = _balances[id][from]; + require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); + unchecked { + _balances[id][from] = fromBalance - amount; + } + + emit TransferSingle(operator, from, address(0), id, amount); + + _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); + } + + function _burnBatch( + address from, + uint256[] memory ids, + uint256[] memory amounts + ) internal virtual { + require(from != address(0), "ERC1155: burn from the zero address"); + require( + ids.length == amounts.length, + "ERC1155: ids and amounts length mismatch" + ); + + address operator = _msgSender(); + + _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); + + for (uint256 i = 0; i < ids.length; i++) { + uint256 id = ids[i]; + uint256 amount = amounts[i]; + + uint256 fromBalance = _balances[id][from]; + require( + fromBalance >= amount, + "ERC1155: burn amount exceeds balance" + ); + unchecked { + _balances[id][from] = fromBalance - amount; + } + } + + emit TransferBatch(operator, from, address(0), ids, amounts); + + _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); + } + + function _setApprovalForAll( + address owner, + address operator, + bool approved + ) internal virtual { + require(owner != operator, "ERC1155: setting approval status for self"); + _operatorApprovals[owner][operator] = approved; + emit ApprovalForAll(owner, operator, approved); + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual {} + + function _afterTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual {} + + function _doSafeTransferAcceptanceCheck( + address operator, + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) private { + if (to.isContract()) { + try + IERC1155Receiver(to).onERC1155Received( + operator, + from, + id, + amount, + data + ) + returns (bytes4 response) { + if (response != IERC1155Receiver.onERC1155Received.selector) { + revert("ERC1155: ERC1155Receiver rejected tokens"); + } + } catch Error(string memory reason) { + revert(reason); + } catch { + revert("ERC1155: transfer to non ERC1155Receiver implementer"); + } + } + } + + function _doSafeBatchTransferAcceptanceCheck( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) private { + if (to.isContract()) { + try + IERC1155Receiver(to).onERC1155BatchReceived( + operator, + from, + ids, + amounts, + data + ) + returns (bytes4 response) { + if ( + response != IERC1155Receiver.onERC1155BatchReceived.selector + ) { + revert("ERC1155: ERC1155Receiver rejected tokens"); + } + } catch Error(string memory reason) { + revert(reason); + } catch { + revert("ERC1155: transfer to non ERC1155Receiver implementer"); + } + } + } + + function _asSingletonArray(uint256 element) + private + pure + returns (uint256[] memory) + { + uint256[] memory array = new uint256[](1); + array[0] = element; + + return array; + } +} + +abstract contract ERC1155Burnable is ERC1155 { + function burn( + address account, + uint256 id, + uint256 value + ) public virtual { + require( + account == _msgSender() || isApprovedForAll(account, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + + _burn(account, id, value); + } + + function burnBatch( + address account, + uint256[] memory ids, + uint256[] memory values + ) public virtual { + require( + account == _msgSender() || isApprovedForAll(account, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + + _burnBatch(account, ids, values); + } +} + +abstract contract Pausable is Context { + event Paused(address account); + + event Unpaused(address account); + + bool private _paused; + + constructor() { + _paused = false; + } + + modifier whenNotPaused() { + _requireNotPaused(); + _; + } + + modifier whenPaused() { + _requirePaused(); + _; + } + + function paused() public view virtual returns (bool) { + return _paused; + } + + function _requireNotPaused() internal view virtual { + require(!paused(), "Pausable: paused"); + } + + function _requirePaused() internal view virtual { + require(paused(), "Pausable: not paused"); + } + + function _pause() internal virtual whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + function _unpause() internal virtual whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } +} + +abstract contract ERC1155Pausable is ERC1155, Pausable { + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual override { + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); + + require(!paused(), "ERC1155Pausable: token transfer while paused"); + } +} + +abstract contract ERC1155Supply is ERC1155 { + mapping(uint256 => uint256) private _totalSupply; + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + function exists(uint256 id) public view virtual returns (bool) { + return ERC1155Supply.totalSupply(id) > 0; + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual override { + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); + + if (from == address(0)) { + for (uint256 i = 0; i < ids.length; ++i) { + _totalSupply[ids[i]] += amounts[i]; + } + } + + if (to == address(0)) { + for (uint256 i = 0; i < ids.length; ++i) { + uint256 id = ids[i]; + uint256 amount = amounts[i]; + uint256 supply = _totalSupply[id]; + require( + supply >= amount, + "ERC1155: burn amount exceeds totalSupply" + ); + unchecked { + _totalSupply[id] = supply - amount; + } + } + } + } +} + +library Strings { + bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; + uint8 private constant _ADDRESS_LENGTH = 20; + + function toString(uint256 value) internal pure returns (string memory) { + if (value == 0) { + return "0"; + } + uint256 temp = value; + uint256 digits; + while (temp != 0) { + digits++; + temp /= 10; + } + bytes memory buffer = new bytes(digits); + while (value != 0) { + digits -= 1; + buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); + value /= 10; + } + return string(buffer); + } + + function toHexString(uint256 value) internal pure returns (string memory) { + if (value == 0) { + return "0x00"; + } + uint256 temp = value; + uint256 length = 0; + while (temp != 0) { + length++; + temp >>= 8; + } + return toHexString(value, length); + } + + function toHexString(uint256 value, uint256 length) + internal + pure + returns (string memory) + { + bytes memory buffer = new bytes(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"); + return string(buffer); + } + + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); + } +} + +abstract contract ERC1155URIStorage is ERC1155 { + using Strings for uint256; + + string private _baseURI = ""; + + mapping(uint256 => string) private _tokenURIs; + + function uri(uint256 tokenId) + public + view + virtual + override + returns (string memory) + { + string memory tokenURI = _tokenURIs[tokenId]; + + return + bytes(tokenURI).length > 0 + ? string(abi.encodePacked(_baseURI, tokenURI)) + : super.uri(tokenId); + } + + function _setURI(uint256 tokenId, string memory tokenURI) internal virtual { + _tokenURIs[tokenId] = tokenURI; + emit URI(uri(tokenId), tokenId); + } + + function _setBaseURI(string memory baseURI) internal virtual { + _baseURI = baseURI; + } +} + +abstract contract Ownable is Context { + address private _owner; + + event OwnershipTransferred( + address indexed previousOwner, + address indexed newOwner + ); + + constructor() { + _transferOwnership(_msgSender()); + } + + modifier onlyOwner() { + _checkOwner(); + _; + } + + function owner() public view virtual returns (address) { + return _owner; + } + + function _checkOwner() internal view virtual { + require(owner() == _msgSender(), "Ownable: caller is not the owner"); + } + + function renounceOwnership() public virtual onlyOwner { + _transferOwnership(address(0)); + } + + function transferOwnership(address newOwner) public virtual onlyOwner { + require( + newOwner != address(0), + "Ownable: new owner is the zero address" + ); + _transferOwnership(newOwner); + } + + function _transferOwnership(address newOwner) internal virtual { + address oldOwner = _owner; + _owner = newOwner; + emit OwnershipTransferred(oldOwner, newOwner); + } +} + +contract JZBG1155 is + ERC1155, + ERC1155Burnable, + ERC1155Pausable, + ERC1155Supply, + ERC1155URIStorage, + Ownable, + Symbolable +{ + using Strings for uint256; + + constructor( + string memory name_, + string memory symbol_, + string memory uri_ + ) Symbolable(name_, symbol_) ERC1155(uri_) { + ERC1155URIStorage._setBaseURI(uri_); + } + + function setURI(uint256 tokenId, string memory tokenURI) + public + virtual + onlyOwner + { + _setURI(tokenId, tokenURI); + } + + function setBaseURI(string memory baseURI) public virtual onlyOwner { + _setBaseURI(baseURI); + } + + function renounceOwnership() public virtual override onlyOwner {} + + function mint( + address to_, + uint256 tokenId_, + uint256 amount_, + string memory uri_ + ) public virtual onlyOwner { + _mint(to_, tokenId_, amount_, ""); + if (bytes(uri_).length > 0) { + _setURI(tokenId_, uri_); + } + } + + function bacthAddressMint( + address to_, + uint256[] memory tokenIds_, + uint256[] memory amounts_, + string[] memory uris_ + ) public virtual { + require( + tokenIds_.length == amounts_.length, + "The tokenIds and Amounts are not match" + ); + + if (uris_.length > 0) { + require( + tokenIds_.length == uris_.length, + "The ids and uris are not match" + ); + } + + _mintBatch(to_, tokenIds_, amounts_, ""); + + if (uris_.length > 0) { + for (uint256 i = 0; i < tokenIds_.length; i++) { + _setURI(tokenIds_[i], uris_[i]); + } + } + } + + function batchAddressesMint( + address[] memory tos_, + uint256 tokenId_, + uint256 amount_, + string memory uri_ + ) public virtual { + for (uint256 i = 0; i < tos_.length; i++) { + _mint(tos_[i], tokenId_, amount_, ""); + } + + if (bytes(uri_).length > 0) { + _setURI(tokenId_, uri_); + } + } + + function safeTransferToAddresses( + address from_, + address[] memory tos_, + uint256 tokenId_, + uint256 amount_ + ) public virtual { + require( + from_ == _msgSender() || isApprovedForAll(from_, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + + uint256 fromBalance = balanceOf(from_, tokenId_); + require( + fromBalance >= amount_ * tos_.length, + "ERC1155: insufficient balance for transfer" + ); + + for (uint256 i = 0; i < tos_.length; i++) { + _safeTransferFrom(from_, tos_[i], tokenId_, amount_, ""); + } + } + + function pause() public virtual whenNotPaused onlyOwner { + _pause(); + } + + function unpause() public virtual whenPaused onlyOwner { + _unpause(); + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual override(ERC1155, ERC1155Supply, ERC1155Pausable) { + ERC1155._beforeTokenTransfer(operator, from, to, ids, amounts, data); + ERC1155Pausable._beforeTokenTransfer( + operator, + from, + to, + ids, + amounts, + data + ); + ERC1155Supply._beforeTokenTransfer( + operator, + from, + to, + ids, + amounts, + data + ); + } + + function uri(uint256 tokenId) + public + view + virtual + override(ERC1155, ERC1155URIStorage) + returns (string memory) + { + return ERC1155URIStorage.uri(tokenId); + } +} diff --git a/src/ERC1155/JZBG-GOODS.sol b/src/ERC1155/JZBG-GOODS.sol new file mode 100644 index 0000000..a707bbf --- /dev/null +++ b/src/ERC1155/JZBG-GOODS.sol @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; +import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol"; +import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; +import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import "../common/Symbolable.sol"; + +contract JZBG1155 is + ERC1155, + ERC1155Burnable, + ERC1155Pausable, + ERC1155Supply, + ERC1155URIStorage, + Ownable, + Symbolable +{ + using Strings for uint256; + + /** + * @dev Jing Zhong Bao Guo,JZBG,https://jzbg.org/ + * 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4,1,1234 + * 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,1,1234567890 + * TRANSFER: 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,0x5B38Da6a701c568545dCfcB03FcB875f56beddC4,1,5,0x + * mintBatch: 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,[1,2,3,4],[100,2000,30000,400000] + * safeTransferToAddresses: 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,[0x5B38Da6a701c568545dCfcB03FcB875f56beddC4,0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db,0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB],1,200 + */ + constructor( + string memory name_, + string memory symbol_, + string memory uri_ + ) Symbolable(name_, symbol_) ERC1155(uri_) { + ERC1155URIStorage._setBaseURI(uri_); + } + + function setURI(uint256 tokenId, string memory tokenURI) + public + virtual + onlyOwner + { + _setURI(tokenId, tokenURI); + } + + function setBaseURI(string memory baseURI) public virtual onlyOwner { + _setBaseURI(baseURI); + } + + /** + * @dev 清空owner,重写了,防止误操作 + */ + function renounceOwnership() public virtual override onlyOwner {} + + /** + * @dev 增发 + */ + function mint( + address to_, + uint256 tokenId_, + uint256 amount_, + string memory uri_ + ) public virtual onlyOwner { + _mint(to_, tokenId_, amount_, ""); + if (bytes(uri_).length > 0) { + _setURI(tokenId_, uri_); + } + } + + /** + * @dev 批量增发 + */ + function bacthAddressMint( + address to_, + uint256[] memory tokenIds_, + uint256[] memory amounts_, + string[] memory uris_ + ) public virtual onlyOwner { + require( + tokenIds_.length == amounts_.length, + "The tokenIds and Amounts are not match" + ); + + if (uris_.length > 0) { + require( + tokenIds_.length == uris_.length, + "The ids and uris are not match" + ); + } + + _mintBatch(to_, tokenIds_, amounts_, ""); + + if (uris_.length > 0) { + for (uint256 i = 0; i < tokenIds_.length; i++) { + _setURI(tokenIds_[i], uris_[i]); + } + } + } + + /** + * @dev 批量给地址增发同一种代币 + */ + function batchAddressesMint( + address[] memory tos_, + uint256 tokenId_, + uint256 amount_, + string memory uri_ + ) public virtual onlyOwner { + for (uint256 i = 0; i < tos_.length; i++) { + _mint(tos_[i], tokenId_, amount_, ""); + } + + if (bytes(uri_).length > 0) { + _setURI(tokenId_, uri_); + } + } + + /** + * @dev See {IERC1155-safeBatchTransferFrom}. + */ + function safeTransferToAddresses( + address from_, + address[] memory tos_, + uint256 tokenId_, + uint256 amount_ + ) public virtual { + require( + from_ == _msgSender() || isApprovedForAll(from_, _msgSender()), + "ERC1155: caller is not token owner nor approved" + ); + + uint256 fromBalance = balanceOf(from_, tokenId_); + require( + fromBalance >= amount_ * tos_.length, + "ERC1155: insufficient balance for transfer" + ); + + for (uint256 i = 0; i < tos_.length; i++) { + _safeTransferFrom(from_, tos_[i], tokenId_, amount_, ""); + } + } + + /** + * @dev 暂停交易 + */ + function pause() public virtual whenNotPaused onlyOwner { + _pause(); + } + + /** + * @dev 恢复交易 + */ + function unpause() public virtual whenPaused onlyOwner { + _unpause(); + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual override(ERC1155, ERC1155Supply, ERC1155Pausable) { + ERC1155._beforeTokenTransfer(operator, from, to, ids, amounts, data); + ERC1155Pausable._beforeTokenTransfer( + operator, + from, + to, + ids, + amounts, + data + ); + ERC1155Supply._beforeTokenTransfer( + operator, + from, + to, + ids, + amounts, + data + ); + } + + function uri(uint256 tokenId) + public + view + virtual + override(ERC1155, ERC1155URIStorage) + returns (string memory) + { + return ERC1155URIStorage.uri(tokenId); + } +} diff --git a/src/ERC20/CZZX.sol b/src/ERC20/CZZX.sol new file mode 100644 index 0000000..4edc853 --- /dev/null +++ b/src/ERC20/CZZX.sol @@ -0,0 +1,754 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.0; + +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } +} + +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) + external + view + returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `from` to `to` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); +} + +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} + +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, with an overflow flag. + * + * _Available since v3.4._ + */ + function tryAdd(uint256 a, uint256 b) + internal + pure + returns (bool, uint256) + { + unchecked { + uint256 c = a + b; + if (c < a) return (false, 0); + return (true, c); + } + } + + /** + * @dev Returns the subtraction of two unsigned integers, with an overflow flag. + * + * _Available since v3.4._ + */ + function trySub(uint256 a, uint256 b) + internal + pure + returns (bool, uint256) + { + unchecked { + 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._ + */ + function tryMul(uint256 a, uint256 b) + internal + pure + returns (bool, uint256) + { + unchecked { + // 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/522 + if (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._ + */ + function tryDiv(uint256 a, uint256 b) + internal + pure + returns (bool, uint256) + { + unchecked { + 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._ + */ + function tryMod(uint256 a, uint256 b) + internal + pure + returns (bool, uint256) + { + unchecked { + 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. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + return a + b; + } + + /** + * @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. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return a - b; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on + * overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + return a * b; + } + + /** + * @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. + * + * Requirements: + * + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + 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. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + 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. + */ + function sub( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + unchecked { + 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. + * + * 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. + */ + function div( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + unchecked { + 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. + */ + function mod( + uint256 a, + uint256 b, + string memory errorMessage + ) internal pure returns (uint256) { + unchecked { + require(b > 0, errorMessage); + return a % b; + } + } +} + +contract ERC20 is Context, IERC20, IERC20Metadata { + mapping(address => uint256) private _balances; + + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * The default value of {decimals} is 18. To select a different value for + * {decimals} you should overload it. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual override returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual override returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the value {ERC20} uses, unless this function is + * overridden; + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual override returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) + public + view + virtual + override + returns (uint256) + { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address to, uint256 amount) + public + virtual + override + returns (bool) + { + address owner = _msgSender(); + _transfer(owner, to, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) + public + view + virtual + override + returns (uint256) + { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) + public + virtual + override + returns (bool) + { + address owner = _msgSender(); + _approve(owner, spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + * - the caller must have allowance for ``from``'s tokens of at least + * `amount`. + */ + function transferFrom( + address from, + address to, + uint256 amount + ) public virtual override returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, amount); + _transfer(from, to, amount); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) + public + virtual + returns (bool) + { + address owner = _msgSender(); + _approve(owner, spender, allowance(owner, spender) + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) + public + virtual + returns (bool) + { + address owner = _msgSender(); + uint256 currentAllowance = allowance(owner, spender); + require( + currentAllowance >= subtractedValue, + "ERC20: decreased allowance below zero" + ); + unchecked { + _approve(owner, spender, currentAllowance - subtractedValue); + } + + return true; + } + + /** + * @dev Moves `amount` of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `from` must have a balance of at least `amount`. + */ + function _transfer( + address from, + address to, + uint256 amount + ) internal virtual { + require(from != address(0), "ERC20: transfer from the zero address"); + require(to != address(0), "ERC20: transfer to the zero address"); + + _beforeTokenTransfer(from, to, amount); + + uint256 fromBalance = _balances[from]; + require( + fromBalance >= amount, + "ERC20: transfer amount exceeds balance" + ); + unchecked { + _balances[from] = fromBalance - amount; + // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by + // decrementing then incrementing. + _balances[to] += amount; + } + + emit Transfer(from, to, amount); + + _afterTokenTransfer(from, to, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply += amount; + unchecked { + // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. + _balances[account] += amount; + } + emit Transfer(address(0), account, amount); + + _afterTokenTransfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + uint256 accountBalance = _balances[account]; + require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); + unchecked { + _balances[account] = accountBalance - amount; + // Overflow not possible: amount <= accountBalance <= totalSupply. + _totalSupply -= amount; + } + + emit Transfer(account, address(0), amount); + + _afterTokenTransfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `amount`. + * + * Does not update the allowance amount in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Might emit an {Approval} event. + */ + function _spendAllowance( + address owner, + address spender, + uint256 amount + ) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + require( + currentAllowance >= amount, + "ERC20: insufficient allowance" + ); + unchecked { + _approve(owner, spender, currentAllowance - amount); + } + } + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} + + /** + * @dev Hook that is called after any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * has been transferred to `to`. + * - when `from` is zero, `amount` tokens have been minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens have been burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} +} + +contract CZZX is ERC20 { + constructor( + string memory name_, + string memory symbol_, + uint256 totalSupply_ + ) ERC20(name_, symbol_) { + _mint(msg.sender, totalSupply_); + } + + function decimals() public view virtual override returns (uint8) { + return 8; + } +} diff --git a/src/common/Symbolable.sol b/src/common/Symbolable.sol new file mode 100644 index 0000000..3975be0 --- /dev/null +++ b/src/common/Symbolable.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +abstract contract Symbolable { + string private _name; + + string private _symbol; + + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + function name() public view virtual returns (string memory) { + return _name; + } + + function symbol() public view virtual returns (string memory) { + return _symbol; + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..3b7bca8 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@openzeppelin/contracts@^4.7.3": + version "4.7.3" + resolved "https://registry.npmmirror.com/@openzeppelin/contracts/-/contracts-4.7.3.tgz#939534757a81f8d69cc854c7692805684ff3111e" + integrity sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==