Skip to content

Commit

Permalink
small updates, add interfaceId tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanio committed Oct 19, 2023
1 parent 92fcf6b commit c7e540f
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 17 deletions.
21 changes: 13 additions & 8 deletions src/extensions/ERC1155RedemptionMintable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {ERC1155ShipyardContractMetadata} from "../lib/ERC1155ShipyardContractMetadata.sol";
import {IRedemptionMintable} from "../interfaces/IRedemptionMintable.sol";
Expand All @@ -10,6 +11,12 @@ contract ERC1155RedemptionMintable is ERC1155ShipyardContractMetadata, IRedempti
/// @dev The ERC-7498 redeemables contract.
address[] internal _ERC7498_REDEEMABLES_CONTRACTS;

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

/// @dev The number of mints per valid redemption.
uint256 immutable _mintsPerRedemption = 3;

/// @dev Revert if the sender of mintRedemption is not the redeemable contract offerer.
error InvalidSender();

Expand All @@ -36,21 +43,19 @@ contract ERC1155RedemptionMintable is ERC1155ShipyardContractMetadata, IRedempti
revert InvalidSender();
}

// Mint the same token IDs and amounts redeemed.
for (uint256 i = 0; i < consideration.length;) {
ConsiderationItem memory considerationItem = consideration[i];
_mint(recipient, considerationItem.identifierOrCriteria, considerationItem.startAmount, "");
unchecked {
++i;
}
for (uint256 i; i < _mintsPerRedemption; i++) {
// Increment nextTokenId first so more of the same token id cannot be minted through reentrancy.
++_nextTokenId;

_mint(recipient, _nextTokenId - 1, 1, "");
}
}

function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC1155ShipyardContractMetadata)
override(ERC1155ShipyardContractMetadata, IERC165)
returns (bool)
{
return ERC1155ShipyardContractMetadata.supportsInterface(interfaceId)
Expand Down
14 changes: 13 additions & 1 deletion src/extensions/ERC1155ShipyardRedeemableMintable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {ERC721ConduitPreapproved_Solady} from "shipyard-core/src/tokens/erc721/ERC721ConduitPreapproved_Solady.sol";
import {ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {Ownable} from "solady/src/auth/Ownable.sol";
Expand All @@ -18,6 +19,8 @@ contract ERC1155ShipyardRedeemableMintable is ERC1155ShipyardRedeemable, IRedemp
/// @dev The next token id to mint. Each token will have a supply of 1.
uint256 _nextTokenId = 1;

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

function mintRedemption(
uint256, /* campaignId */
address recipient,
Expand All @@ -34,5 +37,14 @@ contract ERC1155ShipyardRedeemableMintable is ERC1155ShipyardRedeemable, IRedemp
_mint(recipient, _nextTokenId - 1, 1, "");
}

constructor(string memory name_, string memory symbol_) ERC1155ShipyardRedeemable(name_, symbol_) {}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC1155ShipyardRedeemable, IERC165)
returns (bool)
{
return interfaceId == type(IRedemptionMintable).interfaceId
|| ERC1155ShipyardRedeemable.supportsInterface(interfaceId);
}
}
7 changes: 4 additions & 3 deletions src/extensions/ERC721RedemptionMintable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {ERC721ShipyardContractMetadata} from "../lib/ERC721ShipyardContractMetadata.sol";
import {IRedemptionMintable} from "../interfaces/IRedemptionMintable.sol";
Expand Down Expand Up @@ -49,10 +50,10 @@ contract ERC721RedemptionMintable is ERC721ShipyardContractMetadata, IRedemption
public
view
virtual
override(ERC721ShipyardContractMetadata)
override(ERC721ShipyardContractMetadata, IERC165)
returns (bool)
{
return ERC721ShipyardContractMetadata.supportsInterface(interfaceId)
|| interfaceId == type(IRedemptionMintable).interfaceId;
return interfaceId == type(IRedemptionMintable).interfaceId
|| ERC721ShipyardContractMetadata.supportsInterface(interfaceId);
}
}
14 changes: 13 additions & 1 deletion src/extensions/ERC721ShipyardRedeemableMintable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {ERC721ConduitPreapproved_Solady} from "shipyard-core/src/tokens/erc721/ERC721ConduitPreapproved_Solady.sol";
import {ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {Ownable} from "solady/src/auth/Ownable.sol";
Expand All @@ -15,6 +16,8 @@ contract ERC721ShipyardRedeemableMintable is ERC721ShipyardRedeemable, IRedempti
/// @dev Revert if the sender of mintRedemption is not this contract.
error InvalidSender();

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

function mintRedemption(
uint256, /* campaignId */
address recipient,
Expand All @@ -27,5 +30,14 @@ contract ERC721ShipyardRedeemableMintable is ERC721ShipyardRedeemable, IRedempti
_mint(recipient, 1);
}

constructor(string memory name_, string memory symbol_) ERC721ShipyardRedeemable(name_, symbol_) {}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721ShipyardRedeemable, IERC165)
returns (bool)
{
return interfaceId == type(IRedemptionMintable).interfaceId
|| ERC721ShipyardRedeemable.supportsInterface(interfaceId);
}
}
3 changes: 2 additions & 1 deletion src/interfaces/IERC7498.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {OfferItem, ConsiderationItem, SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {CampaignParams, TraitRedemption} from "../lib/RedeemablesStructs.sol";

interface IERC7498 {
interface IERC7498 is IERC165 {
event CampaignUpdated(uint256 indexed campaignId, CampaignParams params, string uri);
event Redemption(
uint256 indexed campaignId,
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IRedemptionMintable.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {TraitRedemption} from "../lib/RedeemablesStructs.sol";

interface IRedemptionMintable {
interface IRedemptionMintable is IERC165 {
function mintRedemption(
uint256 campaignId,
address recipient,
Expand Down
9 changes: 8 additions & 1 deletion src/lib/ERC7498NFTRedeemables.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.19;

import {IERC20} from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
import {IERC165} from "openzeppelin-contracts/contracts/interfaces/IERC165.sol";
import {IERC721} from "openzeppelin-contracts/contracts/interfaces/IERC721.sol";
import {IERC1155} from "openzeppelin-contracts/contracts/interfaces/IERC1155.sol";
import {OfferItem, ConsiderationItem, SpentItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
Expand Down Expand Up @@ -399,7 +400,13 @@ contract ERC7498NFTRedeemables is IERC7498, DynamicTraits, RedeemablesErrors {
*/
}

function supportsInterface(bytes4 interfaceId) public view virtual override(DynamicTraits) returns (bool) {
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(DynamicTraits, IERC165)
returns (bool)
{
return interfaceId == type(IERC7498).interfaceId || DynamicTraits.supportsInterface(interfaceId);
}
}
24 changes: 24 additions & 0 deletions test/ERC7498-RedemptionMintable.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BaseRedeemablesTest} from "./utils/BaseRedeemablesTest.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {OfferItemLib} from "seaport-sol/src/lib/OfferItemLib.sol";
import {ConsiderationItemLib} from "seaport-sol/src/lib/ConsiderationItemLib.sol";
import {IRedemptionMintable} from "src/interfaces/IRedemptionMintable.sol";

contract TestERC7498_RedemptionMintable is BaseRedeemablesTest {
using OfferItemLib for OfferItem;
using OfferItemLib for OfferItem[];
using ConsiderationItemLib for ConsiderationItem;
using ConsiderationItemLib for ConsiderationItem[];

function setUp() public virtual override {
super.setUp();
}

function testSupportsInterfaceId() public {
assertTrue(receiveToken721.supportsInterface(type(IRedemptionMintable).interfaceId));
assertTrue(receiveToken1155.supportsInterface(type(IRedemptionMintable).interfaceId));
}
}
29 changes: 29 additions & 0 deletions test/ERC7498.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BaseRedeemablesTest} from "./utils/BaseRedeemablesTest.sol";
import {OfferItem, ConsiderationItem} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {OfferItemLib} from "seaport-sol/src/lib/OfferItemLib.sol";
import {ConsiderationItemLib} from "seaport-sol/src/lib/ConsiderationItemLib.sol";
import {IERC7498} from "../src/interfaces/IERC7498.sol";

contract TestERC7498 is BaseRedeemablesTest {
using OfferItemLib for OfferItem;
using OfferItemLib for OfferItem[];
using ConsiderationItemLib for ConsiderationItem;
using ConsiderationItemLib for ConsiderationItem[];

function setUp() public virtual override {
super.setUp();
}

function testSupportsInterfaceId() public {
for (uint256 i; i < erc7498Tokens.length; i++) {
testRedeemable(this.supportsInterfaceId, RedeemablesContext({erc7498Token: IERC7498(erc7498Tokens[i])}));
}
}

function supportsInterfaceId(RedeemablesContext memory context) public {
assertTrue(context.erc7498Token.supportsInterface(type(IERC7498).interfaceId));
}
}

0 comments on commit c7e540f

Please sign in to comment.