From 789b02b19f3a407384331c9ce281a65b52c65192 Mon Sep 17 00:00:00 2001 From: huyhuynh3103 Date: Tue, 1 Jul 2025 18:18:19 +0700 Subject: [PATCH 1/5] feat: set base token URI --- ...interPauserAutoIdCustomizedUpgradeable.sol | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol index 1bea8ff..693eb51 100644 --- a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol +++ b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol @@ -29,14 +29,12 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ERC721PausableUpgradeable, IERC721PresetMinterPauserAutoIdCustomized { - error ErrUnauthorizedAccount(address account, bytes32 neededRole); - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); uint256 private _tokenIdTracker; - string private _baseTokenURI; + string internal _baseTokenURI; /** * @dev This empty reserved space is put in place to allow future versions to add new @@ -62,12 +60,10 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ) internal onlyInitializing { __ERC721_init_unchained(name, symbol); __Pausable_init_unchained(); - __ERC721PresetMinterPauserAutoId_init_unchained(name, symbol, baseTokenURI); + __ERC721PresetMinterPauserAutoId_init_unchained(baseTokenURI); } function __ERC721PresetMinterPauserAutoId_init_unchained( - string memory, - string memory, string memory baseTokenURI ) internal onlyInitializing { _baseTokenURI = baseTokenURI; @@ -77,35 +73,32 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is _grantRole(MINTER_ROLE, _msgSender()); _grantRole(PAUSER_ROLE, _msgSender()); - ++_tokenIdTracker; + _tokenIdTracker = _firstTokenId(); } /// @inheritdoc IERC721PresetMinterPauserAutoIdCustomized function mint( address to - ) public virtual returns (uint256 tokenId) { - address sender = _msgSender(); - if (!hasRole(MINTER_ROLE, sender)) revert ErrUnauthorizedAccount(sender, MINTER_ROLE); - + ) public virtual onlyRole(MINTER_ROLE) returns (uint256 tokenId) { tokenId = _mintFor(to); } /// @inheritdoc IERC721PresetMinterPauserAutoIdCustomized - function pause() public virtual { - address sender = _msgSender(); - if (!hasRole(PAUSER_ROLE, sender)) revert ErrUnauthorizedAccount(sender, PAUSER_ROLE); - + function pause() public virtual onlyRole(PAUSER_ROLE) { _pause(); } /// @inheritdoc IERC721PresetMinterPauserAutoIdCustomized - function unpause() public virtual { - address sender = _msgSender(); - if (!hasRole(PAUSER_ROLE, sender)) revert ErrUnauthorizedAccount(sender, PAUSER_ROLE); - + function unpause() public virtual onlyRole(PAUSER_ROLE) { _unpause(); } + function setBaseTokenURI( + string calldata baseTokenURI + ) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { + _baseTokenURI = baseTokenURI; + } + /** * @dev See {IERC165-supportsInterface}. */ @@ -173,4 +166,9 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ) internal virtual override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { super._increaseBalance(account, amount); } + + /// @dev Allow child contract to define the first token id. Default to 1. + function _firstTokenId() internal view virtual returns (uint256) { + return 1; + } } From a59f5aa04177a3ae1ca4411df168e814a4d4f16f Mon Sep 17 00:00:00 2001 From: huyhuynh3103 Date: Tue, 1 Jul 2025 18:20:34 +0700 Subject: [PATCH 2/5] chore: add comments --- .../ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol index 693eb51..2545b19 100644 --- a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol +++ b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol @@ -93,6 +93,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is _unpause(); } + /// @dev Allow admin to set the base token URI. function setBaseTokenURI( string calldata baseTokenURI ) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { From cb1ce247ccb49c05e0c4719cc115ea48d9abae9d Mon Sep 17 00:00:00 2001 From: huyhuynh3103 Date: Wed, 2 Jul 2025 11:43:49 +0700 Subject: [PATCH 3/5] feat: make _baseTokenURI private --- ...setMinterPauserAutoIdCustomizedUpgradeable.sol | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol index 2545b19..e805485 100644 --- a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol +++ b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol @@ -34,7 +34,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is uint256 private _tokenIdTracker; - string internal _baseTokenURI; + string private _baseTokenURI; /** * @dev This empty reserved space is put in place to allow future versions to add new @@ -66,7 +66,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is function __ERC721PresetMinterPauserAutoId_init_unchained( string memory baseTokenURI ) internal onlyInitializing { - _baseTokenURI = baseTokenURI; + _setBaseTokenURI(baseTokenURI); _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); @@ -97,7 +97,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is function setBaseTokenURI( string calldata baseTokenURI ) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { - _baseTokenURI = baseTokenURI; + _setBaseTokenURI(baseTokenURI); } /** @@ -132,6 +132,15 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ++_tokenIdTracker; } + /// @dev Helper function to set the base token URI. + function _setBaseTokenURI( + string memory baseTokenURI + ) internal { + require(bytes(baseTokenURI).length > 0, "Invalid base token URI"); + + _baseTokenURI = baseTokenURI; + } + /** * @dev Helper function to mint for address `to`. * From e6040c27f06a7e5a113deac8e7de481aa37b92a3 Mon Sep 17 00:00:00 2001 From: huyhuynh3103 Date: Wed, 2 Jul 2025 11:48:19 +0700 Subject: [PATCH 4/5] chore: custom error --- .../ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol index e805485..529609d 100644 --- a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol +++ b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol @@ -29,6 +29,8 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ERC721PausableUpgradeable, IERC721PresetMinterPauserAutoIdCustomized { + error InvalidBaseTokenURI(); + bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); @@ -136,7 +138,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is function _setBaseTokenURI( string memory baseTokenURI ) internal { - require(bytes(baseTokenURI).length > 0, "Invalid base token URI"); + require(bytes(baseTokenURI).length > 0, InvalidBaseTokenURI()); _baseTokenURI = baseTokenURI; } From 2397a94c65bea8c2ac342179638b46d330a6190b Mon Sep 17 00:00:00 2001 From: huyhuynh3103 Date: Wed, 2 Jul 2025 12:22:46 +0700 Subject: [PATCH 5/5] chore: emit event --- src/interfaces/IERC721PresetMinterPauserAutoIdCustomized.sol | 4 ++++ .../ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IERC721PresetMinterPauserAutoIdCustomized.sol b/src/interfaces/IERC721PresetMinterPauserAutoIdCustomized.sol index 9b66084..9fb4215 100644 --- a/src/interfaces/IERC721PresetMinterPauserAutoIdCustomized.sol +++ b/src/interfaces/IERC721PresetMinterPauserAutoIdCustomized.sol @@ -2,6 +2,10 @@ pragma solidity ^0.8.0; interface IERC721PresetMinterPauserAutoIdCustomized { + error InvalidBaseTokenURI(); + + event BaseTokenURIUpdated(string baseTokenURI); + /** * @dev Creates a new token for `to`. Its token ID will be automatically * assigned (and available on the emitted {IERC721Upgradeable-Transfer} event), and the token diff --git a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol index 529609d..6610a42 100644 --- a/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol +++ b/src/upgradeable/ERC721PresetMinterPauserAutoIdCustomizedUpgradeable.sol @@ -29,8 +29,6 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is ERC721PausableUpgradeable, IERC721PresetMinterPauserAutoIdCustomized { - error InvalidBaseTokenURI(); - bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); @@ -141,6 +139,7 @@ contract ERC721PresetMinterPauserAutoIdCustomizedUpgradeable is require(bytes(baseTokenURI).length > 0, InvalidBaseTokenURI()); _baseTokenURI = baseTokenURI; + emit BaseTokenURIUpdated(baseTokenURI); } /**