diff --git a/foundry.toml b/foundry.toml index 085d0b2..430b2b3 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] solc_version = '0.8.17' optimizer = true -optimizer_runs = 300 +optimizer_runs = 500 via_ir = true out = 'out' test = 'test' @@ -30,8 +30,10 @@ optimism = "https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}" optimism_goerli = "https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}" zora = "https://rpc.zora.energy" -zora_goerli = "https://testnet.rpc.zora.energy" - +base_goerli = "https://goerli.base.org" +base = "https://developer-access-mainnet.base.org" +pgn_sepolia = "https://sepolia.publicgoods.network" +pgn = "https://rpc.publicgoods.network" base = "https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}" base_goerli = "https://base-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}" pgn = "https://rpc.publicgoods.network" diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts deleted file mode 160000 index c239e1a..0000000 --- a/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c239e1af8d1a1296577108dd6989a17b57434f8e diff --git a/package.json b/package.json index 0813c76..0f50bfe 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,11 @@ }, "dependencies": { "@dotenv/cli": "^2.2.2", +<<<<<<< HEAD + "@zoralabs/protocol-rewards": "^1.0.1", +======= "@zoralabs/protocol-rewards": "^1.0.2", +>>>>>>> origin/main "ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b", "forge-std": "https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653" } diff --git a/script/TestUpgradeAndMint.s.sol b/script/TestUpgradeAndMint.s.sol index 8a88016..a1ebb5e 100644 --- a/script/TestUpgradeAndMint.s.sol +++ b/script/TestUpgradeAndMint.s.sol @@ -20,6 +20,8 @@ import {ERC721DropProxy} from "../src/ERC721DropProxy.sol"; contract DeployNewERC721Drop is Script { using Strings for uint256; + address internal DEFAULT_CREATE_REFERRAL = address(0); + string configFile; function _getKey(string memory key) internal returns (address result) { diff --git a/src/ERC721Drop.sol b/src/ERC721Drop.sol index 826fa2e..4542319 100644 --- a/src/ERC721Drop.sol +++ b/src/ERC721Drop.sol @@ -94,7 +94,7 @@ contract ERC721Drop is uint8 constant SUPPLY_ROYALTY_FOR_EVERY_MINT = 1; // /// @notice Empty string for blank comments - // string constant EMPTY_STRING = ""; + string constant EMPTY_STRING = ""; /// @notice Only allow for users with admin access modifier onlyAdmin() { @@ -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 @@ -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 @@ -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 @@ -528,9 +528,8 @@ contract ERC721Drop is _requireLegacyFee(msg.value, salePrice, quantity); _mintNFTs(recipient, quantity); - uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; - _payoutZoraFee(quantity); + uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; _emitSaleEvents(_msgSender(), recipient, quantity, salePrice, firstMintedTokenId, comment); @@ -630,7 +629,7 @@ contract ERC721Drop is onlyPresaleActive returns (uint256) { - return _handlePurchasePresale(quantity, maxQuantity, pricePerToken, merkleProof, ""); + return _handlePurchasePresaleWithRewards(quantity, maxQuantity, pricePerToken, merkleProof, "", address(0)); } /// @notice Merkle-tree based presale purchase function with a comment @@ -652,15 +651,40 @@ contract ERC721Drop is onlyPresaleActive returns (uint256) { - return _handlePurchasePresale(quantity, maxQuantity, pricePerToken, merkleProof, comment); + return _handlePurchasePresaleWithRewards(quantity, maxQuantity, pricePerToken, merkleProof, comment, address(0)); } - function _handlePurchasePresale( + /// @notice Merkle-tree based presale purchase function with a comment and protocol rewards + /// @param quantity quantity to purchase + /// @param maxQuantity max quantity that can be purchased via merkle proof # + /// @param pricePerToken price that each token is purchased at + /// @param merkleProof proof for presale mint + /// @param comment comment to include in the IERC721Drop.Sale event + /// @param mintReferral The facilitator of the mint + function purchasePresaleWithRewards( uint256 quantity, uint256 maxQuantity, uint256 pricePerToken, bytes32[] calldata merkleProof, - string memory comment + string calldata comment, + address mintReferral + ) + external + payable + nonReentrant + onlyPresaleActive + returns (uint256) + { + return _handlePurchasePresaleWithRewards(quantity, maxQuantity, pricePerToken, merkleProof, comment, mintReferral); + } + + function _handlePurchasePresaleWithRewards( + uint256 quantity, + uint256 maxQuantity, + uint256 pricePerToken, + bytes32[] calldata merkleProof, + string memory comment, + address mintReferral ) internal returns (uint256) { _mintSupplyRoyalty(quantity); _requireCanMintQuantity(quantity); @@ -669,15 +693,15 @@ contract ERC721Drop is _requireMerkleApproval(msgSender, maxQuantity, pricePerToken, merkleProof); - _requireLegacyFee(msg.value, pricePerToken, quantity); - _requireCanPurchasePresale(msgSender, quantity, maxQuantity); + _handleRewards(msg.value, quantity, pricePerToken, config.fundsRecipient, mintReferral, createReferral); + _mintNFTs(msgSender, quantity); - uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; - _payoutZoraFee(quantity); + uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; + emit IERC721Drop.Sale({ to: msgSender, quantity: quantity, @@ -732,21 +756,29 @@ contract ERC721Drop is _mintSupplyRoyalty(quantity); _requireCanMintQuantity(quantity); - address msgSender = _msgSender(); - - _requireMerkleApproval(msgSender, maxQuantity, pricePerToken, merkleProof); - - _requireCanPurchasePresale(msgSender, quantity, maxQuantity); - - _handleRewards(msg.value, quantity, pricePerToken, config.fundsRecipient != address(0) ? config.fundsRecipient : address(this), createReferral, mintReferral); - - _mintNFTs(msgSender, quantity); - - uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; - - _emitSaleEvents(msgSender, msgSender, quantity, pricePerToken, firstMintedTokenId, comment); - - return firstMintedTokenId; +<<<<<<< HEAD + /// @notice Hook to filter operators (no-op if no filters are registered) + /// @dev Part of ERC721A token hooks + /// @param from Transfer from user + function _beforeTokenTransfers( + address from, + address, + uint256, + uint256 + ) internal virtual override { + if ( + from != address(0) && // skip on mints + from != msg.sender // skip on transfers from sender + ) { + if ( + !operatorFilterRegistry.isOperatorAllowed( + address(this), + msg.sender + ) + ) { + revert OperatorNotAllowed(msg.sender); + } + } } /** @@ -1272,6 +1304,8 @@ contract ERC721Drop is } } +<<<<<<< HEAD +======= function _payoutZoraFee(uint256 quantity) internal { // Transfer ZORA fee to recipient (, uint256 zoraFee) = zoraFeeForAmount(quantity); @@ -1287,6 +1321,7 @@ contract ERC721Drop is } } +>>>>>>> origin/main function _requireCanMintQuantity(uint256 quantity) internal view { if (quantity + _totalMinted() > config.editionSize) { revert Mint_SoldOut();