@@ -11,10 +11,11 @@ import { IPNFT } from "./IPNFT.sol";
1111
1212error MustOwnIpnft ();
1313error AlreadyTokenized ();
14+ error ZeroAddress ();
1415
15- /// @title Tokenizer 1.1
16+ /// @title Tokenizer 1.2
1617/// @author molecule.to
17- /// @notice tokenizes an IPNFT to an ERC20 token (called IPT) and controls its supply.
18+ /// @notice tokenizes an IPNFT to an ERC20 token (called IPToken or IPT) and controls its supply.
1819contract Tokenizer is UUPSUpgradeable , OwnableUpgradeable {
1920 event TokensCreated (
2021 uint256 indexed moleculesId ,
@@ -27,15 +28,23 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable {
2728 string symbol
2829 );
2930
31+ event IPTokenImplementationUpdated (IPToken indexed old , IPToken indexed _new );
32+ event PermissionerUpdated (IPermissioner indexed old , IPermissioner indexed _new );
33+
3034 IPNFT internal ipnft;
3135
32- //this is the old term to keep the storage layout intact
36+ /// @dev a map of all IPTs. We're staying with the the initial term "synthesized" to keep the storage layout intact
3337 mapping (uint256 => IPToken) public synthesized;
38+
39+ /// @dev not used, needed to ensure that storage slots are still in order after 1.1 -> 1.2, use ipTokenImplementation
3440 /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
3541 address immutable tokenImplementation;
3642
3743 /// @dev the permissioner checks if senders have agreed to legal requirements
38- IPermissioner permissioner;
44+ IPermissioner public permissioner;
45+
46+ /// @notice the IPToken implementation this Tokenizer spawns
47+ IPToken public ipTokenImplementation;
3948
4049 /**
4150 * @param _ipnft the IPNFT contract
@@ -50,12 +59,28 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable {
5059
5160 /// @custom:oz-upgrades-unsafe-allow constructor
5261 constructor () {
53- tokenImplementation = address (new IPToken () );
62+ tokenImplementation = address (0 );
5463 _disableInitializers ();
5564 }
5665
5766 /**
58- * @dev called after an upgrade to reinitialize a new permissioner impl. This is 4 for görli compatibility
67+ * @notice sets the new implementation address of the IPToken
68+ * @param _ipTokenImplementation address pointing to the new implementation
69+ */
70+ function setIPTokenImplementation (IPToken _ipTokenImplementation ) external onlyOwner {
71+ /*
72+ could call some functions on old contract to make sure its tokenizer not another contract behind a proxy for safety
73+ */
74+ if (address (_ipTokenImplementation) == address (0 )) {
75+ revert ZeroAddress ();
76+ }
77+
78+ emit IPTokenImplementationUpdated (ipTokenImplementation, _ipTokenImplementation);
79+ ipTokenImplementation = _ipTokenImplementation;
80+ }
81+
82+ /**
83+ * @dev called after an upgrade to reinitialize a new permissioner impl.
5984 * @param _permissioner the new TermsPermissioner
6085 */
6186 function reinit (IPermissioner _permissioner ) public onlyOwner reinitializer (4 ) {
@@ -84,7 +109,7 @@ contract Tokenizer is UUPSUpgradeable, OwnableUpgradeable {
84109 }
85110
86111 // https://github.com/OpenZeppelin/workshops/tree/master/02-contracts-clone
87- token = IPToken (Clones.clone (tokenImplementation ));
112+ token = IPToken (Clones.clone (address (ipTokenImplementation) ));
88113 string memory name = string .concat ("IP Tokens of IPNFT # " , Strings.toString (ipnftId));
89114 token.initialize (name, tokenSymbol, TokenMetadata (ipnftId, _msgSender (), agreementCid));
90115
0 commit comments