diff --git a/.changeset/pink-pants-decide.md b/.changeset/pink-pants-decide.md new file mode 100644 index 000000000..d8c139ce0 --- /dev/null +++ b/.changeset/pink-pants-decide.md @@ -0,0 +1,5 @@ +--- +"@zoralabs/zora-1155-contracts": minor +--- + +Add TokenId to redeemInstructionsHashIsAllowed for Redeem Contracts diff --git a/.changeset/thin-geese-flash.md b/.changeset/thin-geese-flash.md new file mode 100644 index 000000000..7941a7084 --- /dev/null +++ b/.changeset/thin-geese-flash.md @@ -0,0 +1,6 @@ +--- +"@zoralabs/zora-1155-contracts": patch +--- + +- Ensures sales configs can only be updated for the token ids specified +- Deprecates support with 'ZoraCreatorRedeemMinterStrategy' v1.0.1 diff --git a/.changeset/witty-numbers-share.md b/.changeset/witty-numbers-share.md new file mode 100644 index 000000000..9200b936f --- /dev/null +++ b/.changeset/witty-numbers-share.md @@ -0,0 +1,6 @@ +--- +"@zoralabs/zora-1155-contracts": minor +--- + +- Patches the 1155 `callSale` function to ensure that the token id passed matches the token id encoded in the generic calldata to forward +- Updates the redeem minter to v1.1.0 to support b2r per an 1155 token id diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 18da216af..876907819 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -38,6 +38,12 @@ jobs: - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 + - name: Filter files to ignore + run: | + lcov --rc lcov_branch_coverage=1 \ + --remove lcov.info \ + --output-file lcov.info "*node_modules*" "*test*" "*script*" "*DeploymentConfig*" + - name: Report code coverage uses: zgosalvez/github-actions-report-lcov@v2 with: diff --git a/foundry.toml b/foundry.toml index 83304a006..2d32d4992 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,7 +2,7 @@ fs_permissions = [{access = "read", path = "./addresses"}, {access = "read", path = "./chainConfigs"}, {access = "read", path = "./package.json"}] libs = ['_imagine', 'node_modules', 'script'] optimizer = true -optimizer_runs = 3000 +optimizer_runs = 500 out = 'out' solc_version = '0.8.17' src = 'src' diff --git a/src/interfaces/IZoraCreator1155.sol b/src/interfaces/IZoraCreator1155.sol index 7ffd1d490..f7f4da724 100644 --- a/src/interfaces/IZoraCreator1155.sol +++ b/src/interfaces/IZoraCreator1155.sol @@ -76,6 +76,7 @@ interface IZoraCreator1155 is IZoraCreator1155TypesV1, IVersionedContract, IOwna error Sale_CannotCallNonSalesContract(address targetContract); + error Call_TokenIdMismatch(); error CallFailed(bytes reason); error Renderer_NotValidRendererContract(); diff --git a/src/minters/redeem/ZoraCreatorRedeemMinterFactory.sol b/src/minters/redeem/ZoraCreatorRedeemMinterFactory.sol index 2c5cafcb0..c51c1182b 100644 --- a/src/minters/redeem/ZoraCreatorRedeemMinterFactory.sol +++ b/src/minters/redeem/ZoraCreatorRedeemMinterFactory.sol @@ -67,7 +67,7 @@ contract ZoraCreatorRedeemMinterFactory is Enjoy, IContractMetadata, SharedBaseC /// @notice Factory contract version function contractVersion() external pure override returns (string memory) { - return "1.0.1"; + return "1.1.0"; } /// @notice No-op function for IMinter1155 compatibility diff --git a/src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol b/src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol index 1e1201be0..77c19ab96 100644 --- a/src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol +++ b/src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol @@ -120,8 +120,8 @@ contract ZoraCreatorRedeemMinterStrategy is Enjoy, SaleStrategy, Initializable { error MintTokenContractMustBeCreatorContract(); error SenderIsNotTokenOwner(); - /// @notice keccak256(abi.encode(RedeemInstructions)) => redeem instructions are allowed - mapping(bytes32 => bool) public redeemInstructionsHashIsAllowed; + /// @notice tokenId, keccak256(abi.encode(RedeemInstructions)) => redeem instructions are allowed + mapping(uint256 => mapping(bytes32 => bool)) public redeemInstructionsHashIsAllowed; /// @notice Zora creator contract address public creatorContract; @@ -152,7 +152,7 @@ contract ZoraCreatorRedeemMinterStrategy is Enjoy, SaleStrategy, Initializable { /// @notice Redeem Minter Strategy contract version function contractVersion() external pure override returns (string memory) { - return "1.0.1"; + return "1.1.0"; } /// @notice Redeem instructions object hash @@ -210,27 +210,33 @@ contract ZoraCreatorRedeemMinterStrategy is Enjoy, SaleStrategy, Initializable { } /// @notice Set redeem instructions + /// @param tokenId The token id to set redeem instructions for /// @param _redeemInstructions The redeem instructions object - function setRedeem(RedeemInstructions calldata _redeemInstructions) external onlyCreatorContract { + function setRedeem(uint256 tokenId, RedeemInstructions calldata _redeemInstructions) external onlyCreatorContract { + if (_redeemInstructions.mintToken.tokenId != tokenId) { + revert InvalidTokenIdsForTokenType(); + } + validateRedeemInstructions(_redeemInstructions); bytes32 hash = redeemInstructionsHash(_redeemInstructions); - if (redeemInstructionsHashIsAllowed[hash]) { + if (redeemInstructionsHashIsAllowed[tokenId][hash]) { revert RedeemInstructionAlreadySet(); } - redeemInstructionsHashIsAllowed[hash] = true; + redeemInstructionsHashIsAllowed[tokenId][hash] = true; emit RedeemSet(creatorContract, hash, _redeemInstructions); } /// @notice Clear redeem instructions + /// @param tokenId The token id to clear redeem instructions for /// @param hashes Array of redeem instructions hashes to clear - function clearRedeem(bytes32[] calldata hashes) external onlyCreatorContract { + function clearRedeem(uint256 tokenId, bytes32[] calldata hashes) external onlyCreatorContract { uint256 numHashes = hashes.length; unchecked { for (uint256 i; i < numHashes; ++i) { - redeemInstructionsHashIsAllowed[hashes[i]] = false; + redeemInstructionsHashIsAllowed[tokenId][hashes[i]] = false; } } @@ -254,7 +260,11 @@ contract ZoraCreatorRedeemMinterStrategy is Enjoy, SaleStrategy, Initializable { (RedeemInstructions, uint256[][], uint256[][]) ); bytes32 hash = redeemInstructionsHash(redeemInstructions); - if (!redeemInstructionsHashIsAllowed[hash]) { + + if (tokenId != redeemInstructions.mintToken.tokenId) { + revert InvalidTokenIdsForTokenType(); + } + if (!redeemInstructionsHashIsAllowed[tokenId][hash]) { revert RedeemInstructionNotAllowed(); } if (redeemInstructions.saleStart > block.timestamp) { diff --git a/src/nft/ZoraCreator1155Impl.sol b/src/nft/ZoraCreator1155Impl.sol index d9638473b..c29a946fc 100644 --- a/src/nft/ZoraCreator1155Impl.sol +++ b/src/nft/ZoraCreator1155Impl.sol @@ -506,11 +506,21 @@ contract ZoraCreator1155Impl is /// @param tokenId The token ID to call the sale contract with /// @param salesConfig The sales config contract to call /// @param data The data to pass to the sales config contract - function callSale(uint256 tokenId, IMinter1155 salesConfig, bytes memory data) external onlyAdminOrRole(tokenId, PERMISSION_BIT_SALES) { + function callSale(uint256 tokenId, IMinter1155 salesConfig, bytes calldata data) external onlyAdminOrRole(tokenId, PERMISSION_BIT_SALES) { _requireAdminOrRole(address(salesConfig), tokenId, PERMISSION_BIT_MINTER); if (!salesConfig.supportsInterface(type(IMinter1155).interfaceId)) { revert Sale_CannotCallNonSalesContract(address(salesConfig)); } + + // Get the token id encoded in the calldata for the sales config + // Assume that it is the first 32 bytes following the function selector + uint256 encodedTokenId = uint256(bytes32(data[4:36])); + + // Ensure the encoded token id matches the passed token id + if (encodedTokenId != tokenId) { + revert Call_TokenIdMismatch(); + } + (bool success, bytes memory why) = address(salesConfig).call(data); if (!success) { revert CallFailed(why); diff --git a/test/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.t.sol b/test/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.t.sol index caa87907b..03591dc93 100644 --- a/test/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.t.sol +++ b/test/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.t.sol @@ -420,4 +420,44 @@ contract ZoraCreatorFixedPriceSaleStrategyTest is Test { assertTrue(fixedPrice.supportsInterface(0x01ffc9a7)); assertFalse(fixedPrice.supportsInterface(0x0)); } + + function testRevert_CannotSetSaleOfDifferentTokenId() public { + vm.startPrank(admin); + uint256 tokenId1 = target.setupNewToken("https://zora.co/testing/token.json", 10); + uint256 tokenId2 = target.setupNewToken("https://zora.co/testing/token.json", 5); + + target.addPermission(tokenId1, address(fixedPrice), target.PERMISSION_BIT_MINTER()); + target.addPermission(tokenId2, address(fixedPrice), target.PERMISSION_BIT_MINTER()); + + vm.expectRevert(abi.encodeWithSignature("Call_TokenIdMismatch()")); + target.callSale( + tokenId1, + fixedPrice, + abi.encodeWithSelector( + ZoraCreatorFixedPriceSaleStrategy.setSale.selector, + tokenId2, + ZoraCreatorFixedPriceSaleStrategy.SalesConfig({ + pricePerToken: 1 ether, + saleStart: 0, + saleEnd: type(uint64).max, + maxTokensPerAddress: 0, + fundsRecipient: address(0) + }) + ) + ); + vm.stopPrank(); + } + + function testRevert_CannotResetSaleOfDifferentTokenId() public { + vm.startPrank(admin); + uint256 tokenId1 = target.setupNewToken("https://zora.co/testing/token.json", 10); + uint256 tokenId2 = target.setupNewToken("https://zora.co/testing/token.json", 5); + + target.addPermission(tokenId1, address(fixedPrice), target.PERMISSION_BIT_MINTER()); + target.addPermission(tokenId2, address(fixedPrice), target.PERMISSION_BIT_MINTER()); + + vm.expectRevert(abi.encodeWithSignature("Call_TokenIdMismatch()")); + target.callSale(tokenId1, fixedPrice, abi.encodeWithSelector(ZoraCreatorFixedPriceSaleStrategy.resetSale.selector, tokenId2)); + vm.stopPrank(); + } } diff --git a/test/minters/redeem/ZoraCreatorRedeemMinterFactory.t.sol b/test/minters/redeem/ZoraCreatorRedeemMinterFactory.t.sol index 92a9f26fb..738feab88 100644 --- a/test/minters/redeem/ZoraCreatorRedeemMinterFactory.t.sol +++ b/test/minters/redeem/ZoraCreatorRedeemMinterFactory.t.sol @@ -16,6 +16,7 @@ import {IZoraCreator1155Factory} from "../../../src/interfaces/IZoraCreator1155F import {ZoraCreatorRedeemMinterStrategy} from "../../../src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol"; import {ZoraCreatorRedeemMinterFactory} from "../../../src/minters/redeem/ZoraCreatorRedeemMinterFactory.sol"; +/// @notice Contract versions after v1.4.0 will not support burn to redeem contract ZoraCreatorRedeemMinterFactoryTest is Test { ProtocolRewards internal protocolRewards; ZoraCreator1155Impl internal target; @@ -39,7 +40,7 @@ contract ZoraCreatorRedeemMinterFactoryTest is Test { } function test_contractVersion() public { - assertEq(minterFactory.contractVersion(), "1.0.1"); + assertEq(minterFactory.contractVersion(), "1.1.0"); } function test_createMinterIfNoneExists() public { @@ -48,7 +49,7 @@ contract ZoraCreatorRedeemMinterFactoryTest is Test { address predictedAddress = minterFactory.predictMinterAddress(address(target)); vm.expectEmit(false, false, false, false); emit RedeemMinterDeployed(address(target), predictedAddress); - target.callSale(0, minterFactory, abi.encodeWithSelector(ZoraCreatorRedeemMinterFactory.createMinterIfNoneExists.selector)); + target.callSale(0, minterFactory, abi.encodeWithSelector(ZoraCreatorRedeemMinterFactory.createMinterIfNoneExists.selector, 0)); vm.stopPrank(); ZoraCreatorRedeemMinterStrategy minter = ZoraCreatorRedeemMinterStrategy(predictedAddress); diff --git a/test/minters/redeem/ZoraCreatorRedeemMinterStrategy.t.sol b/test/minters/redeem/ZoraCreatorRedeemMinterStrategy.t.sol index 3be42ba5b..e3a57d9ab 100644 --- a/test/minters/redeem/ZoraCreatorRedeemMinterStrategy.t.sol +++ b/test/minters/redeem/ZoraCreatorRedeemMinterStrategy.t.sol @@ -14,6 +14,7 @@ import {ICreatorRoyaltiesControl} from "../../../src/interfaces/ICreatorRoyaltie import {IZoraCreator1155Factory} from "../../../src/interfaces/IZoraCreator1155Factory.sol"; import {ZoraCreatorRedeemMinterStrategy} from "../../../src/minters/redeem/ZoraCreatorRedeemMinterStrategy.sol"; +/// @notice Contract versions after v1.4.0 will not support burn to redeem contract ZoraCreatorRedeemMinterStrategyTest is Test { ProtocolRewards internal protocolRewards; ZoraCreator1155Impl internal target; @@ -51,7 +52,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { } function test_Version() external { - assertEq(redeemMinter.contractVersion(), "1.0.1"); + assertEq(redeemMinter.contractVersion(), "1.1.0"); } function test_OnlyDropContractCanCallWriteFunctions() external { @@ -59,11 +60,11 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { vm.startPrank(address(admin)); vm.expectRevert(abi.encodeWithSignature("CallerNotCreatorContract()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(0, redeemInstructions); bytes32[] memory hashes = new bytes32[](0); vm.expectRevert(abi.encodeWithSignature("CallerNotCreatorContract()")); - redeemMinter.clearRedeem(hashes); + redeemMinter.clearRedeem(0, hashes); vm.expectRevert(abi.encodeWithSignature("CallerNotCreatorContract()")); redeemMinter.requestMint(address(0), 0, 0, 0, bytes("")); @@ -85,6 +86,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ERC20PresetMinterPauser burnToken = new ERC20PresetMinterPauser("Random Token", "RAND"); burnToken.mint(address(tokenRecipient), 1000); + console2.log("NEW TOKEN ID", newTokenId); ZoraCreatorRedeemMinterStrategy.MintToken memory mintToken = ZoraCreatorRedeemMinterStrategy.MintToken({ tokenContract: address(target), tokenId: newTokenId, @@ -114,12 +116,12 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { vm.expectEmit(true, true, false, true); emit RedeemSet(address(target), keccak256(abi.encode(redeemInstructions)), redeemInstructions); vm.startPrank(address(target)); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); vm.expectRevert(abi.encodeWithSignature("RedeemInstructionAlreadySet()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); vm.stopPrank(); - assertTrue(redeemMinter.redeemInstructionsHashIsAllowed(keccak256(abi.encode(redeemInstructions)))); + assertTrue(redeemMinter.redeemInstructionsHashIsAllowed(newTokenId, keccak256(abi.encode(redeemInstructions)))); } function test_SetRedeemInstructionValidation() external { @@ -161,54 +163,54 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { redeemInstructions.instructions[0].tokenIdStart = 1; redeemInstructions.instructions[0].tokenIdEnd = 0; vm.expectRevert(abi.encodeWithSignature("InvalidTokenIdsForTokenType()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions[0].tokenIdStart = 0; redeemInstructions.instructions[0].tokenIdEnd = 1; vm.expectRevert(abi.encodeWithSignature("InvalidTokenIdsForTokenType()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); // InvalidTokenIdsForTokenType: non ERC20 w/ tokenID start > end redeemInstructions.instructions[0].tokenType = ZoraCreatorRedeemMinterStrategy.TokenType.ERC721; redeemInstructions.instructions[0].tokenIdStart = 4; redeemInstructions.instructions[0].tokenIdEnd = 2; vm.expectRevert(abi.encodeWithSignature("InvalidTokenIdsForTokenType()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.mintToken.tokenType = ZoraCreatorRedeemMinterStrategy.TokenType.ERC1155; vm.expectRevert(abi.encodeWithSignature("InvalidTokenIdsForTokenType()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions[0].tokenIdStart = 0; redeemInstructions.instructions[0].tokenIdEnd = 0; // InvalidTokenType: tokenType is NULL redeemInstructions.instructions[0].tokenType = ZoraCreatorRedeemMinterStrategy.TokenType.NULL; vm.expectRevert(abi.encodeWithSignature("InvalidTokenType()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions[0].tokenType = ZoraCreatorRedeemMinterStrategy.TokenType.ERC1155; // MustBurnOrTransfer: both transferRecipient and burnFunction are 0 redeemInstructions.instructions[0].transferRecipient = address(0); redeemInstructions.instructions[0].burnFunction = bytes4(0); vm.expectRevert(abi.encodeWithSignature("MustBurnOrTransfer()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); // MustBurnOrTransfer: both transferRecipient and burnFunction are non-zero redeemInstructions.instructions[0].transferRecipient = address(1); redeemInstructions.instructions[0].burnFunction = bytes4(keccak256(bytes("burnFrom(address,uint256)"))); vm.expectRevert(abi.encodeWithSignature("MustBurnOrTransfer()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions[0].transferRecipient = address(0); // IncorrectMintAmount redeemInstructions.instructions[0].amount = 0; vm.expectRevert(abi.encodeWithSignature("IncorrectMintAmount()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions[0].amount = 500; // InvalidSaleEndOrStart: start > end redeemInstructions.saleStart = 1; redeemInstructions.saleEnd = 0; vm.expectRevert(abi.encodeWithSignature("InvalidSaleEndOrStart()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.saleStart = 0; redeemInstructions.saleEnd = type(uint64).max; @@ -217,25 +219,25 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { redeemInstructions.saleEnd = 1 days; vm.warp(2 days); vm.expectRevert(abi.encodeWithSignature("InvalidSaleEndOrStart()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.saleEnd = type(uint64).max; // EmptyRedeemInstructions(); redeemInstructions.instructions = new ZoraCreatorRedeemMinterStrategy.RedeemInstruction[](0); vm.expectRevert(abi.encodeWithSignature("EmptyRedeemInstructions()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.instructions = instructions; // MintTokenContractMustBeCreatorContract redeemInstructions.mintToken.tokenContract = address(0); vm.expectRevert(abi.encodeWithSignature("MintTokenContractMustBeCreatorContract()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); redeemInstructions.mintToken.tokenContract = address(target); // MintTokenTypeMustBeERC1155: redeemInstructions.mintToken.tokenType = ZoraCreatorRedeemMinterStrategy.TokenType.ERC721; vm.expectRevert(abi.encodeWithSignature("MintTokenTypeMustBeERC1155()")); - redeemMinter.setRedeem(redeemInstructions); + redeemMinter.setRedeem(newTokenId, redeemInstructions); } ///////// REQUEST MINT ///////// @@ -274,7 +276,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -327,7 +329,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -380,7 +382,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -457,7 +459,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -547,7 +549,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -634,7 +636,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -719,7 +721,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -768,7 +770,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.warp(2 days); @@ -818,7 +820,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -871,7 +873,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: fundsRecipient }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -920,7 +922,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -969,7 +971,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); // instructions length != tokenIds length @@ -1038,7 +1040,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1120,7 +1122,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1178,7 +1180,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1238,7 +1240,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.prank(actualTokenOwner); @@ -1299,7 +1301,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1357,7 +1359,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1417,7 +1419,7 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); vm.stopPrank(); vm.startPrank(tokenRecipient); @@ -1477,12 +1479,12 @@ contract ZoraCreatorRedeemMinterStrategyTest is Test { ethRecipient: address(0) }); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, redeemInstructions)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.setRedeem.selector, newTokenId, redeemInstructions)); bytes32[] memory hashes = new bytes32[](1); hashes[0] = keccak256(abi.encode(redeemInstructions)); vm.expectEmit(true, false, false, true); emit RedeemsCleared(address(target), hashes); - target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.clearRedeem.selector, hashes)); + target.callSale(newTokenId, redeemMinter, abi.encodeWithSelector(ZoraCreatorRedeemMinterStrategy.clearRedeem.selector, newTokenId, hashes)); vm.stopPrank(); vm.startPrank(tokenRecipient); diff --git a/test/nft/ZoraCreator1155.t.sol b/test/nft/ZoraCreator1155.t.sol index 26f2538d6..27bee01c5 100644 --- a/test/nft/ZoraCreator1155.t.sol +++ b/test/nft/ZoraCreator1155.t.sol @@ -88,12 +88,6 @@ contract ZoraCreator1155Test is Test { ); } - // NOTE: This won't work on PRs that update the contract version bc package.json is updated via changesets - // function test_packageJsonVersion() public { - // string memory package = vm.readFile("./package.json"); - // assertEq(package.readString(".version"), target.contractVersion()); - // } - function test_initialize(uint32 royaltySchedule, uint32 royaltyBPS, address royaltyRecipient, address payable defaultAdmin) external { vm.assume(royaltySchedule != 1); vm.assume(royaltyRecipient != address(0) && royaltySchedule != 0 && royaltyBPS != 0); @@ -1008,7 +1002,7 @@ contract ZoraCreator1155Test is Test { target.callSale(tokenId, simpleMinter, abi.encodeWithSignature("setNum(uint256)", 1)); assertEq(simpleMinter.num(), 1); - vm.expectRevert(abi.encodeWithSelector(IZoraCreator1155.CallFailed.selector, "")); + vm.expectRevert(abi.encodeWithSignature("Call_TokenIdMismatch()")); target.callSale(tokenId, simpleMinter, abi.encodeWithSignature("setNum(uint256)", 0)); vm.stopPrank();