From b6fc3a4e9875201033e1c8ab9a0b685d3fc9f3c8 Mon Sep 17 00:00:00 2001 From: Dan Oved Date: Fri, 12 Apr 2024 13:25:09 -0400 Subject: [PATCH] Mints Manager url update (#353) ## Description * Updates the mints manager `setMetadataURIs` with the ability to notify for each token id a url update on the mints 1155 contract * Adds a test that verifiers the desired metadata uris * updates the deployment scripts to set the correct metadata uris ## Motivation and Context ## Does this change the ABI/API? - [ ] This changes the ABI/API ## What tests did you add/modify to account for these changes ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New module / feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) ## Checklist: - [ ] My code follows the code style of this project. - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] i added a changeset to account for this change ## Reviewer Checklist: - [ ] My review includes a symposis of the changes and potential issues - [ ] The code style is enforced - [ ] There are no risky / concerning changes / additions to the PR --- .changeset/lemon-chefs-brake.md | 5 +++ .changeset/shiny-ways-destroy.md | 5 +++ .../1155-deployments/test/UpgradesTest.t.sol | 34 +++++++++++++++++-- .../mints-deployments/addresses/7777777.json | 4 +-- .../addresses/999999999.json | 4 +-- .../scripts/deployMintsDeterminisitic.ts | 4 +-- packages/mints/src/ZoraMintsManagerImpl.sol | 7 +++- .../mints/test/ZoraMintsManagerMetadata.t.sol | 34 +++++++++++++++++-- 8 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 .changeset/lemon-chefs-brake.md create mode 100644 .changeset/shiny-ways-destroy.md diff --git a/.changeset/lemon-chefs-brake.md b/.changeset/lemon-chefs-brake.md new file mode 100644 index 00000000..11f65e17 --- /dev/null +++ b/.changeset/lemon-chefs-brake.md @@ -0,0 +1,5 @@ +--- +"@zoralabs/protocol-deployments": patch +--- + +Deployed latest ZoraMintsManagerImpl to zora and zora-sepolia diff --git a/.changeset/shiny-ways-destroy.md b/.changeset/shiny-ways-destroy.md new file mode 100644 index 00000000..ea67726e --- /dev/null +++ b/.changeset/shiny-ways-destroy.md @@ -0,0 +1,5 @@ +--- +"@zoralabs/mints-contracts": patch +--- + +When updating token uris in the mints manager, it notifies the zors mints 1155 to emit an event for all token ids that were updated diff --git a/packages/1155-deployments/test/UpgradesTest.t.sol b/packages/1155-deployments/test/UpgradesTest.t.sol index 21f5c2fe..138e1337 100644 --- a/packages/1155-deployments/test/UpgradesTest.t.sol +++ b/packages/1155-deployments/test/UpgradesTest.t.sol @@ -49,6 +49,12 @@ interface UUPSUpgradeable { function upgradeToAndCall(address newImplementation, bytes memory data) external payable; } +interface IOwnable2StepUpgradeable { + function owner() external view returns (address); + function pendingOwner() external view returns (address); + function acceptOwnership() external; +} + contract UpgradesTest is ForkDeploymentConfig, DeploymentTestingUtils, Test { using stdJson for string; @@ -110,6 +116,29 @@ contract UpgradesTest is ForkDeploymentConfig, DeploymentTestingUtils, Test { return tryReadMintsImpl() != address(0); } + function determineMintsOwnershipNeeded() private view returns (UpgradeStatus memory) { + IOwnable2StepUpgradeable mintsManagerProxy = IOwnable2StepUpgradeable(getDeterminsticMintsManagerAddress()); + + if (address(mintsManagerProxy).code.length == 0) { + return UpgradeStatus("Accept Mints Ownership", false, address(0), address(0), ""); + } + + ChainConfig memory chainConfig = getChainConfig(); + + bool upgradeNeeded = chainConfig.factoryOwner != mintsManagerProxy.owner(); + + bytes memory upgradeCalldata; + + if (upgradeNeeded) { + if (mintsManagerProxy.pendingOwner() != chainConfig.factoryOwner) { + revert("Mints pending owner is not the expected owner"); + } + upgradeCalldata = abi.encodeWithSelector(IOwnable2StepUpgradeable.acceptOwnership.selector); + } + + return UpgradeStatus("Accept Mints Ownership", upgradeNeeded, address(mintsManagerProxy), address(0), upgradeCalldata); + } + function determineMintsUpgrade() private view returns (UpgradeStatus memory) { address mintsManagerProxy = getDeterminsticMintsManagerAddress(); @@ -333,10 +362,11 @@ contract UpgradesTest is ForkDeploymentConfig, DeploymentTestingUtils, Test { ChainConfig memory chainConfig = getChainConfig(); - UpgradeStatus[] memory upgradeStatuses = new UpgradeStatus[](3); + UpgradeStatus[] memory upgradeStatuses = new UpgradeStatus[](4); upgradeStatuses[0] = determine1155Upgrade(deployment); upgradeStatuses[1] = determinePreminterUpgrade(deployment); - upgradeStatuses[2] = determineMintsUpgrade(); + upgradeStatuses[2] = determineMintsOwnershipNeeded(); + upgradeStatuses[3] = determineMintsUpgrade(); bool upgradePerformed = performNeededUpgrades(chainConfig.factoryOwner, upgradeStatuses); diff --git a/packages/mints-deployments/addresses/7777777.json b/packages/mints-deployments/addresses/7777777.json index ed6f084e..973f4bd7 100644 --- a/packages/mints-deployments/addresses/7777777.json +++ b/packages/mints-deployments/addresses/7777777.json @@ -1,5 +1,5 @@ { "MINTS_ETH_UNWRAPPER_AND_CALLER": "0xE9Db91DD126D81697B588F1C145d74283E5C8ccC", - "MINTS_MANAGER_IMPL": "0x212957295F3A40408E14531387915cDfB26A7DeB", - "MINTS_MANAGER_IMPL_VERSION": "0.1.0" + "MINTS_MANAGER_IMPL": "0x978685ad10B829F17e6c2C6E8EeABd7dFDdC1678", + "MINTS_MANAGER_IMPL_VERSION": "0.1.2" } diff --git a/packages/mints-deployments/addresses/999999999.json b/packages/mints-deployments/addresses/999999999.json index ed6f084e..973f4bd7 100644 --- a/packages/mints-deployments/addresses/999999999.json +++ b/packages/mints-deployments/addresses/999999999.json @@ -1,5 +1,5 @@ { "MINTS_ETH_UNWRAPPER_AND_CALLER": "0xE9Db91DD126D81697B588F1C145d74283E5C8ccC", - "MINTS_MANAGER_IMPL": "0x212957295F3A40408E14531387915cDfB26A7DeB", - "MINTS_MANAGER_IMPL_VERSION": "0.1.0" + "MINTS_MANAGER_IMPL": "0x978685ad10B829F17e6c2C6E8EeABd7dFDdC1678", + "MINTS_MANAGER_IMPL_VERSION": "0.1.2" } diff --git a/packages/mints-deployments/scripts/deployMintsDeterminisitic.ts b/packages/mints-deployments/scripts/deployMintsDeterminisitic.ts index a14d07f2..b9939739 100644 --- a/packages/mints-deployments/scripts/deployMintsDeterminisitic.ts +++ b/packages/mints-deployments/scripts/deployMintsDeterminisitic.ts @@ -190,8 +190,8 @@ const generateInitializationConfig = async ({ const initialEthTokenId = 1n; const initialEthTokenPrice = parseEther("0.000777"); - const metadataBaseURI = "https://zora.co/metadata/mints/"; - const contractURI = "https://zora.co/metadata/mints/contract.json"; + const metadataBaseURI = "https://zora.co/assets/mints/metadata/"; + const contractURI = "https://zora.co/assets/mints/metadata/"; // this will initialize the mints contract with the owner, the initial token id, and the initial token price: // and will be called when the proxy will be initially upgraded to the implementation: diff --git a/packages/mints/src/ZoraMintsManagerImpl.sol b/packages/mints/src/ZoraMintsManagerImpl.sol index 79f302c7..c9224085 100644 --- a/packages/mints/src/ZoraMintsManagerImpl.sol +++ b/packages/mints/src/ZoraMintsManagerImpl.sol @@ -104,8 +104,13 @@ contract ZoraMintsManagerImpl is return "Zora Mints Manager"; } - function setMetadataURIs(string memory newContractURI, string memory newBaseURI) external onlyOwner { + function setMetadataURIs(string calldata newContractURI, string calldata newBaseURI, uint256[] calldata tokenIdsToNotifyUpdate) external onlyOwner { _setMetadataURIs(newContractURI, newBaseURI); + + // iterate through tokenIdsToNotifyUpdate and notify the mints contract of the updated URIs + for (uint256 i = 0; i < tokenIdsToNotifyUpdate.length; i++) { + IUpdateableTokenURI(address(_getMintsManagerStorage().mints)).notifyUpdatedTokenURI(_uri(tokenIdsToNotifyUpdate[i]), tokenIdsToNotifyUpdate[i]); + } } function _setMetadataURIs(string memory newContractURI, string memory newBaseURI) internal { diff --git a/packages/mints/test/ZoraMintsManagerMetadata.t.sol b/packages/mints/test/ZoraMintsManagerMetadata.t.sol index 6768ccf0..e3b454ae 100644 --- a/packages/mints/test/ZoraMintsManagerMetadata.t.sol +++ b/packages/mints/test/ZoraMintsManagerMetadata.t.sol @@ -27,6 +27,8 @@ contract ZoraMintsManagerMetadataTest is Test { ZoraMintsManagerImpl zoraMintsManager; IZoraMints1155 mints; + uint256[] tokenIds; + function setUp() public { bytes memory mintsCreationCode = abi.encodePacked(type(ZoraMints1155).creationCode); ZoraMintsManagerImpl managerImpl = new ZoraMintsManagerImpl(IZoraCreator1155PremintExecutorV2(address(0x123))); @@ -41,6 +43,10 @@ contract ZoraMintsManagerMetadataTest is Test { newBaseURI: "", newContractURI: "" }); + + tokenIds = new uint256[](2); + tokenIds[0] = 1; + tokenIds[1] = 5; } function testMetadataDeploysCorrectly() public { @@ -49,7 +55,7 @@ contract ZoraMintsManagerMetadataTest is Test { vm.expectEmit(true, true, true, true); emit URIsUpdated({contractURI: "https://zora.co/mints/metadata/contract.json", baseURI: "https://zora.co/mints/metadata/"}); vm.prank(defaultOwner); - zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/"); + zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/", tokenIds); assertEq(zoraMintsManager.uri(1), "https://zora.co/mints/metadata/1"); assertEq(zoraMintsManager.contractURI(), "https://zora.co/mints/metadata/contract.json"); } @@ -60,14 +66,14 @@ contract ZoraMintsManagerMetadataTest is Test { function testMetadataCannotBeUpdatedNonOwner() public { vm.expectRevert(abi.encodeWithSignature("OwnableUnauthorizedAccount(address)", address(0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496))); - zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/"); + zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/", tokenIds); } function testZoraNFTEmitsContractURI() public { vm.expectEmit(true, true, true, true); emit ContractURIUpdated(); vm.prank(defaultOwner); - zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/"); + zoraMintsManager.setMetadataURIs("https://zora.co/mints/metadata/contract.json", "https://zora.co/mints/metadata/", tokenIds); } function testZoraNFTNotifiesNewTokenURI() public { @@ -76,4 +82,26 @@ contract ZoraMintsManagerMetadataTest is Test { emit URI("2", 2); zoraMintsManager.createToken(2, TokenConfig({price: 0.01 ether, tokenAddress: address(0), redeemHandler: address(0)}), false); } + + function testMintsMetadataUpdate_zora() public { + string memory newContractURI = "https://zora.co/assets/mints/metadata"; + string memory newBaseURI = "https://zora.co/assets/mints/metadata/"; + + tokenIds = new uint256[](1); + + tokenIds[0] = 1; + + bytes memory setNewUrlsCall = abi.encodeWithSelector(ZoraMintsManagerImpl.setMetadataURIs.selector, newContractURI, newBaseURI, tokenIds); + + vm.startPrank(zoraMintsManager.owner()); + + (bool success, ) = address(zoraMintsManager).call(setNewUrlsCall); + + assertTrue(success); + assertEq(ZoraMints1155(address(zoraMintsManager.zoraMints1155())).contractURI(), newContractURI); + assertEq(ZoraMints1155(address(zoraMintsManager.zoraMints1155())).uri(1), "https://zora.co/assets/mints/metadata/1"); + + console2.log("update urls call:"); + console2.log(vm.toString(setNewUrlsCall)); + } }