Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fork tests for upgrading proxies on zora goerli to point to correct impl addresses #241

Merged
merged 2 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion script/DeployProxiesToNewChain.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
69 changes: 51 additions & 18 deletions test/factory/ZoraCreator1155Factory_Fork.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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);
}
}
98 changes: 69 additions & 29 deletions test/premint/ZoraCreator1155PremintExecutor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -58,17 +59,17 @@ 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) {
return ContractCreationConfig({contractAdmin: creator, contractName: "blah", contractURI: "blah.contract"});
}

function makeDefaultTokenCreationConfig() internal view returns (TokenCreationConfig memory) {
IMinter1155 fixedPriceMinter = factoryImpl.defaultMinters()[0];
IMinter1155 fixedPriceMinter = factory.defaultMinters()[0];
return
TokenCreationConfig({
tokenURI: "blah.token",
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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 {
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down