// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import { ContractMetadataUpgradeable } from "../metadata/ContractMetadataUpgradeable.sol"; import { ERC1155BaseUpgradeable } from "../token/ERC1155/ERC1155BaseUpgradeable.sol"; import { ERC1155CementableUpgradeable } from "../token/ERC1155/ERC1155CementableUpgradeable.sol"; import { ERC1155BurnableUpgradeable } from "../token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; import { ERC1155FreezableUpgradeable } from "../token/ERC1155/extensions/ERC1155FreezableUpgradeable.sol"; import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import { ERC1155Upgradeable as ERC1155UpgradeableOZ } from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; import { ERC2981Upgradeable } from "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract SimpleERC1155Upgradeable is Initializable, Ownable2StepUpgradeable, ContractMetadataUpgradeable, ERC2981Upgradeable, ERC1155CementableUpgradeable, ERC1155BurnableUpgradeable, ERC1155FreezableUpgradeable, UUPSUpgradeable { /// @custom:storage-location erc7201:forma.storage.SimpleERC1155Storage struct SimpleERC1155Storage { uint256 _nextTokenId; mapping(uint256 => mapping(address => bool)) _minters; } // keccak256(abi.encode(uint256(keccak256("forma.storage.SimpleERC1155Storage")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant SimpleERC1155StorageLocation = 0x27dac445b5458a76eba16f82f5018c4c24fc0b32dd897e6a7b7282573c377d00; function _getSimpleERC1155Storage() private pure returns (SimpleERC1155Storage storage s) { assembly { s.slot := SimpleERC1155StorageLocation } } modifier onlyMinter(uint256 _tokenId) { SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); require(s._minters[_tokenId][_msgSender()], "Invalid minter"); _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( string calldata _name, address _initialOwner, address _defaultRoyaltyReceiver, uint96 _defaultRoyaltyFeeNumerator ) public initializer { __ERC1155_init(""); __ERC1155Burnable_init(); __Ownable_init(_initialOwner); __Ownable2Step_init(); __ContractMetadata_init(_name); __ERC1155Base_init(); __ERC1155Cementable_init(); __ERC2981_init(); __UUPSUpgradeable_init(); SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); s._nextTokenId = 0; _setDefaultRoyalty(_defaultRoyaltyReceiver, _defaultRoyaltyFeeNumerator); } function create(string calldata _metadata, bool _cemented, address _minter) external onlyOwner returns (uint256) { SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); uint256 _tokenId = s._nextTokenId; _setTokenMetadata(_tokenId, _metadata); if (_cemented) { _cementTokenMetadata(_tokenId); } if (_minter != address(0)) { s._minters[_tokenId][_minter] = true; } s._nextTokenId++; return _tokenId; } function mint(address _to, uint256 _tokenId, uint256 _amount) public virtual onlyMinter(_tokenId) { require(_exists(_tokenId), "Invalid tokenId"); _mint(_to, _tokenId, _amount, ""); } function grantMinter(uint256 _tokenId, address _minter) external onlyOwner { SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); s._minters[_tokenId][_minter] = true; } function revokeMinter(uint256 _tokenId, address _minter) external onlyOwner { SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); delete s._minters[_tokenId][_minter]; } function renounceMinter(uint256 _tokenId) external onlyOwner { SimpleERC1155Storage storage s = _getSimpleERC1155Storage(); delete s._minters[_tokenId][_msgSender()]; } function uri( uint256 _tokenId ) public view override(ERC1155UpgradeableOZ, ERC1155CementableUpgradeable) returns (string memory) { return _uri(_tokenId); } function setDefaultRoyalty(address _receiver, uint96 _feeNumerator) external onlyOwner { _setDefaultRoyalty(_receiver, _feeNumerator); } function setTokenRoyalty(uint256 _tokenId, address _receiver, uint96 _feeNumerator) external onlyOwner { _setTokenRoyalty(_tokenId, _receiver, _feeNumerator); } function _canSetContractMetadata() internal view override returns (bool) { return owner() == _msgSender(); } /// @dev Returns whether token metadata can be set in the given execution context. function _canSetTokenMetadata(uint256) internal view override returns (bool) { return owner() == _msgSender(); } function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC1155BurnableUpgradeable, ERC1155FreezableUpgradeable, ERC1155UpgradeableOZ, ERC2981Upgradeable) returns (bool) { return super.supportsInterface(interfaceId); } /** * @dev See {ERC1155-_update}. */ function _update( address from, address to, uint256[] memory ids, uint256[] memory values ) internal virtual override(ERC1155BaseUpgradeable, ERC1155FreezableUpgradeable) { super._update(from, to, ids, values); } function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} }