From 140fdc49d650d22ff0f4a0c7b800a184d6bcbbb2 Mon Sep 17 00:00:00 2001 From: Dan Oved Date: Tue, 3 Oct 2023 16:40:41 -0400 Subject: [PATCH] Fork tests for upgrading proxies on zora goerli to point to correct impl addresses --- script/DeployProxiesToNewChain.s.sol | 2 +- .../factory/ZoraCreator1155Factory_Fork.t.sol | 69 +++++++++---- .../ZoraCreator1155PremintExecutor.t.sol | 98 +++++++++++++------ 3 files changed, 121 insertions(+), 48 deletions(-) diff --git a/script/DeployProxiesToNewChain.s.sol b/script/DeployProxiesToNewChain.s.sol index 5ac69045e..508e04a69 100644 --- a/script/DeployProxiesToNewChain.s.sol +++ b/script/DeployProxiesToNewChain.s.sol @@ -17,7 +17,7 @@ import {DeterministicDeployerScript} from "../src/deployment/DeterministicDeploy import {IMinter1155} from "../src/interfaces/IMinter1155.sol"; import {DeploymentTestingUtils} from "../src/deployment/DeploymentTestingUtils.sol"; -contract DeployAllToNewChain is ZoraDeployerBase, DeterministicDeployerScript, DeploymentTestingUtils { +contract DeployProxiesToNewChain is ZoraDeployerBase, DeterministicDeployerScript, DeploymentTestingUtils { function run() public returns (string memory) { Deployment memory deployment = getDeployment(); ChainConfig memory chainConfig = getChainConfig(); diff --git a/test/factory/ZoraCreator1155Factory_Fork.t.sol b/test/factory/ZoraCreator1155Factory_Fork.t.sol index dad17f269..e45761254 100644 --- a/test/factory/ZoraCreator1155Factory_Fork.t.sol +++ b/test/factory/ZoraCreator1155Factory_Fork.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.17; import "forge-std/Test.sol"; import {IZoraCreator1155Factory} from "../../src/interfaces/IZoraCreator1155Factory.sol"; +import {ZoraCreator1155FactoryImpl} from "../../src/factory/ZoraCreator1155FactoryImpl.sol"; import {IZoraCreator1155Errors} from "../../src/interfaces/IZoraCreator1155Errors.sol"; import {IZoraCreator1155} from "../../src/interfaces/IZoraCreator1155.sol"; import {ZoraCreator1155Impl} from "../../src/nft/ZoraCreator1155Impl.sol"; @@ -12,7 +13,7 @@ import {ICreatorRoyaltiesControl} from "../../src/interfaces/ICreatorRoyaltiesCo import {MockContractMetadata} from "../mock/MockContractMetadata.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {ZoraCreatorFixedPriceSaleStrategy} from "../../src/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.sol"; -import {ForkDeploymentConfig} from "../../src/deployment/DeploymentConfig.sol"; +import {ForkDeploymentConfig, Deployment} from "../../src/deployment/DeploymentConfig.sol"; contract ZoraCreator1155FactoryForkTest is ForkDeploymentConfig, Test { uint256 constant quantityToMint = 3; @@ -92,27 +93,12 @@ contract ZoraCreator1155FactoryForkTest is ForkDeploymentConfig, Test { // ** 2. Setup a new token with the fixed price sales strategy ** } - function testTheFork(string memory chainName) private { + function mintTokenAtFork(IZoraCreator1155Factory factory) internal { uint96 tokenPrice = 1 ether; - console.log("testing on fork: ", chainName); - - // create and select the fork, which will be used for all subsequent calls - // it will also affect the current block chain id based on the rpc url returned - vm.createSelectFork(vm.rpcUrl(chainName)); - - address factoryAddress = getDeployment().factoryProxy; - IZoraCreator1155Factory factory = IZoraCreator1155Factory(factoryAddress); - - assertEq(getChainConfig().factoryOwner, IOwnable(factoryAddress).owner(), string.concat("configured owner incorrect on: ", chainName)); - + IMinter1155 fixedPrice = factory.defaultMinters()[0]; // now create a contract with the factory vm.startPrank(creator); - IMinter1155 fixedPrice = factory.defaultMinters()[0]; - - // make sure that the address from the factory matches the stored fixed price address - assertEq(getDeployment().fixedPriceSaleStrategy, address(fixedPrice), string.concat("configured fixed price address incorrect on: ", chainName)); - // ** 1. Create the erc1155 contract ** IZoraCreator1155 target = _createErc1155Contract(factory); @@ -134,10 +120,57 @@ contract ZoraCreator1155FactoryForkTest is ForkDeploymentConfig, Test { assertEq(balance, quantityToMint, "balance mismatch"); } + function testTheFork(string memory chainName) private { + console.log("testing on fork: ", chainName); + + // create and select the fork, which will be used for all subsequent calls + // it will also affect the current block chain id based on the rpc url returned + vm.createSelectFork(vm.rpcUrl(chainName)); + + Deployment memory deployment = getDeployment(); + + address factoryAddress = deployment.factoryProxy; + ZoraCreator1155FactoryImpl factory = ZoraCreator1155FactoryImpl(factoryAddress); + + assertEq(factory.implementation(), deployment.factoryImpl, "factory implementation incorrect"); + + assertEq(getChainConfig().factoryOwner, IOwnable(factoryAddress).owner(), string.concat("configured owner incorrect on: ", chainName)); + + // make sure that the address from the factory matches the stored fixed price address + // sanity check - check minters match config + assertEq(address(factory.merkleMinter()), deployment.merkleMintSaleStrategy); + assertEq(address(factory.fixedPriceMinter()), deployment.fixedPriceSaleStrategy); + assertEq(address(factory.redeemMinterFactory()), deployment.redeemMinterFactory); + } + function test_fork_canCreateContractAndMint() external { string[] memory forkTestChains = getForkTestChains(); for (uint256 i = 0; i < forkTestChains.length; i++) { testTheFork(forkTestChains[i]); } } + + // this is a temporary test to simulate the upgrade to the correct factory implementation + // on zora goerli. it can be deleted post upgrade + function test_fork_zoraGoerli_factoryUpgradeCanMint() external { + // create and select the fork, which will be used for all subsequent calls + // it will also affect the current block chain id based on the rpc url returned + vm.createSelectFork(vm.rpcUrl("zora_goerli")); + + Deployment memory deployment = getDeployment(); + + address factoryAddress = deployment.factoryProxy; + ZoraCreator1155FactoryImpl factory = ZoraCreator1155FactoryImpl(factoryAddress); + + vm.prank(factory.owner()); + + factory.upgradeTo(deployment.factoryImpl); + + // sanity check - check minters match config + assertEq(address(factory.merkleMinter()), deployment.merkleMintSaleStrategy); + assertEq(address(factory.fixedPriceMinter()), deployment.fixedPriceSaleStrategy); + assertEq(address(factory.redeemMinterFactory()), deployment.redeemMinterFactory); + + mintTokenAtFork(factory); + } } diff --git a/test/premint/ZoraCreator1155PremintExecutor.t.sol b/test/premint/ZoraCreator1155PremintExecutor.t.sol index fcc922679..d5c3bf87a 100644 --- a/test/premint/ZoraCreator1155PremintExecutor.t.sol +++ b/test/premint/ZoraCreator1155PremintExecutor.t.sol @@ -16,7 +16,8 @@ import {Zora1155Factory} from "../../src/proxies/Zora1155Factory.sol"; import {ZoraCreator1155FactoryImpl} from "../../src/factory/ZoraCreator1155FactoryImpl.sol"; import {ZoraCreator1155PremintExecutorImpl} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol"; import {ZoraCreator1155Attribution, ContractCreationConfig, TokenCreationConfig, PremintConfig} from "../../src/delegation/ZoraCreator1155Attribution.sol"; -import {ForkDeploymentConfig} from "../../src/deployment/DeploymentConfig.sol"; +import {ForkDeploymentConfig, Deployment} from "../../src/deployment/DeploymentConfig.sol"; +import {UUPSUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol"; import {ProxyShim} from "../../src/utils/ProxyShim.sol"; contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { @@ -25,7 +26,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { ZoraCreator1155PremintExecutorImpl internal preminter; Zora1155Factory factoryProxy; - ZoraCreator1155FactoryImpl factoryImpl; + ZoraCreator1155FactoryImpl factory; ICreatorRoyaltiesControl.RoyaltyConfiguration internal defaultRoyaltyConfig; uint256 internal mintFeeAmount = 0.000777 ether; @@ -58,9 +59,9 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { (, , factoryProxy) = Zora1155FactoryFixtures.setup1155AndFactoryProxy(zora, zora); vm.stopPrank(); - factoryImpl = ZoraCreator1155FactoryImpl(address(factoryProxy)); + factory = ZoraCreator1155FactoryImpl(address(factoryProxy)); - preminter = new ZoraCreator1155PremintExecutorImpl(factoryImpl); + preminter = new ZoraCreator1155PremintExecutorImpl(factory); } function makeDefaultContractCreationConfig() internal view returns (ContractCreationConfig memory) { @@ -68,7 +69,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { } function makeDefaultTokenCreationConfig() internal view returns (TokenCreationConfig memory) { - IMinter1155 fixedPriceMinter = factoryImpl.defaultMinters()[0]; + IMinter1155 fixedPriceMinter = factory.defaultMinters()[0]; return TokenCreationConfig({ tokenURI: "blah.token", @@ -222,27 +223,8 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { } } - function testTheForkPremint(string memory chainName) private { - console.log("testing on fork: ", chainName); - - // create and select the fork, which will be used for all subsequent calls - // it will also affect the current block chain id based on the rpc url returned - vm.createSelectFork(vm.rpcUrl(chainName)); - - // get contract hash, which is unique per contract creation config, and can be used - // retreive the address created for a contract - address preminterAddress = getDeployment().preminterProxy; - - if (preminterAddress == address(0)) { - console.log("preminter not configured for chain...skipping"); - return; - } - - preminter = ZoraCreator1155PremintExecutorImpl(preminterAddress); - - factoryImpl = ZoraCreator1155FactoryImpl(getDeployment().factoryProxy); - - console.log("building defaults"); + function preminterCanMintTokens() internal { + // we are for now upgrading to correct preminter impl // configuration of contract to create ContractCreationConfig memory contractConfig = makeDefaultContractCreationConfig(); @@ -275,8 +257,32 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { // get the contract address from the preminter based on the contract hash id. IZoraCreator1155 created1155Contract = IZoraCreator1155(contractAddress); + // console.log("getting balance"); // get the created contract, and make sure that tokens have been minted to the address - assertEq(created1155Contract.balanceOf(premintExecutor, tokenId), quantityToMint); + uint256 balance = created1155Contract.balanceOf(premintExecutor, tokenId); + + assertEq(balance, quantityToMint, "balance"); + } + + function testTheForkPremint(string memory chainName) private { + console.log("testing on fork: ", chainName); + + // create and select the fork, which will be used for all subsequent calls + // it will also affect the current block chain id based on the rpc url returned + vm.createSelectFork(vm.rpcUrl(chainName)); + + // get contract hash, which is unique per contract creation config, and can be used + // retreive the address created for a contract + address preminterAddress = getDeployment().preminterProxy; + + if (preminterAddress == address(0)) { + console.log("preminter not configured for chain...skipping"); + return; + } + + // override local preminter to use the addresses from the chain + factory = ZoraCreator1155FactoryImpl(getDeployment().factoryProxy); + preminter = ZoraCreator1155PremintExecutorImpl(preminterAddress); } function test_fork_successfullyMintsTokens() external { @@ -286,6 +292,40 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { } } + // this is a temporary test to simulate the upcoming upgrade + function test_fork_zoraGoerli_afterUpgradeCanPremint() external { + vm.createSelectFork(vm.rpcUrl("zora_goerli")); + + Deployment memory deployment = getDeployment(); + + factory = ZoraCreator1155FactoryImpl(deployment.factoryProxy); + + console2.log("factory upgrade target:", deployment.factoryProxy); + bytes memory factoryProxyUpgradeCall = abi.encodeWithSelector(UUPSUpgradeable.upgradeTo.selector, deployment.factoryImpl); + console2.log("factory upgrade call:", vm.toString(factoryProxyUpgradeCall)); + + console2.log("preminter upgrade target:", deployment.preminterProxy); + bytes memory preminterProxyUpgradeCall = abi.encodeWithSelector(UUPSUpgradeable.upgradeTo.selector, deployment.preminterImpl); + console2.log("preminter upgrade call:", vm.toString(preminterProxyUpgradeCall)); + + vm.prank(factory.owner()); + // lets call it as if we were calling from a safe: + deployment.factoryProxy.call(factoryProxyUpgradeCall); + + // override test storage to point to proxy + preminter = ZoraCreator1155PremintExecutorImpl(deployment.preminterProxy); + + vm.prank(preminter.owner()); + // preminter impl was already created with correct factory, were just upgrading it now + deployment.preminterProxy.call(preminterProxyUpgradeCall); + + assertEq(address(preminter.zora1155Factory()), address(factory)); + + preminterCanMintTokens(); + + // lets console.log these upgrades + } + function test_signatureForSameContractandUid_shouldMintExistingToken() external { // 1. Make contract creation params @@ -447,7 +487,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { fundsRecipient: creator }); - IMinter1155 fixedPrice = factoryImpl.fixedPriceMinter(); + IMinter1155 fixedPrice = factory.fixedPriceMinter(); // have the premint contract try to set the sales config - it should revert with // the expected UserMissingRole error @@ -596,7 +636,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { vm.warp(timeOfSecondMint); // execute mint directly on the contract - and check make sure it reverts if minted after sale start - IMinter1155 fixedPriceMinter = factoryImpl.defaultMinters()[0]; + IMinter1155 fixedPriceMinter = factory.defaultMinters()[0]; if (shouldRevert) { vm.expectRevert(ZoraCreatorFixedPriceSaleStrategy.SaleEnded.selector); }