Skip to content

Commit

Permalink
Merge pull request #155 from ourzora/isabella/remove-old-purchase-wit…
Browse files Browse the repository at this point in the history
…hout-rewards

Remove old purchase without rewards functions
  • Loading branch information
IsabellaSmallcombe committed Sep 25, 2023
2 parents 11afe08 + 4fa7404 commit 6361928
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 86 deletions.
5 changes: 5 additions & 0 deletions .changeset/nervous-roses-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@zoralabs/nft-drop-contracts': minor
---

Removing old purchase without rewards functions for purchase and purchasePresale
87 changes: 9 additions & 78 deletions src/ERC721Drop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ contract ERC721Drop is
onlyPublicSaleActive
returns (uint256)
{
return _handlePurchase(msg.sender, quantity, "");
return _handleMintWithRewards(msg.sender, quantity, "", address(0));
}

/// @notice Purchase a quantity of tokens with a comment
Expand All @@ -466,7 +466,7 @@ contract ERC721Drop is
onlyPublicSaleActive
returns (uint256)
{
return _handlePurchase(msg.sender, quantity, comment);
return _handleMintWithRewards(msg.sender, quantity, comment, address(0));
}

/// @notice Purchase a quantity of tokens to a specified recipient, with an optional comment
Expand All @@ -481,7 +481,7 @@ contract ERC721Drop is
onlyPublicSaleActive
returns (uint256)
{
return _handlePurchase(recipient, quantity, comment);
return _handleMintWithRewards(recipient, quantity, comment, address(0));
}

/// @notice Mint a quantity of tokens with a comment that will pay out rewards
Expand All @@ -501,7 +501,7 @@ contract ERC721Drop is
return _handleMintWithRewards(recipient, quantity, comment, mintReferral);
}

function _handleMintWithRewards(address recipient, uint256 quantity, string calldata comment, address mintReferral) internal returns (uint256) {
function _handleMintWithRewards(address recipient, uint256 quantity, string memory comment, address mintReferral) internal returns (uint256) {
_mintSupplyRoyalty(quantity);
_requireCanPurchaseQuantity(recipient, quantity);

Expand All @@ -518,25 +518,6 @@ contract ERC721Drop is
return firstMintedTokenId;
}

function _handlePurchase(address recipient, uint256 quantity, string memory comment) internal returns (uint256) {
_mintSupplyRoyalty(quantity);
_requireCanMintQuantity(quantity);
_requireCanPurchaseQuantity(recipient, quantity);

uint256 salePrice = salesConfig.publicSalePrice;

_requireLegacyFee(msg.value, salePrice, quantity);

_mintNFTs(recipient, quantity);
uint256 firstMintedTokenId = _lastMintedTokenId() - quantity;

_payoutZoraFee(quantity);

_emitSaleEvents(_msgSender(), recipient, quantity, salePrice, firstMintedTokenId, comment);

return firstMintedTokenId;
}

/// @notice Function to mint NFTs
/// @dev (important: Does not enforce max supply limit, enforce that limit earlier)
/// @dev This batches in size of 8 as per recommended by ERC721A creators
Expand Down Expand Up @@ -626,11 +607,9 @@ contract ERC721Drop is
)
external
payable
nonReentrant
onlyPresaleActive
returns (uint256)
{
return _handlePurchasePresale(quantity, maxQuantity, pricePerToken, merkleProof, "");
return purchasePresaleWithRewards(quantity, maxQuantity, pricePerToken, merkleProof, "", address(0));
}

/// @notice Merkle-tree based presale purchase function with a comment
Expand All @@ -652,49 +631,7 @@ contract ERC721Drop is
onlyPresaleActive
returns (uint256)
{
return _handlePurchasePresale(quantity, maxQuantity, pricePerToken, merkleProof, comment);
}

function _handlePurchasePresale(
uint256 quantity,
uint256 maxQuantity,
uint256 pricePerToken,
bytes32[] calldata merkleProof,
string memory comment
) internal returns (uint256) {
_mintSupplyRoyalty(quantity);
_requireCanMintQuantity(quantity);

address msgSender = _msgSender();

_requireMerkleApproval(msgSender, maxQuantity, pricePerToken, merkleProof);

_requireLegacyFee(msg.value, pricePerToken, quantity);

_requireCanPurchasePresale(msgSender, quantity, maxQuantity);

_mintNFTs(msgSender, quantity);
uint256 firstMintedTokenId = _lastMintedTokenId() - quantity;

_payoutZoraFee(quantity);

emit IERC721Drop.Sale({
to: msgSender,
quantity: quantity,
pricePerToken: pricePerToken,
firstPurchasedTokenId: firstMintedTokenId
});
if (bytes(comment).length > 0) {
emit IERC721Drop.MintComment({
sender: msgSender,
tokenContract: address(this),
tokenId: firstMintedTokenId,
quantity: quantity,
comment: comment
});
}

return firstMintedTokenId;
return purchasePresaleWithRewards(quantity, maxQuantity, pricePerToken, merkleProof, comment, address(0));
}

/// @notice Merkle-tree based presale purchase function with a comment and protocol rewards
Expand All @@ -709,10 +646,10 @@ contract ERC721Drop is
uint256 maxQuantity,
uint256 pricePerToken,
bytes32[] calldata merkleProof,
string calldata comment,
string memory comment,
address mintReferral
)
external
public
payable
nonReentrant
onlyPresaleActive
Expand All @@ -726,7 +663,7 @@ contract ERC721Drop is
uint256 maxQuantity,
uint256 pricePerToken,
bytes32[] calldata merkleProof,
string calldata comment,
string memory comment,
address mintReferral
) internal returns (uint256) {
_mintSupplyRoyalty(quantity);
Expand Down Expand Up @@ -1281,12 +1218,6 @@ contract ERC721Drop is
emit MintFeePayout(zoraFee, ZORA_MINT_FEE_RECIPIENT, success);
}

function _requireLegacyFee(uint256 msgValue, uint256 salePrice, uint256 quantity) internal view {
if (msgValue != (salePrice + ZORA_MINT_FEE) * quantity) {
revert Purchase_WrongPrice((salePrice + ZORA_MINT_FEE) * quantity);
}
}

function _requireCanMintQuantity(uint256 quantity) internal view {
if (quantity + _totalMinted() > config.editionSize) {
revert Mint_SoldOut();
Expand Down
46 changes: 40 additions & 6 deletions test/ERC721Drop.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,38 @@ contract ERC721DropTest is Test {
assertEq(royaltyAmount, 0 ether);
}

function test_Purchase(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) {
function test_PurchaseFreeMint(uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) {
vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0);
vm.prank(DEFAULT_OWNER_ADDRESS);
zoraNFTBase.setSaleConfiguration({
publicSaleStart: 0,
publicSaleEnd: type(uint64).max,
presaleStart: 0,
presaleEnd: 0,
publicSalePrice: 0,
maxSalePurchasePerAddress: purchaseQuantity + 1,
presaleMerkleRoot: bytes32(0)
});

(, uint256 protocolFee) = zoraNFTBase.zoraFeeForAmount(purchaseQuantity);
uint256 paymentAmount = protocolFee;
vm.deal(address(456), paymentAmount);
vm.prank(address(456));
vm.expectEmit(true, true, true, true);
emit Sale(address(456), purchaseQuantity, 0, 0);
zoraNFTBase.purchase{value: paymentAmount}(purchaseQuantity);

assertEq(zoraNFTBase.saleDetails().maxSupply, purchaseQuantity);
assertEq(zoraNFTBase.saleDetails().totalMinted, purchaseQuantity);
require(zoraNFTBase.ownerOf(1) == address(456), "owner is wrong for new minted token");
assertEq(address(zoraNFTBase).balance, paymentAmount - protocolFee);
assertEq(address(protocolRewards).balance, protocolFee);
assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), 0.000444 ether * purchaseQuantity);
assertEq(protocolRewards.balanceOf(mintFeeRecipient), 0.000333 ether * purchaseQuantity);
}

function test_PurchaseWithValue(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) {
vm.assume(salePrice > 0);
vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0);
vm.prank(DEFAULT_OWNER_ADDRESS);
zoraNFTBase.setSaleConfiguration({
Expand All @@ -230,8 +261,12 @@ contract ERC721DropTest is Test {
assertEq(zoraNFTBase.saleDetails().maxSupply, purchaseQuantity);
assertEq(zoraNFTBase.saleDetails().totalMinted, purchaseQuantity);
require(zoraNFTBase.ownerOf(1) == address(456), "owner is wrong for new minted token");

assertEq(address(zoraNFTBase).balance, paymentAmount - zoraFee);
assertEq(mintFeeRecipient.balance, zoraFee);
assertEq(address(protocolRewards).balance, zoraFee);
assertEq(protocolRewards.balanceOf(mintFeeRecipient), 0.000666 ether * purchaseQuantity);
assertEq(address(zoraNFTBase).balance, uint256(salePrice) * uint256(purchaseQuantity));
assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), 0.000111 ether * uint256(purchaseQuantity));
}

function test_PurchaseWithComment(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) {
Expand Down Expand Up @@ -787,9 +822,8 @@ contract ERC721DropTest is Test {
maxSalePurchasePerAddress: 2,
presaleMerkleRoot: bytes32(0)
});
(, uint256 fee) = zoraNFTBase.zoraFeeForAmount(1);
vm.prank(address(456));
vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Purchase_WrongPrice.selector, 0.15 ether + fee));
vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()"));
zoraNFTBase.purchase{value: 0.12 ether}(1);
}

Expand Down Expand Up @@ -940,7 +974,7 @@ contract ERC721DropTest is Test {
vm.expectRevert(IERC721Drop.Mint_SoldOut.selector);
vm.prank(DEFAULT_OWNER_ADDRESS);
zoraNFTBase.adminMint(address(0x1234), 2);
vm.expectRevert(IERC721Drop.Mint_SoldOut.selector);
vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()"));
zoraNFTBase.purchase{value: 0.6 ether}(3);
}

Expand Down Expand Up @@ -981,7 +1015,7 @@ contract ERC721DropTest is Test {

vm.deal(address(456), uint256(1) * 2);
vm.prank(address(456));
vm.expectRevert(IERC721Drop.Mint_SoldOut.selector);
vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()"));
zoraNFTBase.purchase{value: 1}(1);
}

Expand Down
3 changes: 1 addition & 2 deletions test/merkle/MerkleDrop.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,10 @@ contract ZoraNFTBaseTest is Test {
MerkleData.MerkleEntry memory item;

item = merkleData.getTestSetByName("test-3-addresses").entries[0];
(, uint256 fee) = zoraNFTBase.zoraFeeForAmount(1);
vm.deal(address(item.user), 1 ether);
vm.startPrank(address(item.user));

vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Purchase_WrongPrice.selector, item.mintPrice + fee));
vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()"));
zoraNFTBase.purchasePresale{value: item.mintPrice - 1}(1, item.maxMint, item.mintPrice, item.proof);
assertEq(zoraNFTBase.saleDetails().maxSupply, 10);
assertEq(zoraNFTBase.saleDetails().totalMinted, 0);
Expand Down

0 comments on commit 6361928

Please sign in to comment.