diff --git a/test/ERC7498-DynamicTraits.t.sol b/test/ERC7498-DynamicTraits.t.sol index 13946bc..2b0c26b 100644 --- a/test/ERC7498-DynamicTraits.t.sol +++ b/test/ERC7498-DynamicTraits.t.sol @@ -11,6 +11,7 @@ import {IERC721A} from "seadrop/lib/ERC721A/contracts/IERC721A.sol"; import {IERC721} from "openzeppelin-contracts/contracts/interfaces/IERC721.sol"; import {IERC1155} from "openzeppelin-contracts/contracts/interfaces/IERC1155.sol"; import {IERC7498} from "../../src/interfaces/IERC7498.sol"; +import {DynamicTraits} from "shipyard-core/src/dynamic-traits/DynamicTraits.sol"; import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol"; import {ItemType, OrderType, Side} from "seaport-sol/src/SeaportEnums.sol"; import {OfferItemLib} from "seaport-sol/src/lib/OfferItemLib.sol"; @@ -19,6 +20,8 @@ import {CampaignParams, CampaignRequirements, TraitRedemption} from "../src/lib/ import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol"; import {ERC721ShipyardRedeemableOwnerMintable} from "../src/test/ERC721ShipyardRedeemableOwnerMintable.sol"; import {ERC1155ShipyardRedeemableOwnerMintable} from "../src/test/ERC1155ShipyardRedeemableOwnerMintable.sol"; +import {ERC721ShipyardRedeemablePreapprovedTraitSetters} from + "../src/test/ERC721ShipyardRedeemablePreapprovedTraitSetters.sol"; import {ERC1155ShipyardRedeemableMintable} from "../src/extensions/ERC1155ShipyardRedeemableMintable.sol"; contract ERC7498_DynamicTraits is BaseRedeemablesTest { @@ -59,22 +62,77 @@ contract ERC7498_DynamicTraits is BaseRedeemablesTest { } function erc721TraitRedemptionSubstandardOneForErc721(RedeemablesContext memory context) public { - _mintToken(address(context.erc7498Token), tokenId, context.isErc7498Token721); + address[] memory allowedTraitSetters = new address[](1); + allowedTraitSetters[0] = address(context.erc7498Token); + + ERC721ShipyardRedeemablePreapprovedTraitSetters redeemToken = + new ERC721ShipyardRedeemablePreapprovedTraitSetters( + "Test", + "TEST", + allowedTraitSetters + ); + redeemToken.mint(address(this), tokenId); TraitRedemption[] memory traitRedemptions = new TraitRedemption[](1); // trait key is "hasRedeemed" + bytes32 traitKey = bytes32(bytes(string("hasRedeemed"))); + // previous trait value (`substandardValue`) should be 0 // new trait value should be 1 traitRedemptions[0] = TraitRedemption({ substandard: 1, - token: address(context.erc7498Token), - identifier: tokenId, - traitKey: bytes32(bytes(string("hasRedeemed"))), + token: address(redeemToken), + identifier: 0, // unused field + traitKey: traitKey, traitValue: bytes32(uint256(1)), substandardValue: bytes32(uint256(0)) }); + // consideration is empty ConsiderationItem[] memory consideration = new ConsiderationItem[](0); + + CampaignRequirements[] memory requirements = new CampaignRequirements[]( + 1 + ); + + requirements[0] = CampaignRequirements({ + offer: defaultCampaignOffer, + consideration: consideration, + traitRedemptions: traitRedemptions + }); + + CampaignParams memory params = CampaignParams({ + requirements: requirements, + signer: address(0), + startTime: uint32(block.timestamp), + endTime: uint32(block.timestamp + 1000), + maxCampaignRedemptions: 5, + manager: address(this) + }); + + context.erc7498Token.createCampaign(params, ""); + + uint256[] memory considerationTokenIds = new uint256[](0); + uint256[] memory traitRedemptionTokenIds = Solarray.uint256s(tokenId); + + // campaignId: 1 + // requirementsIndex: 0 + // redemptionHash: bytes32(0) + // traitRedemptionTokenIds: traitRedemptionTokenIds + // salt: 0 + // signature: bytes(0) + bytes memory extraData = abi.encode(1, 0, bytes32(0), traitRedemptionTokenIds, uint256(0), bytes("")); + + vm.expectEmit(true, true, true, true); + emit Redemption(1, 0, bytes32(0), considerationTokenIds, traitRedemptionTokenIds, address(this)); + + context.erc7498Token.redeem(considerationTokenIds, address(this), extraData); + + bytes32 actualTraitValue = DynamicTraits(address(redeemToken)).getTraitValue(tokenId, traitKey); + + assertEq(bytes32(uint256(1)), actualTraitValue); + + assertEq(IERC721(address(context.erc7498Token)).ownerOf(tokenId), address(this)); } } diff --git a/test/ERC7498-MultiRedeem.t.sol b/test/ERC7498-MultiRedeem.t.sol index 0846842..fde03f2 100644 --- a/test/ERC7498-MultiRedeem.t.sol +++ b/test/ERC7498-MultiRedeem.t.sol @@ -106,7 +106,7 @@ contract ERC7498_MultiRedeem is BaseRedeemablesTest { // campaignId: 1 // requirementsIndex: 0 // redemptionHash: bytes32(0) - bytes memory extraData = abi.encode(1, 0, bytes32(0)); + bytes memory extraData = abi.encode(1, 0, bytes32(0), defaultTraitRedemptionTokenIds, uint256(0), bytes("")); consideration[0].identifierOrCriteria = tokenId; uint256[] memory tokenIds = Solarray.uint256s(tokenId, tokenId); @@ -120,6 +120,7 @@ contract ERC7498_MultiRedeem is BaseRedeemablesTest { _checkTokenSentToBurnAddress(secondRedeemTokenAddress, tokenId, context.isErc7498Token721); assertEq(receiveToken721.ownerOf(1), address(this)); + assertEq(receiveToken721.balanceOf(address(this)), 1); } function testBurnOneErc721OrErc1155RedeemMultiErc1155() public { @@ -196,7 +197,7 @@ contract ERC7498_MultiRedeem is BaseRedeemablesTest { // campaignId: 1 // requirementsIndex: 0 // redemptionHash: bytes32(0) - bytes memory extraData = abi.encode(1, 0, bytes32(0)); + bytes memory extraData = abi.encode(1, 0, bytes32(0), defaultTraitRedemptionTokenIds, uint256(0), bytes("")); consideration[0].identifierOrCriteria = tokenId; uint256[] memory tokenIds = Solarray.uint256s(tokenId);