2
2
pragma solidity 0.8.26 ;
3
3
4
4
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol " ;
5
- import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol " ;
6
- import { ERC721URIStorage } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol " ;
7
- import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol " ;
8
- import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol " ;
5
+ /* solhint-disable-next-line max-line-length */
6
+ import { ERC721URIStorageUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol " ;
7
+ import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol " ;
9
8
import { IIPAssetRegistry } from "@story-protocol/protocol-core/contracts/interfaces/registries/IIPAssetRegistry.sol " ;
10
9
/*solhint-disable-next-line max-line-length*/
11
10
import { ILicensingModule } from "@story-protocol/protocol-core/contracts/interfaces/modules/licensing/ILicensingModule.sol " ;
@@ -17,72 +16,56 @@ import { IStoryNFT } from "../interfaces/story-nft/IStoryNFT.sol";
17
16
/// To create a new custom StoryNFT, inherit from this contract and override the required functions.
18
17
/// Note: the new StoryNFT must be whitelisted in `StoryNFTFactory` by the Story governance in order
19
18
/// to use the Story NFT Factory features.
20
- abstract contract BaseStoryNFT is IStoryNFT , ERC721URIStorage , Ownable , Initializable {
19
+ abstract contract BaseStoryNFT is IStoryNFT , ERC721URIStorageUpgradeable , OwnableUpgradeable {
21
20
/// @notice Story Proof-of-Creativity IP Asset Registry address.
21
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
22
22
IIPAssetRegistry public immutable IP_ASSET_REGISTRY;
23
23
24
24
/// @notice Story Proof-of-Creativity Licensing Module address.
25
+ /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
25
26
ILicensingModule public immutable LICENSING_MODULE;
26
27
27
- /// @notice Organization NFT address (see {OrgNFT}).
28
- address public immutable ORG_NFT;
29
-
30
- /// @notice Associated Organization NFT token ID.
31
- uint256 public orgTokenId;
32
-
33
- /// @notice Associated Organization IP ID.
34
- address public orgIpId;
35
-
36
- /// @dev Name of the collection.
37
- string private _name;
38
-
39
- /// @dev Symbol of the collection.
40
- string private _symbol;
41
-
42
- /// @dev Contract URI of the collection (follows OpenSea contract-level metadata standard).
43
- string private _contractURI;
44
-
45
- /// @dev Base URI of the collection (see {ERC721URIStorage-tokenURI} for how it is used).
46
- string private _baseURI_;
28
+ /// @dev Storage structure for the BaseStoryNFT
29
+ /// @param contractURI The contract URI of the collection.
30
+ /// @param baseURI The base URI of the collection.
31
+ /// @param totalSupply The total supply of the collection.
32
+ /// @custom:storage-location erc7201:story-protocol-periphery.BaseStoryNFT
33
+ struct BaseStoryNFTStorage {
34
+ string contractURI;
35
+ string baseURI;
36
+ uint256 totalSupply;
37
+ }
47
38
48
- /// @dev Current total supply of the collection.
49
- uint256 private _totalSupply;
39
+ // keccak256(abi.encode(uint256(keccak256("story-protocol-periphery.BaseStoryNFT")) - 1)) & ~bytes32(uint256(0xff));
40
+ bytes32 private constant BaseStoryNFTStorageLocation =
41
+ 0x81ed94d7560ff7bef5060a232718049e514c358c346e3254b876807a753c0e00 ;
50
42
51
- constructor (address ipAssetRegistry , address licensingModule , address orgNft ) ERC721 ("" , "" ) Ownable (msg .sender ) {
52
- if (ipAssetRegistry == address (0 ) || licensingModule == address (0 ) || orgNft == address (0 ))
53
- revert StoryNFT__ZeroAddressParam ();
43
+ constructor (address ipAssetRegistry , address licensingModule ) {
44
+ if (ipAssetRegistry == address (0 ) || licensingModule == address (0 )) revert StoryNFT__ZeroAddressParam ();
54
45
IP_ASSET_REGISTRY = IIPAssetRegistry (ipAssetRegistry);
55
46
LICENSING_MODULE = ILicensingModule (licensingModule);
56
- ORG_NFT = orgNft;
47
+
48
+ _disableInitializers ();
57
49
}
58
50
59
51
/// @notice Initializes the StoryNFT
60
- /// @param orgTokenId_ The token ID of the organization NFT.
61
- /// @param orgIpId_ The ID of the organization IP.
62
52
/// @param initParams The initialization parameters for StoryNFT {see {IStoryNFT-StoryNftInitParams}}.
63
- function initialize (
64
- uint256 orgTokenId_ ,
65
- address orgIpId_ ,
66
- StoryNftInitParams calldata initParams
67
- ) public virtual initializer {
68
- if (initParams.owner == address (0 ) || orgIpId_ == address (0 )) revert StoryNFT__ZeroAddressParam ();
69
-
70
- orgTokenId = orgTokenId_;
71
- orgIpId = orgIpId_;
72
-
73
- _name = initParams.name;
74
- _symbol = initParams.symbol;
75
- _contractURI = initParams.contractURI;
76
- _baseURI_ = initParams.baseURI;
77
-
78
- _transferOwnership (initParams.owner);
53
+ function __BaseStoryNFT_init (StoryNftInitParams calldata initParams ) internal onlyInitializing {
54
+ __Ownable_init (initParams.owner);
55
+ __ERC721URIStorage_init ();
56
+ __ERC721_init (initParams.name, initParams.symbol);
57
+
58
+ BaseStoryNFTStorage storage $ = _getBaseStoryNFTStorage ();
59
+ $.contractURI = initParams.contractURI;
60
+ $.baseURI = initParams.baseURI;
61
+
79
62
_customize (initParams.customInitData);
80
63
}
81
64
82
65
/// @notice Sets the contractURI of the collection (follows OpenSea contract-level metadata standard).
83
66
/// @param contractURI_ The new contractURI of the collection.
84
67
function setContractURI (string memory contractURI_ ) external onlyOwner {
85
- _contractURI = contractURI_;
68
+ _getBaseStoryNFTStorage ().contractURI = contractURI_;
86
69
87
70
emit ContractURIUpdated ();
88
71
}
@@ -104,7 +87,7 @@ abstract contract BaseStoryNFT is IStoryNFT, ERC721URIStorage, Ownable, Initiali
104
87
address recipient ,
105
88
string memory tokenURI_
106
89
) internal virtual returns (uint256 tokenId , address ipId ) {
107
- tokenId = _totalSupply ++ ;
90
+ tokenId = _getBaseStoryNFTStorage ().totalSupply ++ ;
108
91
_safeMint (recipient, tokenId);
109
92
_setTokenURI (tokenId, tokenURI_);
110
93
ipId = IP_ASSET_REGISTRY.register (block .chainid , address (this ), tokenId);
@@ -138,28 +121,18 @@ abstract contract BaseStoryNFT is IStoryNFT, ERC721URIStorage, Ownable, Initiali
138
121
/// @notice IERC165 interface support.
139
122
function supportsInterface (
140
123
bytes4 interfaceId
141
- ) public view virtual override (ERC721URIStorage , IERC165 ) returns (bool ) {
124
+ ) public view virtual override (ERC721URIStorageUpgradeable , IERC165 ) returns (bool ) {
142
125
return interfaceId == type (IStoryNFT).interfaceId || super .supportsInterface (interfaceId);
143
126
}
144
127
145
- /// @notice Returns the name of the collection.
146
- function name () public view override returns (string memory ) {
147
- return _name;
148
- }
149
-
150
- /// @notice Returns the symbol of the collection.
151
- function symbol () public view override returns (string memory ) {
152
- return _symbol;
153
- }
154
-
155
128
/// @notice Returns the current total supply of the collection.
156
129
function totalSupply () public view returns (uint256 ) {
157
- return _totalSupply ;
130
+ return _getBaseStoryNFTStorage ().totalSupply ;
158
131
}
159
132
160
133
/// @notice Returns the contract URI of the collection (follows OpenSea contract-level metadata standard).
161
134
function contractURI () external view virtual returns (string memory ) {
162
- return _contractURI ;
135
+ return _getBaseStoryNFTStorage ().contractURI ;
163
136
}
164
137
165
138
/// @notice Initializes the StoryNFT with custom data, required to be overridden by the inheriting contracts.
@@ -169,6 +142,13 @@ abstract contract BaseStoryNFT is IStoryNFT, ERC721URIStorage, Ownable, Initiali
169
142
170
143
/// @notice Returns the base URI of the collection (see {ERC721URIStorage-tokenURI} for how it is used).
171
144
function _baseURI () internal view virtual override returns (string memory ) {
172
- return _baseURI_;
145
+ return _getBaseStoryNFTStorage ().baseURI;
146
+ }
147
+
148
+ /// @dev Returns the storage struct of BaseStoryNFT.
149
+ function _getBaseStoryNFTStorage () private pure returns (BaseStoryNFTStorage storage $) {
150
+ assembly {
151
+ $.slot := BaseStoryNFTStorageLocation
152
+ }
173
153
}
174
154
}
0 commit comments