From 1720bf2fde1d616b613af68df2c0c78250f6bce0 Mon Sep 17 00:00:00 2001 From: Dan Oved Date: Tue, 24 Oct 2023 09:14:34 -0600 Subject: [PATCH] Mint arguments are a struct --- .../ZoraCreator1155PremintExecutorImpl.sol | 32 +++++++++---------- .../ZoraCreator1155PremintExecutorImplLib.sol | 6 ++-- .../src/deployment/DeploymentTestingUtils.sol | 31 +++++++++--------- .../test/fixtures/Zora1155PremintFixtures.sol | 4 +-- .../Zora1155PremintExecutorProxy.t.sol | 14 ++++---- .../ZoraCreator1155PremintExecutor.t.sol | 31 +++++++++++------- 6 files changed, 61 insertions(+), 57 deletions(-) diff --git a/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImpl.sol b/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImpl.sol index 776d0a9d6..46c535cbb 100644 --- a/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImpl.sol +++ b/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImpl.sol @@ -43,6 +43,12 @@ interface ILegacyZoraCreator1155PremintExecutor { ) external payable returns (uint256 newTokenId); } +struct MintArguments { + address mintRecipient; + string mintComment; + address mintReferral; +} + /// @title Enables creation of and minting tokens on Zora1155 contracts transactions using eip-712 signatures. /// Signature must provided by the contract creator, or an account that's permitted to create new tokens on the contract. /// Mints the first x tokens to the executor of the transaction. @@ -71,8 +77,7 @@ contract ZoraCreator1155PremintExecutorImpl is bool indexed createdNewContract, uint32 uid, address minter, - uint256 quantityMinted, - bytes mintArgumets + uint256 quantityMinted ); /// Creates a new token on the given erc1155 contract on behalf of a creator, and mints x tokens to the executor of this transaction. @@ -90,7 +95,7 @@ contract ZoraCreator1155PremintExecutorImpl is PremintConfigV2 calldata premintConfig, bytes calldata signature, uint256 quantityToMint, - bytes calldata mintArguments + MintArguments calldata mintArguments ) external payable returns (uint256 newTokenId) { (bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV2(premintConfig); address fixedPriceMinter = premintConfig.tokenConfig.fixedPriceMinter; @@ -126,7 +131,7 @@ contract ZoraCreator1155PremintExecutorImpl is PremintConfig calldata premintConfig, bytes calldata signature, uint256 quantityToMint, - bytes memory mintArguments + MintArguments memory mintArguments ) public payable returns (uint256 newTokenId) { (bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV1(premintConfig); @@ -151,7 +156,7 @@ contract ZoraCreator1155PremintExecutorImpl is uint256 quantityToMint, address fixedPriceMinter, uint32 uid, - bytes memory mintArguments + MintArguments memory mintArguments ) private returns (uint256 newTokenId) { // get or create the contract with the given params // contract address is deterministic. @@ -165,7 +170,7 @@ contract ZoraCreator1155PremintExecutorImpl is _performMint(tokenContract, fixedPriceMinter, newTokenId, quantityToMint, mintArguments); // emit Preminted event - emit PremintedV2(address(tokenContract), newTokenId, isNewContract, uid, msg.sender, quantityToMint, mintArguments); + emit PremintedV2(address(tokenContract), newTokenId, isNewContract, uid, msg.sender, quantityToMint); } function _performMint( @@ -173,19 +178,12 @@ contract ZoraCreator1155PremintExecutorImpl is address fixedPriceMinter, uint256 tokenId, uint256 quantityToMint, - bytes memory mintArguments + MintArguments memory mintArguments ) internal { - (address mintReferral, string memory mintComment) = ZoraCreator1155PremintExecutorImplLib.decodeMintArguments(mintArguments); - + bytes memory mintSettings = abi.encode(mintArguments.mintRecipient, mintArguments.mintComment); if (quantityToMint != 0) // mint the number of specified tokens to the executor - tokenContract.mintWithRewards{value: msg.value}( - IMinter1155(fixedPriceMinter), - tokenId, - quantityToMint, - abi.encode(msg.sender, mintComment), - mintReferral - ); + tokenContract.mintWithRewards{value: msg.value}(IMinter1155(fixedPriceMinter), tokenId, quantityToMint, mintSettings, mintArguments.mintReferral); } function isValidSignature( @@ -284,7 +282,7 @@ contract ZoraCreator1155PremintExecutorImpl is string calldata mintComment ) external payable returns (uint256 newTokenId) { // encode legacy mint arguments to call current function: - bytes memory mintArguments = ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), mintComment); + MintArguments memory mintArguments = MintArguments({mintRecipient: msg.sender, mintComment: mintComment, mintReferral: address(0)}); return premint(contractConfig, premintConfig, signature, quantityToMint, mintArguments); } diff --git a/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImplLib.sol b/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImplLib.sol index 6ac32a540..873e20290 100644 --- a/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImplLib.sol +++ b/packages/1155-contracts/src/delegation/ZoraCreator1155PremintExecutorImplLib.sol @@ -51,11 +51,11 @@ library ZoraCreator1155PremintExecutorImplLib { zora1155Factory.deterministicContractAddress(address(this), contractConfig.contractURI, contractConfig.contractName, contractConfig.contractAdmin); } - function encodeMintArguments(address mintReferral, string memory mintComment) internal pure returns (bytes memory) { - return abi.encode(mintReferral, mintComment); + function encodeMintArguments(address mintRecipient, string memory mintComment) internal pure returns (bytes memory) { + return abi.encode(mintRecipient, mintComment); } - function decodeMintArguments(bytes memory mintArguments) internal pure returns (address mintReferral, string memory mintComment) { + function decodeMintArguments(bytes memory mintArguments) internal pure returns (address mintRecipient, string memory mintComment) { return abi.decode(mintArguments, (address, string)); } } diff --git a/packages/1155-contracts/src/deployment/DeploymentTestingUtils.sol b/packages/1155-contracts/src/deployment/DeploymentTestingUtils.sol index a91e7a34c..3ed77c292 100644 --- a/packages/1155-contracts/src/deployment/DeploymentTestingUtils.sol +++ b/packages/1155-contracts/src/deployment/DeploymentTestingUtils.sol @@ -5,7 +5,7 @@ import "forge-std/Script.sol"; import {IMinter1155} from "..//interfaces/IMinter1155.sol"; import {Zora1155FactoryFixtures} from "../../test/fixtures/Zora1155FactoryFixtures.sol"; import {Zora1155PremintFixtures} from "../../test/fixtures/Zora1155PremintFixtures.sol"; -import {ZoraCreator1155PremintExecutorImpl} from "../delegation/ZoraCreator1155PremintExecutorImpl.sol"; +import {ZoraCreator1155PremintExecutorImpl, MintArguments} from "../delegation/ZoraCreator1155PremintExecutorImpl.sol"; import {ZoraCreator1155FactoryImpl} from "../factory/ZoraCreator1155FactoryImpl.sol"; import {ZoraCreator1155Attribution, ContractCreationConfig, PremintConfigV2} from "../delegation/ZoraCreator1155Attribution.sol"; import {ZoraCreator1155Impl} from "../nft/ZoraCreator1155Impl.sol"; @@ -31,26 +31,27 @@ contract DeploymentTestingUtils is Script { ContractCreationConfig memory contractConfig = Zora1155PremintFixtures.makeDefaultContractCreationConfig(creator); address deterministicAddress = preminterAtProxy.getContractAddress(contractConfig); - bytes32 signatureVersion = ZoraCreator1155Attribution.HASHED_VERSION_2; - bytes32 structHash = ZoraCreator1155Attribution.hashPremint(premintConfig); - // sign the premint - bytes32 digest = ZoraCreator1155Attribution.premintHashedTypeDataV4(structHash, deterministicAddress, signatureVersion, block.chainid); + uint256 quantityToMint = 1; - (uint8 v, bytes32 r, bytes32 s) = vm.sign(creatorPrivateKey, digest); + address mintRecipient = creator; - uint256 quantityToMint = 1; + MintArguments memory mintArguments = MintArguments({mintRecipient: mintRecipient, mintComment: "", mintReferral: address(0)}); - bytes memory signature = abi.encodePacked(r, s, v); + bytes memory signature = signPremint(premintConfig, deterministicAddress, creatorPrivateKey); // execute the premint - uint256 tokenId = preminterAtProxy.premint{value: 0.000777 ether}( - contractConfig, - premintConfig, - signature, - quantityToMint, - ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), "") - ); + uint256 tokenId = preminterAtProxy.premint{value: 0.000777 ether}(contractConfig, premintConfig, signature, quantityToMint, mintArguments); require(ZoraCreator1155Impl(deterministicAddress).delegatedTokenId(premintConfig.uid) == tokenId, "token id not created for uid"); } + + function signPremint(PremintConfigV2 memory premintConfig, address deterministicAddress, uint256 privateKey) private view returns (bytes memory signature) { + bytes32 signatureVersion = ZoraCreator1155Attribution.HASHED_VERSION_2; + bytes32 structHash = ZoraCreator1155Attribution.hashPremint(premintConfig); + // sign the premint + bytes32 digest = ZoraCreator1155Attribution.premintHashedTypeDataV4(structHash, deterministicAddress, signatureVersion, block.chainid); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + return abi.encodePacked(r, s, v); + } } diff --git a/packages/1155-contracts/test/fixtures/Zora1155PremintFixtures.sol b/packages/1155-contracts/test/fixtures/Zora1155PremintFixtures.sol index 0448044e6..7953b2849 100644 --- a/packages/1155-contracts/test/fixtures/Zora1155PremintFixtures.sol +++ b/packages/1155-contracts/test/fixtures/Zora1155PremintFixtures.sol @@ -20,8 +20,8 @@ library Zora1155PremintFixtures { return TokenCreationConfigV2({ tokenURI: "blah.token", - maxSupply: 10, - maxTokensPerAddress: 5, + maxSupply: 20, + maxTokensPerAddress: 10, pricePerToken: 0, mintStart: 0, mintDuration: 0, diff --git a/packages/1155-contracts/test/premint/Zora1155PremintExecutorProxy.t.sol b/packages/1155-contracts/test/premint/Zora1155PremintExecutorProxy.t.sol index e68f367b0..aea0fe36b 100644 --- a/packages/1155-contracts/test/premint/Zora1155PremintExecutorProxy.t.sol +++ b/packages/1155-contracts/test/premint/Zora1155PremintExecutorProxy.t.sol @@ -7,7 +7,7 @@ import {Zora1155PremintFixtures} from "../fixtures/Zora1155PremintFixtures.sol"; import {ZoraCreator1155FactoryImpl} from "../../src/factory/ZoraCreator1155FactoryImpl.sol"; import {Zora1155PremintExecutor} from "../../src/proxies/Zora1155PremintExecutor.sol"; import {ZoraCreator1155Impl} from "../../src/nft/ZoraCreator1155Impl.sol"; -import {ZoraCreator1155PremintExecutorImpl} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol"; +import {ZoraCreator1155PremintExecutorImpl, MintArguments} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol"; import {Zora1155Factory} from "../../src/proxies/Zora1155Factory.sol"; import {IMinter1155} from "../../src/interfaces/IMinter1155.sol"; import {ProxyShim} from "../../src/utils/ProxyShim.sol"; @@ -27,6 +27,8 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName { uint256 internal mintFeeAmount = 0.000777 ether; ZoraCreator1155PremintExecutorImpl preminterAtProxy; + MintArguments defaultMintArguments; + function setUp() external { zora = makeAddr("zora"); owner = makeAddr("owner"); @@ -47,6 +49,8 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName { // access the executor implementation via the proxy, and initialize the admin preminterAtProxy = ZoraCreator1155PremintExecutorImpl(address(proxy)); preminterAtProxy.initialize(owner); + + defaultMintArguments = MintArguments({mintRecipient: collector, mintComment: "blah", mintReferral: address(0)}); } function test_canInvokeImplementationMethods() external { @@ -82,13 +86,7 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName { // execute the premint vm.deal(collector, mintFeeAmount); vm.prank(collector); - uint256 tokenId = preminterAtProxy.premint{value: mintFeeAmount}( - contractConfig, - premintConfig, - signature, - quantityToMint, - ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), "") - ); + uint256 tokenId = preminterAtProxy.premint{value: mintFeeAmount}(contractConfig, premintConfig, signature, quantityToMint, defaultMintArguments); assertEq(ZoraCreator1155Impl(deterministicAddress).balanceOf(collector, tokenId), 1); } diff --git a/packages/1155-contracts/test/premint/ZoraCreator1155PremintExecutor.t.sol b/packages/1155-contracts/test/premint/ZoraCreator1155PremintExecutor.t.sol index e595b55d4..11efc8bf8 100644 --- a/packages/1155-contracts/test/premint/ZoraCreator1155PremintExecutor.t.sol +++ b/packages/1155-contracts/test/premint/ZoraCreator1155PremintExecutor.t.sol @@ -14,7 +14,7 @@ import {ICreatorRoyaltiesControl} from "../../src/interfaces/ICreatorRoyaltiesCo import {ZoraCreatorFixedPriceSaleStrategy} from "../../src/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.sol"; import {Zora1155Factory} from "../../src/proxies/Zora1155Factory.sol"; import {ZoraCreator1155FactoryImpl} from "../../src/factory/ZoraCreator1155FactoryImpl.sol"; -import {ZoraCreator1155PremintExecutorImpl} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol"; +import {ZoraCreator1155PremintExecutorImpl, MintArguments} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol"; import {ZoraCreator1155Attribution, ContractCreationConfig, TokenCreationConfig, TokenCreationConfigV2, PremintConfigV2, PremintConfig} from "../../src/delegation/ZoraCreator1155Attribution.sol"; import {ForkDeploymentConfig, Deployment} from "../../src/deployment/DeploymentConfig.sol"; import {UUPSUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol"; @@ -40,7 +40,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { address internal premintExecutor; address internal collector; - bytes defaultMintArguments; + MintArguments defaultMintArguments; event PremintedV2( address indexed contractAddress, @@ -48,8 +48,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { bool indexed createdNewContract, uint32 uid, address minter, - uint256 quantityMinted, - bytes mintArgumets + uint256 quantityMinted ); function setUp() external { @@ -66,7 +65,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { preminter = new ZoraCreator1155PremintExecutorImpl(factory); - defaultMintArguments = ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), ""); + defaultMintArguments = MintArguments({mintRecipient: premintExecutor, mintComment: "blah", mintReferral: address(0)}); } function makeDefaultContractCreationConfig() internal view returns (ContractCreationConfig memory) { @@ -391,12 +390,18 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { uint256 nextTokenId; + uint256 beforeTokenBalance = created1155Contract.balanceOf(defaultMintArguments.mintRecipient, firstTokenId); + vm.startPrank(collector); // premint with new token config and signature, but same uid - it should mint tokens for the first token nextTokenId = preminter.premint{value: mintCost}(contractConfig, premintConfig, signature, quantityToMint, defaultMintArguments); assertEq(nextTokenId, firstTokenId); - assertEq(created1155Contract.balanceOf(collector, firstTokenId), quantityToMint); + assertEq( + created1155Contract.balanceOf(defaultMintArguments.mintRecipient, firstTokenId) - beforeTokenBalance, + quantityToMint, + "balance after first mint" + ); // change the version, it should still point to the first token premintConfig.version++; @@ -409,7 +414,11 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { vm.stopPrank(); assertEq(nextTokenId, firstTokenId); - assertEq(created1155Contract.balanceOf(collector, firstTokenId), quantityToMint * 2); + assertEq( + created1155Contract.balanceOf(defaultMintArguments.mintRecipient, firstTokenId) - beforeTokenBalance, + quantityToMint * 2, + "balance after second mint" + ); } function testCreateTokenPerUid() public { @@ -481,14 +490,12 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { // this account will be used to execute the premint, and should result in a contract being created vm.deal(premintExecutor, mintCost); - bytes memory mintArguments = defaultMintArguments; - vm.startPrank(premintExecutor); bool createdNewContract = true; vm.expectEmit(true, true, true, true); - emit PremintedV2(contractAddress, expectedTokenId, createdNewContract, premintConfig.uid, premintExecutor, quantityToMint, mintArguments); - preminter.premint{value: mintCost}(contractConfig, premintConfig, signature, quantityToMint, mintArguments); + emit PremintedV2(contractAddress, expectedTokenId, createdNewContract, premintConfig.uid, premintExecutor, quantityToMint); + preminter.premint{value: mintCost}(contractConfig, premintConfig, signature, quantityToMint, defaultMintArguments); } function test_onlyOwner_hasAdminRights_onCreatedToken() public { @@ -803,7 +810,7 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { ) private returns (uint256 newTokenId) { bytes memory signature = _signPremint(preminter.getContractAddress(contractConfig), premintConfig, privateKey, chainId); - bytes memory mintArguments = ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), comment); + MintArguments memory mintArguments = MintArguments({mintRecipient: executor, mintComment: comment, mintReferral: address(0)}); uint256 mintCost = mintFeeAmount * quantityToMint; vm.deal(executor, mintCost);