Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanio committed Nov 2, 2023
1 parent dc41bb1 commit 0337999
Show file tree
Hide file tree
Showing 20 changed files with 145 additions and 227 deletions.
8 changes: 3 additions & 5 deletions script/DeployAndConfigure1155Receive.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import {Test} from "forge-std/Test.sol";
import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {CampaignParams, CampaignRequirements} from "../src/lib/RedeemablesStructs.sol";
import {BURN_ADDRESS} from "../src/lib/RedeemablesConstants.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {ERC721OwnerMintable} from "../src/test/ERC721OwnerMintable.sol";
import {ERC1155ShipyardRedeemableMintable} from "../src/extensions/ERC1155ShipyardRedeemableMintable.sol";

contract DeployAndConfigure1155Receive is Script, Test {
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

Expand Down Expand Up @@ -51,7 +50,7 @@ contract DeployAndConfigure1155Receive is Script, Test {
identifierOrCriteria: 0,
startAmount: 1,
endAmount: 1,
recipient: payable(_BURN_ADDRESS)
recipient: payable(BURN_ADDRESS)
});

CampaignRequirements[] memory requirements = new CampaignRequirements[](
Expand All @@ -68,8 +67,7 @@ contract DeployAndConfigure1155Receive is Script, Test {
maxCampaignRedemptions: 1_000,
manager: msg.sender
});
uint256 campaignId =
receiveToken.createCampaign(params, "ipfs://QmQjubc6guHReNW5Es5ZrgDtJRwXk2Aia7BkVoLJGaCRqP");
receiveToken.createCampaign(params, "ipfs://QmQjubc6guHReNW5Es5ZrgDtJRwXk2Aia7BkVoLJGaCRqP");

// To test updateCampaign, update to proper start/end times.
params.startTime = uint32(block.timestamp);
Expand Down
5 changes: 2 additions & 3 deletions script/DeployAndConfigureExampleCampaign.s.sol.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {RedeemableContractOfferer} from "../src/RedeemableContractOfferer.sol";
import {CampaignParams} from "../src/lib/RedeemablesStructs.sol";
import {BURN_ADDRESS} from "../src/lib/RedeemablesConstants.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {TestERC721} from "../test/utils/mocks/TestERC721.sol";

Expand All @@ -16,8 +17,6 @@ contract DeployAndConfigureExampleCampaign is Script {
address conduit = 0x1E0049783F008A0085193E00003D00cd54003c71;
bytes32 conduitKey = 0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000;

address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

Expand Down Expand Up @@ -49,7 +48,7 @@ contract DeployAndConfigureExampleCampaign is Script {
identifierOrCriteria: 0,
startAmount: 1,
endAmount: 1,
recipient: payable(_BURN_ADDRESS)
recipient: payable(BURN_ADDRESS)
});

CampaignParams memory params = CampaignParams({
Expand Down
48 changes: 20 additions & 28 deletions script/DeployAndRedeemTokens-CampaignOnReceiveToken.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ import {Test} from "forge-std/Test.sol";
import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {CampaignParams, CampaignRequirements} from "../src/lib/RedeemablesStructs.sol";
import {BURN_ADDRESS} from "../src/lib/RedeemablesConstants.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {ERC721OwnerMintable} from "../src/test/ERC721OwnerMintable.sol";
import {ERC721ShipyardRedeemableMintable} from "../src/extensions/ERC721ShipyardRedeemableMintable.sol";

contract DeployAndRedeemTokens_CampaignOnReceiveToken is Script, Test {
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

ERC721ShipyardRedeemableMintable redeemToken =
ERC721ShipyardRedeemableMintable(0xe0535403Af71813B59bcEae5F8F6685B7daF6d07);
ERC721ShipyardRedeemableMintable receiveToken = new ERC721ShipyardRedeemableMintable(
"Demo 721 Receive Token",
"DemoReceive721"
);
ERC721OwnerMintable redeemToken = new ERC721OwnerMintable();
ERC721ShipyardRedeemableMintable receiveToken =
new ERC721ShipyardRedeemableMintable("TestRedeemablesReceiveToken", "TEST");

// Configure the campaign.
OfferItem[] memory offer = new OfferItem[](1);
Expand All @@ -40,7 +36,7 @@ contract DeployAndRedeemTokens_CampaignOnReceiveToken is Script, Test {
identifierOrCriteria: 0,
startAmount: 1,
endAmount: 1,
recipient: payable(_BURN_ADDRESS)
recipient: payable(BURN_ADDRESS)
});

CampaignRequirements[] memory requirements = new CampaignRequirements[](
Expand All @@ -60,31 +56,27 @@ contract DeployAndRedeemTokens_CampaignOnReceiveToken is Script, Test {
uint256 campaignId =
receiveToken.createCampaign(params, "ipfs://QmQKc93y2Ev5k9Kz54mCw48ZM487bwGDktZYPLtrjJ3r1d");

assertEq(campaignId, 1);
// // redeemToken.setBaseURI(
// // "ipfs://QmYTSupCtriDLBHgPBBhZ98wYdp6N9S8jTL5sKSZwbASeT"
// // );
receiveToken.setBaseURI("ipfs://QmWxgnz8T9wsMBmpCY4Cvanj3RR1obFD2hqDKPZhKN5Tsq/");

// // Mint token 1 to redeem for token 1.
// redeemToken.mint(msg.sender, 1);
// Mint token 1 to redeem for token 1.
redeemToken.mint(msg.sender, 1);

// Let's redeem them!
// uint256 requirementsIndex = 0;
// bytes32 redemptionHash = bytes32(0);
// bytes memory data = abi.encode(1, requirementsIndex, redemptionHash);
uint256 requirementsIndex = 0;
bytes32 redemptionHash;
uint256 salt;
bytes memory signature;
bytes memory data = abi.encode(campaignId, requirementsIndex, redemptionHash, salt, signature);

// uint256[] memory tokenIds = new uint256[](1);
// tokenIds[0] = 2;
uint256[] memory tokenIds = new uint256[](1);
tokenIds[0] = 1;

// // Individual user approvals not needed when setting the burn address.
// // redeemToken.setApprovalForAll(address(receiveToken), true);
// // redeemToken.setBurnAddress(address(receiveToken));
// Individual user approvals not needed when setting the burn address.
redeemToken.setApprovalForAll(address(receiveToken), true);
// redeemToken.setBurnAddress(address(receiveToken));

// receiveToken.redeem(tokenIds, msg.sender, data);
receiveToken.redeem(tokenIds, msg.sender, data);

// Assert redeemable token is burned and redemption token is minted.
// assertEq(redeemToken.balanceOf(msg.sender), 0);
// assertEq(receiveToken.ownerOf(1), msg.sender);
assertEq(redeemToken.balanceOf(msg.sender), 0);
assertEq(receiveToken.ownerOf(1), msg.sender);
}
}
5 changes: 2 additions & 3 deletions script/DeployAndRedeemTokens.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import {Test} from "forge-std/Test.sol";
import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {CampaignParams, CampaignRequirements} from "../src/lib/RedeemablesStructs.sol";
import {BURN_ADDRESS} from "../src/lib/RedeemablesConstants.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {ERC721ShipyardRedeemableOwnerMintable} from "../src/test/ERC721ShipyardRedeemableOwnerMintable.sol";

contract DeployAndRedeemTokens is Script, Test {
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

Expand Down Expand Up @@ -44,7 +43,7 @@ contract DeployAndRedeemTokens is Script, Test {
identifierOrCriteria: 0,
startAmount: 1,
endAmount: 1,
recipient: payable(_BURN_ADDRESS)
recipient: payable(BURN_ADDRESS)
});

CampaignRequirements[] memory requirements = new CampaignRequirements[](
Expand Down
8 changes: 2 additions & 6 deletions script/DeployAndRedeemTrait.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import {Script} from "forge-std/Script.sol";
import {Test} from "forge-std/Test.sol";
import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {DynamicTraits} from "shipyard-core/src/dynamic-traits/DynamicTraits.sol";
import {IERC7496} from "shipyard-core/src/dynamic-traits/interfaces/IERC7496.sol";
import {CampaignParams, CampaignRequirements, TraitRedemption} from "../src/lib/RedeemablesStructs.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {ERC721ShipyardRedeemableMintable} from "../src/extensions/ERC721ShipyardRedeemableMintable.sol";
import {ERC721ShipyardRedeemablePreapprovedTraitSetters} from
"../src/test/ERC721ShipyardRedeemablePreapprovedTraitSetters.sol";

contract DeployAndRedeemTrait is Script, Test {
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

Expand Down Expand Up @@ -107,11 +105,9 @@ contract DeployAndRedeemTrait is Script, Test {
receiveToken.redeem(new uint256[](0), msg.sender, data);

// Assert new trait has been set and redemption token is minted.
bytes32 actualTraitValue = DynamicTraits(address(redeemToken)).getTraitValue(1, traitKey);

bytes32 actualTraitValue = IERC7496(address(redeemToken)).getTraitValue(1, traitKey);
// "hasRedeemed" should be 1 (true)
assertEq(bytes32(uint256(1)), actualTraitValue);

assertEq(receiveToken.ownerOf(1), msg.sender);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import {Test} from "forge-std/Test.sol";
import {ItemType} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {CampaignParams, CampaignRequirements} from "../src/lib/RedeemablesStructs.sol";
import {BURN_ADDRESS} from "../src/lib/RedeemablesConstants.sol";
import {ERC721RedemptionMintable} from "../src/extensions/ERC721RedemptionMintable.sol";
import {ERC721OwnerMintable} from "../src/test/ERC721OwnerMintable.sol";
import {ERC721ShipyardRedeemableMintable} from "../src/extensions/ERC721ShipyardRedeemableMintable.sol";

contract DeployERC721ReceiveTokenWithPredeployedSeadropRedeemToken is Script, Test {
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function run() external {
vm.startBroadcast();

Expand All @@ -38,7 +37,7 @@ contract DeployERC721ReceiveTokenWithPredeployedSeadropRedeemToken is Script, Te
identifierOrCriteria: 0,
startAmount: 1,
endAmount: 1,
recipient: payable(_BURN_ADDRESS)
recipient: payable(BURN_ADDRESS)
});

CampaignRequirements[] memory requirements = new CampaignRequirements[](
Expand Down
4 changes: 2 additions & 2 deletions script/RedeemTokens.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ contract RedeemTokens is Script, Test {
function run() external {
vm.startBroadcast();

address redeemToken = 0x1eCC76De3f9E4e9f8378f6ade61A02A10f976c45;
// address redeemToken = 0x1eCC76De3f9E4e9f8378f6ade61A02A10f976c45;
ERC1155ShipyardRedeemableMintable receiveToken =
ERC1155ShipyardRedeemableMintable(0x3D0fa2a8D07dfe357905a4cB4ed51b0Aea8385B9);

// Let's redeem them!
uint256 campaignId = 1;
uint256 requirementsIndex = 0;
bytes32 redemptionHash = bytes32(0);
bytes memory data = abi.encode(campaignId, requirementsIndex, redemptionHash);
bytes memory data = abi.encode(campaignId, requirementsIndex, redemptionHash, bytes32(0), "");

uint256[] memory redeemTokenIds = new uint256[](1);
redeemTokenIds[0] = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/extensions/ERC1155RedemptionMintable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ contract ERC1155RedemptionMintable is ERC1155ShipyardContractMetadata, IRedempti
function mintRedemption(
uint256, /* campaignId */
address recipient,
ConsiderationItem[] calldata consideration,
ConsiderationItem[] calldata, /* consideration */
TraitRedemption[] calldata /* traitRedemptions */
) external {
bool validSender;
Expand Down
39 changes: 0 additions & 39 deletions src/extensions/ERC721ShipyardRedeemableMintable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@ import {TraitRedemption} from "../lib/RedeemablesStructs.sol";
contract ERC721ShipyardRedeemableMintable is ERC721ShipyardRedeemable, IRedemptionMintable {
/// @dev Revert if the sender of mintRedemption is not this contract.
error InvalidSender();
error InvalidTokenURIQuery();

/// @dev The next token id to mint.
uint256 _nextTokenId = 1;

mapping(uint256 => uint256) public tokenURINumbers;

constructor(string memory name_, string memory symbol_) ERC721ShipyardRedeemable(name_, symbol_) {}

function mintRedemption(
Expand Down Expand Up @@ -49,40 +46,4 @@ contract ERC721ShipyardRedeemableMintable is ERC721ShipyardRedeemable, IRedempti
return interfaceId == type(IRedemptionMintable).interfaceId
|| ERC721ShipyardRedeemable.supportsInterface(interfaceId);
}

/**
* @notice Hook to set tokenURINumber on mint.
*/
function _beforeTokenTransfer(address from, address, /* to */ uint256 id) internal virtual override {
// Set tokenURINumbers on mint.
if (from == address(0)) {
// 60% chance of tokenURI 1
// 30% chance of tokenURI 2
// 10% chance of tokenURI 3

// block.difficulty returns PREVRANDAO on Ethereum post-merge
// NOTE: do not use this on other chains
uint256 randomness = (uint256(keccak256(abi.encode(block.difficulty))) % 100) + 1;

uint256 tokenURINumber = 1;
if (randomness >= 60 && randomness < 90) {
tokenURINumber = 2;
} else if (randomness >= 90) {
tokenURINumber = 3;
}

tokenURINumbers[id] = tokenURINumber;
}
}

/*
* @notice Overrides the `tokenURI()` function to return baseURI + 1, 2, or 3
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
if (!_exists(tokenId)) revert InvalidTokenURIQuery();

uint256 tokenURINumber = tokenURINumbers[tokenId];

return string(abi.encodePacked(baseURI, _toString(tokenURINumber)));
}
}
23 changes: 10 additions & 13 deletions src/lib/ERC7498NFTRedeemables.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {IERC7498} from "../interfaces/IERC7498.sol";
import {IRedemptionMintable} from "../interfaces/IRedemptionMintable.sol";
import {RedeemablesErrors} from "./RedeemablesErrors.sol";
import {CampaignParams, CampaignRequirements, TraitRedemption} from "./RedeemablesStructs.sol";
import {BURN_ADDRESS} from "./RedeemablesConstants.sol";

contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesErrors {
/// @dev Counter for next campaign id.
Expand All @@ -30,9 +31,6 @@ contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesE
/// @dev The total current redemptions by campaign id.
mapping(uint256 campaignId => uint256 count) private _totalRedemptions;

/// @dev The burn address.
address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

function redeem(uint256[] calldata considerationTokenIds, address recipient, bytes calldata extraData)
public
payable
Expand All @@ -43,16 +41,15 @@ contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesE
}

// Get the values from extraData.
// uint256 campaignId = uint256(bytes32(extraData[0:32]));
// uint256 requirementsIndex = uint256(bytes32(extraData[32:64]));
// uint256[] memory traitRedemptionTokenIds;
(
uint256 campaignId,
uint256 requirementsIndex,
bytes32 redemptionHash,
/* bytes32 redemptionHash */
,
uint256[] memory traitRedemptionTokenIds,
uint256 salt,
bytes memory signature
/* uint256 salt */
,
/*bytes memory signature */
) = abi.decode(extraData, (uint256, uint256, bytes32, uint256[], uint256, bytes));

// Get the campaign params.
Expand Down Expand Up @@ -223,13 +220,13 @@ contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesE

// If consideration item is this contract, recipient is burn address, and _useInternalBurn() fn returns true,
// call the internal burn function and return.
if (c.token == address(this) && c.recipient == payable(_BURN_ADDRESS) && _useInternalBurn()) {
if (c.token == address(this) && c.recipient == payable(BURN_ADDRESS) && _useInternalBurn()) {
_internalBurn(msg.sender, id, c.startAmount);
} else {
// Transfer the token to the consideration recipient.
if (c.itemType == ItemType.ERC721 || c.itemType == ItemType.ERC721_WITH_CRITERIA) {
// If recipient is the burn address, try burning the token first, if that doesn't work use transfer.
if (c.recipient == payable(_BURN_ADDRESS)) {
if (c.recipient == payable(BURN_ADDRESS)) {
try ERC721Burnable(c.token).burn(id) {
// If the burn worked, return.
return;
Expand All @@ -241,7 +238,7 @@ contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesE
IERC721(c.token).safeTransferFrom(msg.sender, c.recipient, id);
}
} else if ((c.itemType == ItemType.ERC1155 || c.itemType == ItemType.ERC1155_WITH_CRITERIA)) {
if (c.recipient == payable(_BURN_ADDRESS)) {
if (c.recipient == payable(BURN_ADDRESS)) {
// If recipient is the burn address, try burning the token first, if that doesn't work use transfer.
try ERC1155Burnable(c.token).burn(msg.sender, id, c.startAmount) {
// If the burn worked, return.
Expand All @@ -254,7 +251,7 @@ contract ERC7498NFTRedeemables is IERC165, IERC7498, DynamicTraits, RedeemablesE
IERC1155(c.token).safeTransferFrom(msg.sender, c.recipient, id, c.startAmount, "");
}
} else if (c.itemType == ItemType.ERC20) {
if (c.recipient == payable(_BURN_ADDRESS)) {
if (c.recipient == payable(BURN_ADDRESS)) {
// If recipient is the burn address, try burning the token first, if that doesn't work use transfer.
try ERC20Burnable(c.token).burnFrom(msg.sender, c.startAmount) {
// If the burn worked, return.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/RedeemablesConstants.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

address constant _BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
address constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
3 changes: 3 additions & 0 deletions src/test/ERC721ShipyardRedeemablePreapprovedTraitSetters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {DynamicTraits} from "shipyard-core/src/dynamic-traits/DynamicTraits.sol"
import {CampaignParams} from "../lib/RedeemablesStructs.sol";

contract ERC721ShipyardRedeemablePreapprovedTraitSetters is ERC721ShipyardRedeemableOwnerMintable {
// TODO add the `allowedTraitSetters` logic to DynamicTraits.sol contract in shipyard-core
// with getAllowedTraitSetters() and setAllowedTraitSetters(). add `is DynamicTraits` to
// ERC721ShipyardRedeemable and ERC721SeaDropRedeemable contracts with onlyOwner on setAllowedTraitSetters().
address[] public allowedTraitSetters;

constructor(string memory name_, string memory symbol_, address[] memory allowedTraitSetters_)
Expand Down
Loading

0 comments on commit 0337999

Please sign in to comment.