// SPDX-License-Identifier: Affero General Public License v3.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts@v4.4.2/access/AccessControlEnumerable.sol"; import "@openzeppelin/contracts@v4.4.2/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts@v4.4.2/token/ERC721/extensions/IERC721Metadata.sol"; import "@openzeppelin/contracts@v4.4.2/token/ERC721/extensions/ERC721Pausable.sol"; import "@openzeppelin/contracts@v4.4.2/utils/Counters.sol"; import "@openzeppelin/contracts@v4.4.2/token/ERC721/extensions/ERC721URIStorage.sol"; import "./ERC2981.sol"; contract AmaFansNFT is Context, AccessControlEnumerable, ERC2981, ERC721Enumerable, ERC721Pausable, ERC721URIStorage { using Counters for Counters.Counter; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); Counters.Counter private _tokenIdTracker; string private _baseTokenURI; uint96 public royaltyValue = 500; //Makes it at 3% as feeDenominator in ERC2981 defaults //to 10000 so fees are expressed in basis points, /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * Token URIs will be autogenerated based on `baseURI` and their token IDs. * See {ERC721-tokenURI}. */ constructor() ERC721("ama.fans", "AMAF") { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); super._setRoleAdmin(MINTER_ROLE, DEFAULT_ADMIN_ROLE); super._setRoleAdmin(PAUSER_ROLE, DEFAULT_ADMIN_ROLE); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); } function _baseURI() internal view override returns (string memory) { return _baseTokenURI; } function setRoyaltyValue(uint96 _royaltyValue) external onlyRole(DEFAULT_ADMIN_ROLE){ royaltyValue = _royaltyValue; } /** * @dev Creates a new token for `to`. Its token ID will be automatically * assigned (and available on the emitted {IERC721-Transfer} event), and the token * URI autogenerated based on the base URI passed at construction. * * See {ERC721-_mint}. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function mint(address to, string memory _tokenURI) public whenNotPaused() returns(uint256) { require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint"); //We could have the totalSupply directly but then it would have // minted first token as id = 0, _tokenIdTracker.increment(); uint256 newNftTokenId = _tokenIdTracker.current(); // We cannot just use balanceOf to create the new tokenId because tokens // can be burned (destroyed), so we need a separate counter. _safeMint(to, newNftTokenId); _setTokenURI(newNftTokenId, _tokenURI); _setTokenRoyalty(newNftTokenId, to, royaltyValue); return newNftTokenId; } /** * @dev Pauses all token transfers. * * See {ERC721Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause"); _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC721Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public virtual { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause"); _unpause(); } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal override(ERC721, ERC721Enumerable, ERC721Pausable) { super._beforeTokenTransfer(from, to, tokenId); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view override(AccessControlEnumerable, ERC2981, ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function burn(uint256 tokenId) external { _burn(tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage){ //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved"); super._resetTokenRoyalty(tokenId); super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } }