From c6e4f97b939dbb0ce80f18b426c3d25f729df457 Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Thu, 20 Jul 2023 17:35:49 -0400 Subject: [PATCH 01/10] Remove operator owner configuration and ZORA subscription deployer list (#139) * remove unused subscription market filter owner address * remove deploy fee registry --- DEPLOYING.md | 2 -- chainConfigs/1.json | 1 - chainConfigs/10.json | 1 - chainConfigs/420.json | 1 - chainConfigs/5.json | 1 - chainConfigs/7777777.json | 1 - chainConfigs/8453.json | 1 - chainConfigs/84531.json | 1 - chainConfigs/999.json | 1 - script/DeployFeeRegistry.s.sol | 35 ---------------------------------- 10 files changed, 45 deletions(-) delete mode 100644 script/DeployFeeRegistry.s.sol diff --git a/DEPLOYING.md b/DEPLOYING.md index 6e82394..2a2760b 100644 --- a/DEPLOYING.md +++ b/DEPLOYING.md @@ -35,8 +35,6 @@ Use `1.json` for reference. We are ordering keys alphabetically. # subscription market filter address for operator filter registry. # can be set to 0 to disable. see: https://github.com/ProjectOpenSea/operator-filter-registry "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - # subscription market filter owner address. - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x9AaC739c133074dB445183A95149880a2156541A", # pre-approved transfer helper for ZORA v3, likely should be 0 on new networks "ZORA_ERC721_TRANSFER_HELPER": "0x909e9efE4D87d1a6018C2065aE642b6D0447bc91" } diff --git a/chainConfigs/1.json b/chainConfigs/1.json index 4e1eef1..2eed09a 100644 --- a/chainConfigs/1.json +++ b/chainConfigs/1.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x9AaC739c133074dB445183A95149880a2156541A", "ZORA_ERC721_TRANSFER_HELPER": "0x909e9efE4D87d1a6018C2065aE642b6D0447bc91" } diff --git a/chainConfigs/10.json b/chainConfigs/10.json index 0062c92..61f4b64 100644 --- a/chainConfigs/10.json +++ b/chainConfigs/10.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0xe3A6CD067a1193b903143C36dA00557c9d95C41e", "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" } diff --git a/chainConfigs/420.json b/chainConfigs/420.json index 6af76c2..b75a240 100644 --- a/chainConfigs/420.json +++ b/chainConfigs/420.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0xe3A6CD067a1193b903143C36dA00557c9d95C41e", "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" } diff --git a/chainConfigs/5.json b/chainConfigs/5.json index 7daac2a..f73d6fc 100644 --- a/chainConfigs/5.json +++ b/chainConfigs/5.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xDC498668B5e6CC518fD58A2ADBF614Fd3A13D3a0", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x9AaC739c133074dB445183A95149880a2156541A", "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f" } diff --git a/chainConfigs/7777777.json b/chainConfigs/7777777.json index 6133103..f9f8908 100644 --- a/chainConfigs/7777777.json +++ b/chainConfigs/7777777.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xEcfc2ee50409E459c554a2b0376F882Ce916D853", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/chainConfigs/8453.json b/chainConfigs/8453.json index b7ef558..916b019 100644 --- a/chainConfigs/8453.json +++ b/chainConfigs/8453.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x7bf90111Ad7C22bec9E9dFf8A01A44713CC1b1B6", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x000000000000AAeB6D7670E522A718067333cd4E", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" } diff --git a/chainConfigs/84531.json b/chainConfigs/84531.json index 7b51a6e..7a45789 100644 --- a/chainConfigs/84531.json +++ b/chainConfigs/84531.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 111000000000000, "MINT_FEE_RECIPIENT": "0x02539E813cA450C2c7334e885423f4A899a063Fe", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x9B414A3F7872bdd2E6513689214BD2Debbe48340", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x02539E813cA450C2c7334e885423f4A899a063Fe", "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f" } diff --git a/chainConfigs/999.json b/chainConfigs/999.json index c3a04d0..a84c849 100644 --- a/chainConfigs/999.json +++ b/chainConfigs/999.json @@ -4,6 +4,5 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", - "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/script/DeployFeeRegistry.s.sol b/script/DeployFeeRegistry.s.sol deleted file mode 100644 index 7b042af..0000000 --- a/script/DeployFeeRegistry.s.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import "forge-std/console2.sol"; - -import {ZoraDropsDeployBase} from "./ZoraDropsDeployBase.sol"; -import {IOperatorFilterRegistry} from "../src/interfaces/IOperatorFilterRegistry.sol"; -import {OwnedSubscriptionManager} from "../src/filter/OwnedSubscriptionManager.sol"; -import {ChainConfig} from '../src/DeploymentConfig.sol'; - -contract DeployFeeRegistry is ZoraDropsDeployBase { - address constant IMMUTABLE_OPENSEA_FEE_REGISTRY = address(0x000000000000AAeB6D7670E522A718067333cd4E); - - function setupFeeRegistry(address deployer) public returns (OwnedSubscriptionManager) { - OwnedSubscriptionManager ownedSubscriptionManager = new OwnedSubscriptionManager(deployer); - address[] memory blockedOperatorsList = new address[](0); - IOperatorFilterRegistry operatorFilterRegistry = IOperatorFilterRegistry(IMMUTABLE_OPENSEA_FEE_REGISTRY); - operatorFilterRegistry.updateOperators(address(ownedSubscriptionManager), blockedOperatorsList, true); - return ownedSubscriptionManager; - } - - function run() public { - address subscriptionOwner = getChainConfig().subscriptionMarketFilterOwner; - console2.log("Setup operators ---"); - - vm.startBroadcast(); - - // Add opensea contracts to test - OwnedSubscriptionManager ownedSubscriptionManager = setupFeeRegistry(subscriptionOwner); - - vm.stopBroadcast(); - - console2.log(address(ownedSubscriptionManager)); - } -} From 3e6d7a6c33b2cafec339c59238bb8a1bbbe08ffd Mon Sep 17 00:00:00 2001 From: Dan Oved Date: Thu, 20 Jul 2023 22:30:51 -0700 Subject: [PATCH 02/10] Deploy pgn sepolia and mainnet (#140) * Deployed to pgn sepolia * added pgn mainnet --- .changeset/four-onions-collect.md | 5 +++++ .changeset/pretty-badgers-sneeze.md | 5 +++++ .github/workflows/test_fork.yml | 2 +- addresses/424.json | 10 ++++++++++ addresses/58008.json | 10 ++++++++++ chainConfigs/424.json | 9 +++++++++ chainConfigs/58008.json | 9 +++++++++ foundry.toml | 4 +++- script/Deploy.s.sol | 4 +++- 9 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 .changeset/four-onions-collect.md create mode 100644 .changeset/pretty-badgers-sneeze.md create mode 100644 addresses/424.json create mode 100644 addresses/58008.json create mode 100644 chainConfigs/424.json create mode 100644 chainConfigs/58008.json diff --git a/.changeset/four-onions-collect.md b/.changeset/four-onions-collect.md new file mode 100644 index 0000000..eb0e211 --- /dev/null +++ b/.changeset/four-onions-collect.md @@ -0,0 +1,5 @@ +--- +'@zoralabs/nft-drop-contracts': patch +--- + +Deployed to pgn sepolia diff --git a/.changeset/pretty-badgers-sneeze.md b/.changeset/pretty-badgers-sneeze.md new file mode 100644 index 0000000..63b781d --- /dev/null +++ b/.changeset/pretty-badgers-sneeze.md @@ -0,0 +1,5 @@ +--- +'@zoralabs/nft-drop-contracts': patch +--- + +Added pgn mainnet diff --git a/.github/workflows/test_fork.yml b/.github/workflows/test_fork.yml index 0cc19ca..6ddfd3e 100644 --- a/.github/workflows/test_fork.yml +++ b/.github/workflows/test_fork.yml @@ -35,6 +35,6 @@ jobs: run: | forge test -vvv --match-test fork env: - FORK_TEST_CHAINS: mainnet,goerli,optimism,optimism_goerli,zora,zora_goerli,base_goerli,base + FORK_TEST_CHAINS: mainnet,goerli,optimism,optimism_goerli,zora,zora_goerli,base_goerli,base,pgn_sepolia,pgn ALCHEMY_KEY: ${{ secrets.ALCHEMY_KEY }} id: test diff --git a/addresses/424.json b/addresses/424.json new file mode 100644 index 0000000..700b843 --- /dev/null +++ b/addresses/424.json @@ -0,0 +1,10 @@ +{ + "DROP_METADATA_RENDERER": "0xd77783B9df27BC9ABd438d1ddE67e3afB64618e0", + "EDITION_METADATA_RENDERER": "0xC647382DFbb02ddf39dde7fDEbb5D844a832BE33", + "ERC721DROP_IMPL": "0x0ef82DaB14798E63F1B99479Ba689e3f6A6fEb6C", + "FACTORY_UPGRADE_GATE": "0x973577d5B73a9b2508296F81260415151d0a955E", + "ZORA_NFT_CREATOR_PROXY": "0x48d8db63724444C6270749fEe80bBDB6CF33677f", + "ZORA_NFT_CREATOR_V1_IMPL": "0x97eb05B8db496B12244BCcf17CF377d00a99b67a", + "timestamp": 1689886675, + "commit": "bdafc01" +} \ No newline at end of file diff --git a/addresses/58008.json b/addresses/58008.json new file mode 100644 index 0000000..8e88817 --- /dev/null +++ b/addresses/58008.json @@ -0,0 +1,10 @@ +{ + "DROP_METADATA_RENDERER": "0x973577d5B73a9b2508296F81260415151d0a955E", + "EDITION_METADATA_RENDERER": "0x0ef82DaB14798E63F1B99479Ba689e3f6A6fEb6C", + "ERC721DROP_IMPL": "0x48d8db63724444C6270749fEe80bBDB6CF33677f", + "FACTORY_UPGRADE_GATE": "0x97eb05B8db496B12244BCcf17CF377d00a99b67a", + "ZORA_NFT_CREATOR_PROXY": "0x418B87c2C9579d27FC3D66605545AB9889737E60", + "ZORA_NFT_CREATOR_V1_IMPL": "0x39C51a7957651ea176733F19125BD9c253894D6F", + "timestamp": 1689881298, + "commit": "4b6455d" +} \ No newline at end of file diff --git a/chainConfigs/424.json b/chainConfigs/424.json new file mode 100644 index 0000000..3d66d97 --- /dev/null +++ b/chainConfigs/424.json @@ -0,0 +1,9 @@ +{ + "FACTORY_OWNER": "0x8fbC66d36cceB3Ad69B4d672756da54CcFec1cD2", + "FACTORY_UPGRADE_GATE_OWNER": "0x8fbC66d36cceB3Ad69B4d672756da54CcFec1cD2", + "MINT_FEE_AMOUNT": 777000000000000, + "MINT_FEE_RECIPIENT": "0x95FD5d77B206cCc0B1f7D7A4077fbE8eb4fC31eF", + "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", + "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" +} diff --git a/chainConfigs/58008.json b/chainConfigs/58008.json new file mode 100644 index 0000000..33e5b3a --- /dev/null +++ b/chainConfigs/58008.json @@ -0,0 +1,9 @@ +{ + "FACTORY_OWNER": "0xfAe426B462f4Bc9857ED28D8473Fb85192f23E9b", + "FACTORY_UPGRADE_GATE_OWNER": "0xfAe426B462f4Bc9857ED28D8473Fb85192f23E9b", + "MINT_FEE_AMOUNT": 111000000000000, + "MINT_FEE_RECIPIENT": "0x917D86f1eBD1d9f59Dae1C00e5Af7f8689299EC4", + "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", + "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" +} diff --git a/foundry.toml b/foundry.toml index 43b582a..b07f1b1 100644 --- a/foundry.toml +++ b/foundry.toml @@ -21,4 +21,6 @@ optimism_goerli = "https://goerli.optimism.io" 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" \ No newline at end of file +base = "https://developer-access-mainnet.base.org" +pgn_sepolia = "https://sepolia.publicgoods.network" +pgn = "https://rpc.publicgoods.network" \ No newline at end of file diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 1e55946..1712d8e 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -30,7 +30,9 @@ contract Deploy is ZoraDropsDeployBase { console2.log("Setup contracts ---"); - vm.startBroadcast(); + address deployer = vm.envAddress("DEPLOYER"); + + vm.startBroadcast(deployer); DropMetadataRenderer dropMetadata = new DropMetadataRenderer(); EditionMetadataRenderer editionMetadata = new EditionMetadataRenderer(); From b8de02e7fc62609895c0c4265229286175839e53 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 22:46:53 -0700 Subject: [PATCH 03/10] Version Packages (#141) Co-authored-by: github-actions[bot] --- .changeset/four-onions-collect.md | 5 ----- .changeset/pretty-badgers-sneeze.md | 5 ----- CHANGELOG.md | 7 +++++++ package.json | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) delete mode 100644 .changeset/four-onions-collect.md delete mode 100644 .changeset/pretty-badgers-sneeze.md diff --git a/.changeset/four-onions-collect.md b/.changeset/four-onions-collect.md deleted file mode 100644 index eb0e211..0000000 --- a/.changeset/four-onions-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@zoralabs/nft-drop-contracts': patch ---- - -Deployed to pgn sepolia diff --git a/.changeset/pretty-badgers-sneeze.md b/.changeset/pretty-badgers-sneeze.md deleted file mode 100644 index 63b781d..0000000 --- a/.changeset/pretty-badgers-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@zoralabs/nft-drop-contracts': patch ---- - -Added pgn mainnet diff --git a/CHANGELOG.md b/CHANGELOG.md index dca5e0f..6cfc183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # @zoralabs/nft-drop-contracts +## 1.14.1 + +### Patch Changes + +- 3e6d7a6: Deployed to pgn sepolia +- 3e6d7a6: Added pgn mainnet + ## 1.14.0 ### Minor Changes diff --git a/package.json b/package.json index 06319b0..20dc1fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zoralabs/nft-drop-contracts", - "version": "1.14.0", + "version": "1.14.1", "description": "ZORA NFT Drops Contracts", "author": "ZORA", "license": "MIT", From 2c7e73e3000c1b679221b1c3c796bb87a3fbc297 Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Wed, 2 Aug 2023 15:30:26 -0400 Subject: [PATCH 04/10] Update foundry toml file settings (#144) * update foundry toml file settings * update etherscan * update owner in config for optimism --- chainConfigs/10.json | 4 ++-- foundry.toml | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/chainConfigs/10.json b/chainConfigs/10.json index 61f4b64..2465ac4 100644 --- a/chainConfigs/10.json +++ b/chainConfigs/10.json @@ -1,6 +1,6 @@ { - "FACTORY_OWNER": "0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c", - "FACTORY_UPGRADE_GATE_OWNER": "0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c", + "FACTORY_OWNER": "0x4c7f7b6067fac9a737ecf2ca1a733fc85dd65a2b", + "FACTORY_UPGRADE_GATE_OWNER": "0x4c7f7b6067fac9a737ecf2ca1a733fc85dd65a2b", "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", diff --git a/foundry.toml b/foundry.toml index b07f1b1..c93998f 100644 --- a/foundry.toml +++ b/foundry.toml @@ -11,16 +11,28 @@ gas_reports = ['*'] fs_permissions = [{ access = "read", path = "./addresses"}, { access = "read", path = "./chainConfigs"}, { access = "read", path = "./package.json" }] +[etherscan] +zora_mainnet = { key = "", chain = 7777777, url = "https://explorer.zora.energy/api\\?" } +zora_testnet = { key = "", chain = 999, url = "https://explorer.testnet.zora.energy/api\\?" } + +pgn = { key = "", chain = 7777777, url = "https://explorer.publicgoods.network/api\\?" } +pgn_sepolia = { key = "", chain = 7777777, url = "https://explorer.sepolia.publicgoods.network/api\\?" } + [rpc_endpoints] mainnet = "https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}" goerli = "https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}" + # for optimism, since we are just using this for deployment/fork testing, # we can use these since they're lower volume. + optimism = "https://mainnet.optimism.io" optimism_goerli = "https://goerli.optimism.io" + 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" +base_goerli = "https://goerli.base.org" + +pgn = "https://rpc.publicgoods.network" pgn_sepolia = "https://sepolia.publicgoods.network" -pgn = "https://rpc.publicgoods.network" \ No newline at end of file From 4ac79500c33553a16015db1e61b08865297b7e1e Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Thu, 3 Aug 2023 07:28:22 -0400 Subject: [PATCH 05/10] adding public changesets publish flags (#146) --- .changeset/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/config.json b/.changeset/config.json index 6d2119a..cee6df8 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -4,7 +4,7 @@ "commit": false, "fixed": [], "linked": [], - "access": "restricted", + "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] From e6038b8620f3cc037e1ac5cbfc4b823a3a9f3250 Mon Sep 17 00:00:00 2001 From: Rohan Kulkarni Date: Wed, 9 Aug 2023 15:01:43 -0400 Subject: [PATCH 06/10] feat: protocol rewards (#143) * chore: add zora rewards package * chore: update remappings * refactor: add ERC721Rewards extension * chore: update dependencies * chore: add zora rewards to scripts * chore: update existing tests * feat: add purchaseWithRewards * chore: update dependencies * fix: add finder and lister params * chore: add rewards tests * chore: reduce optimizer runs * chore: update dependencies * chore: update runs * fix: handle supply royaltes when purchasing with rewards * chore: update tests * chore: update OZ dependency location * chore: update rewards tests * refactor: add recipient to purchase w rewards * chore: update rewards dep * refactor: update lister to origin * chore: update tests * chore: add zora rewards to chain configs * refactor: change purchase to mint w/ rewards * refactor: update referral names * chore: add pgn * chore: add rewards to deploy config * chore: update dependencies * refactor: set create referral on initialization * refactor: add create referral to factory * chore: update scripts w/ default create referral * chore: update tests * chore: update create referral tests * refactor: add common helpers * chore: update deps * chore: update deps * refactor: add rewards storage * chore: update runs * chore: update protocol rewards * chore: update deploy config * chore: update naming * chore: update versions * refactor: do not force create referral via factory * chore: update goerli deploy * chore: update zora goerli deploy * chore: update op goerli deploy * chore: update base goerli deploy * chore: update deps * chore: update goerli deploy * chore: update zora goerli deploy * chore: update op goerli deploy * chore: update base goerli deploy * chore: update dep * refactor: update rewards handler * chore: update tests * refactor: add error for protocol rewards withdraw * refactor: add rewards withdraw and sale event helper * chore: update runs * chore: remove old var * chore: add back OZ * chore: update lock * chore: update chain configs * chore: update testnets * chore: update deploys * chore: update deployments * chore: update op goerli * chore: update chain configs * fix: consistent chain config amounts * chore: update deploys * fix: remove chain config key * generate new storage layout --------- Co-authored-by: James Geary <36774175+jgeary@users.noreply.github.com> --- .storage-layout | 1 + addresses/1.json | 4 +- addresses/10.json | 4 +- addresses/420.json | 4 +- addresses/5.json | 6 +- addresses/7777777.json | 4 +- addresses/8453.json | 4 +- addresses/84531.json | 4 +- addresses/999.json | 4 +- chainConfigs/1.json | 3 +- chainConfigs/10.json | 3 +- chainConfigs/11155111.json | 2 +- chainConfigs/420.json | 3 +- chainConfigs/424.json | 3 +- chainConfigs/5.json | 3 +- chainConfigs/58008.json | 2 +- chainConfigs/7777777.json | 3 +- chainConfigs/8453.json | 3 +- chainConfigs/84531.json | 5 +- chainConfigs/999.json | 3 +- foundry.toml | 3 +- package.json | 1 + remappings.txt | 1 + script/Deploy.s.sol | 3 +- script/UpgradeERC721DropFactory.s.sol | 3 +- script/ZoraDropsDeployBase.sol | 2 +- src/DeploymentConfig.sol | 7 +- src/ERC721Drop.sol | 293 ++++++++--- src/ZoraNFTCreatorV1.sol | 85 ++- src/interfaces/IERC721Drop.sol | 2 + test/ERC721Drop.t.sol | 730 +++++++++++++++----------- test/ZoraNFTCreatorV1.t.sol | 13 +- test/merkle/MerkleDrop.t.sol | 17 +- yarn.lock | 714 +++++++++++++------------ 34 files changed, 1196 insertions(+), 746 deletions(-) diff --git a/.storage-layout b/.storage-layout index fddfd12..e549afa 100644 --- a/.storage-layout +++ b/.storage-layout @@ -31,6 +31,7 @@ | salesConfig | struct IERC721Drop.SalesConfiguration | 354 | 0 | 96 | src/ERC721Drop.sol:ERC721Drop | | presaleMintsByAddress | mapping(address => uint256) | 357 | 0 | 32 | src/ERC721Drop.sol:ERC721Drop | | royaltyMintSchedule | uint32 | 358 | 0 | 4 | src/ERC721Drop.sol:ERC721Drop | +| createReferral | address | 358 | 4 | 20 | src/ERC721Drop.sol:ERC721Drop | ======================= ➡ ERC721DropProxy diff --git a/addresses/1.json b/addresses/1.json index 28c6196..45cb0ad 100644 --- a/addresses/1.json +++ b/addresses/1.json @@ -1,8 +1,8 @@ { "DROP_METADATA_RENDERER": "0x5914d9a241008b9f02f22811bf3a77e02b84d226", "EDITION_METADATA_RENDERER": "0x192ce8267cbab9c3c477d61e85d7f0c5fe3b46af", - "ERC721DROP_IMPL": "0x419074d73Cf0852e46b8531b430B1230C348C291", + "ERC721DROP_IMPL": "0x8237F421357F87a23ed0CFf3a5586172F210A21B", "FACTORY_UPGRADE_GATE": "0x8Da5aC3A39D3B8BCaA1FC15A01506cf4F5e79830", "ZORA_NFT_CREATOR_PROXY": "0xF74B146ce44CC162b601deC3BE331784DB111DC1", - "ZORA_NFT_CREATOR_V1_IMPL": "0xa6a2956fa075d50b021385478A99f3642dAfCc2C" + "ZORA_NFT_CREATOR_V1_IMPL": "0x932A29Dbfc1B8c3BdfC763eF53F113486A5b5E7D" } diff --git a/addresses/10.json b/addresses/10.json index 26443e0..526d419 100644 --- a/addresses/10.json +++ b/addresses/10.json @@ -1,10 +1,10 @@ { "DROP_METADATA_RENDERER": "0x96CcF205A366E15E261d77B14586389f80a029e9", "EDITION_METADATA_RENDERER": "0xa2a7D8bcE0bf58D177137ECB94f3Fa6aA06aA7A1", - "ERC721DROP_IMPL": "0x46E772210f01647FA573b915bE287Ff9b65AD4B0", + "ERC721DROP_IMPL": "0x3E8524770adD176bE381a0529E09f1c6c3502A5a", "FACTORY_UPGRADE_GATE": "0x192D663C3D6813a24a24582A76B8d872c4F6F7f9", "ZORA_NFT_CREATOR_PROXY": "0x7d1a46c6e614A0091c39E102F2798C27c1fA8892", - "ZORA_NFT_CREATOR_V1_IMPL": "0xd1cba36d92B052079523F471Eb891563F2E5dF5C", + "ZORA_NFT_CREATOR_V1_IMPL": "0x805E0a08dE70f85C01F7848370d5e3fc08aAd0ea", "timestamp": 1683682873, "commit": "8b52993" } \ No newline at end of file diff --git a/addresses/420.json b/addresses/420.json index 39c8efc..fac3e4d 100644 --- a/addresses/420.json +++ b/addresses/420.json @@ -1,10 +1,10 @@ { "DROP_METADATA_RENDERER": "0xCe6B190956D73dA045bA348743E4C1cb6652f37f", "EDITION_METADATA_RENDERER": "0x169007EF8fF4d2a225f361654e4B8280910fD8FC", - "ERC721DROP_IMPL": "0x0Cf8733DEd6d9E0905A8cCc8DC767F381A76970a", + "ERC721DROP_IMPL": "0x61Cb091f8EC70029E393D31BA8F6D533c1308408", "FACTORY_UPGRADE_GATE": "0x9B414A3F7872bdd2E6513689214BD2Debbe48340", "ZORA_NFT_CREATOR_PROXY": "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3", - "ZORA_NFT_CREATOR_V1_IMPL": "0xC5c958a65656A84b74100D1d420a1819fEA18d41", + "ZORA_NFT_CREATOR_V1_IMPL": "0xbe83E15eED1FD666C241960f50549bE9D639743c", "timestamp": 1683668679, "commit": "e100eee" } \ No newline at end of file diff --git a/addresses/5.json b/addresses/5.json index b88b8ce..5f9b3f6 100644 --- a/addresses/5.json +++ b/addresses/5.json @@ -1,12 +1,10 @@ { - "ZORA_NFT_CREATOR_V1": "0xb4d319458E489825Cea8e25b5e43742BCdAFc6dd", - "ZORA_NFT_CREATOR_PROXY": "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519", "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f", "ZORA_FEE_MANAGER": "0xCf5E957CA7b77EC16611992d79f4E179132ad98C", "EDITION_METADATA_RENDERER": "0x2f5C21EF9DdFf9A1FE76a1c55dd5112fcf2EfD39", "DROP_METADATA_RENDERER": "0x5956Fd16c4d8c4b4711F2551971aBB7c2F4aF677", - "ERC721_DROP": "0x2093eFB737C07324D8b6c5807910EFF45045D987", + "ERC721DROP_IMPL": "0xe4c17055048aEe01D0d122804816fEe5E6ac4A67", "FACTORY_UPGRADE_GATE": "0x942C03C7afE5c8118BDB728Aa06d1b894B1cD9A8", "ZORA_NFT_CREATOR_PROXY": "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519", - "ZORA_NFT_CREATOR_V1_IMPL": "0x4328cbDAD668E81B475766520E1004e6688D2949" + "ZORA_NFT_CREATOR_V1_IMPL": "0x0209aAEC870BE5C1cC243eE18eF6e80d545e9F32" } diff --git a/addresses/7777777.json b/addresses/7777777.json index bac272a..add45f1 100644 --- a/addresses/7777777.json +++ b/addresses/7777777.json @@ -1,10 +1,10 @@ { "DROP_METADATA_RENDERER": "0x4A0ad3Ef9bE8095590D854bC8481C9E50922a3c0", "EDITION_METADATA_RENDERER": "0xCA7bF48453B72e4E175267127B4Ed7EB12F83b93", - "ERC721DROP_IMPL": "0x8ee55A8598EC2CE412a476890695fa0E7154510c", + "ERC721DROP_IMPL": "0x53a85FbD2955EF713AA489Ae0C48523E727a0c07", "FACTORY_UPGRADE_GATE": "0x446A4135FB31007064107EFfDC15B8843B72B6F6", "ZORA_NFT_CREATOR_PROXY": "0xA2c2A96A232113Dd4993E8b048EEbc3371AE8d85", - "ZORA_NFT_CREATOR_V1_IMPL": "0xe7763512099a9C2567a40a669aA9F48FF8493455", + "ZORA_NFT_CREATOR_V1_IMPL": "0xfFFD7409031B1aeb731271C6C2D59771523Ff8a8", "timestamp": 1686787866, "commit": "87735a2" } \ No newline at end of file diff --git a/addresses/8453.json b/addresses/8453.json index ff4f8d2..ca7945c 100644 --- a/addresses/8453.json +++ b/addresses/8453.json @@ -1,10 +1,10 @@ { "DROP_METADATA_RENDERER": "0xF77330C8b1c41f2e44470763Cf9E3ACa78Db4381", "EDITION_METADATA_RENDERER": "0x2008C05685F9fA15BBD75d80e9A44ab0c7230577", - "ERC721DROP_IMPL": "0x3F155E58AcA1AE60e4FEce2753CC6B363525042c", + "ERC721DROP_IMPL": "0x8Ca5e648C5dFEfcdDa06d627F4b490B719ccFD98", "FACTORY_UPGRADE_GATE": "0x532142aE8e53a5F92B9dE1a43F1FFD6eF789e65e", "ZORA_NFT_CREATOR_PROXY": "0x58C3ccB2dcb9384E5AB9111CD1a5DEA916B0f33c", - "ZORA_NFT_CREATOR_V1_IMPL": "0xba187429b966788B5C11a99A848938c88DfDFf5C", + "ZORA_NFT_CREATOR_V1_IMPL": "0x76CC78EF3aafD52e716a8e37F3dBbE0C42c51d54", "timestamp": 1689712140, "commit": "a9e390f" } \ No newline at end of file diff --git a/addresses/84531.json b/addresses/84531.json index 95e5f50..b634a46 100644 --- a/addresses/84531.json +++ b/addresses/84531.json @@ -1,8 +1,8 @@ { "DROP_METADATA_RENDERER": "0x0Cf8733DEd6d9E0905A8cCc8DC767F381A76970a", "EDITION_METADATA_RENDERER": "0xC5c958a65656A84b74100D1d420a1819fEA18d41", - "ERC721DROP_IMPL": "0x421B6ad0CdD20bE3636F3511B6ae244d8F668dB1", + "ERC721DROP_IMPL": "0x39Bcc1e15b8ec15684F17fEf298151F4A544B591", "FACTORY_UPGRADE_GATE": "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3", "ZORA_NFT_CREATOR_PROXY": "0x87cfd516c5ea86e50b950678CA970a8a28de27ac", - "ZORA_NFT_CREATOR_V1_IMPL": "0x0ABdD5AA61E9107519DB7cD626442B905284B7eb" + "ZORA_NFT_CREATOR_V1_IMPL": "0x489f8fFbd5f5eA8875c2EbC5CA9ED1214BD77F42" } diff --git a/addresses/999.json b/addresses/999.json index e3a9ba7..395e58e 100644 --- a/addresses/999.json +++ b/addresses/999.json @@ -1,8 +1,8 @@ { "DROP_METADATA_RENDERER": "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519", "EDITION_METADATA_RENDERER": "0x481c56e15A9B2987Bd6041043e1d807697505d23", - "ERC721DROP_IMPL": "0xA3Fb46092D9DAe8eAa2F99417630930F4Ee5A45a", + "ERC721DROP_IMPL": "0x293997C6a1f2A1cA3aB971f548c4D95585E46282", "FACTORY_UPGRADE_GATE": "0x2068BA7Be6e22b97d21f5eb6e152A36d2Dc27da2", "ZORA_NFT_CREATOR_PROXY": "0xeB29A4e5b84fef428c072debA2444e93c080CE87", - "ZORA_NFT_CREATOR_V1_IMPL": "0x4589A93f2444b736E3d35acB331f5241b1c6DAD3" + "ZORA_NFT_CREATOR_V1_IMPL": "0xe4c17055048aEe01D0d122804816fEe5E6ac4A67" } \ No newline at end of file diff --git a/chainConfigs/1.json b/chainConfigs/1.json index 2eed09a..338a6e5 100644 --- a/chainConfigs/1.json +++ b/chainConfigs/1.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "ZORA_ERC721_TRANSFER_HELPER": "0x909e9efE4D87d1a6018C2065aE642b6D0447bc91" + "ZORA_ERC721_TRANSFER_HELPER": "0x909e9efE4D87d1a6018C2065aE642b6D0447bc91", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/10.json b/chainConfigs/10.json index 2465ac4..2f069f8 100644 --- a/chainConfigs/10.json +++ b/chainConfigs/10.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/11155111.json b/chainConfigs/11155111.json index b448462..6e0ce65 100644 --- a/chainConfigs/11155111.json +++ b/chainConfigs/11155111.json @@ -1,7 +1,7 @@ { "FACTORY_OWNER": "0xE51051a204afb2fC071A2406914cdEA5638e5018", "FACTORY_UPGRADE_GATE_OWNER": "0xE51051a204afb2fC071A2406914cdEA5638e5018", - "MINT_FEE_AMOUNT": 111000000000000, + "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xE51051a204afb2fC071A2406914cdEA5638e5018", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x9B414A3F7872bdd2E6513689214BD2Debbe48340", "SUBSCRIPTION_MARKET_FILTER_OWNER": "0xE51051a204afb2fC071A2406914cdEA5638e5018", diff --git a/chainConfigs/420.json b/chainConfigs/420.json index b75a240..ea95149 100644 --- a/chainConfigs/420.json +++ b/chainConfigs/420.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/424.json b/chainConfigs/424.json index 3d66d97..7212b2d 100644 --- a/chainConfigs/424.json +++ b/chainConfigs/424.json @@ -5,5 +5,6 @@ "MINT_FEE_RECIPIENT": "0x95FD5d77B206cCc0B1f7D7A4077fbE8eb4fC31eF", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777A456fF23D9b6851184472c08FBDa73e32" } diff --git a/chainConfigs/5.json b/chainConfigs/5.json index f73d6fc..f8bbea0 100644 --- a/chainConfigs/5.json +++ b/chainConfigs/5.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xDC498668B5e6CC518fD58A2ADBF614Fd3A13D3a0", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", - "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f" + "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/58008.json b/chainConfigs/58008.json index 33e5b3a..c917fc9 100644 --- a/chainConfigs/58008.json +++ b/chainConfigs/58008.json @@ -1,7 +1,7 @@ { "FACTORY_OWNER": "0xfAe426B462f4Bc9857ED28D8473Fb85192f23E9b", "FACTORY_UPGRADE_GATE_OWNER": "0xfAe426B462f4Bc9857ED28D8473Fb85192f23E9b", - "MINT_FEE_AMOUNT": 111000000000000, + "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x917D86f1eBD1d9f59Dae1C00e5Af7f8689299EC4", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", "SUBSCRIPTION_MARKET_FILTER_OWNER": "0x0000000000000000000000000000000000000000", diff --git a/chainConfigs/7777777.json b/chainConfigs/7777777.json index f9f8908..5654c34 100644 --- a/chainConfigs/7777777.json +++ b/chainConfigs/7777777.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0xEcfc2ee50409E459c554a2b0376F882Ce916D853", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } \ No newline at end of file diff --git a/chainConfigs/8453.json b/chainConfigs/8453.json index 916b019..94f50e2 100644 --- a/chainConfigs/8453.json +++ b/chainConfigs/8453.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x7bf90111Ad7C22bec9E9dFf8A01A44713CC1b1B6", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x000000000000AAeB6D7670E522A718067333cd4E", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/84531.json b/chainConfigs/84531.json index 7a45789..721b586 100644 --- a/chainConfigs/84531.json +++ b/chainConfigs/84531.json @@ -1,8 +1,9 @@ { "FACTORY_OWNER": "0x02539E813cA450C2c7334e885423f4A899a063Fe", "FACTORY_UPGRADE_GATE_OWNER": "0x02539E813cA450C2c7334e885423f4A899a063Fe", - "MINT_FEE_AMOUNT": 111000000000000, + "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x02539E813cA450C2c7334e885423f4A899a063Fe", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x9B414A3F7872bdd2E6513689214BD2Debbe48340", - "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f" + "ZORA_ERC721_TRANSFER_HELPER": "0xd1adAF05575295710dE1145c3c9427c364A70a7f", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } diff --git a/chainConfigs/999.json b/chainConfigs/999.json index a84c849..273cc19 100644 --- a/chainConfigs/999.json +++ b/chainConfigs/999.json @@ -4,5 +4,6 @@ "MINT_FEE_AMOUNT": 777000000000000, "MINT_FEE_RECIPIENT": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb", "SUBSCRIPTION_MARKET_FILTER_ADDRESS": "0x0000000000000000000000000000000000000000", - "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000" + "ZORA_ERC721_TRANSFER_HELPER": "0x0000000000000000000000000000000000000000", + "PROTOCOL_REWARDS": "0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B" } \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index c93998f..5a0b463 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] solc_version = '0.8.17' optimizer = true -optimizer_runs = 2383 +optimizer_runs = 300 via_ir = true out = 'out' test = 'test' @@ -33,6 +33,5 @@ zora_goerli = "https://testnet.rpc.zora.energy" base = "https://developer-access-mainnet.base.org" base_goerli = "https://goerli.base.org" - pgn = "https://rpc.publicgoods.network" pgn_sepolia = "https://sepolia.publicgoods.network" diff --git a/package.json b/package.json index 20dc1fa..0813c76 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ }, "dependencies": { "@dotenv/cli": "^2.2.2", + "@zoralabs/protocol-rewards": "^1.0.2", "ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b", "forge-std": "https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653" } diff --git a/remappings.txt b/remappings.txt index 3a80d29..099e00c 100644 --- a/remappings.txt +++ b/remappings.txt @@ -4,3 +4,4 @@ erc721a-upgradeable=lib/ERC721A-Upgradeable/contracts/ base64/=lib/base64/ ds-test/=node_modules/ds-test/src/ forge-std/=node_modules/forge-std/src/ +@zoralabs/protocol-rewards/=node_modules/@zoralabs/protocol-rewards/ \ No newline at end of file diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 1712d8e..99ae2fa 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -43,7 +43,8 @@ contract Deploy is ZoraDropsDeployBase { _factoryUpgradeGate: factoryUpgradeGate, _marketFilterDAOAddress: address(chainConfig.subscriptionMarketFilterAddress), _mintFeeAmount: chainConfig.mintFeeAmount, - _mintFeeRecipient: payable(chainConfig.mintFeeRecipient) + _mintFeeRecipient: payable(chainConfig.mintFeeRecipient), + _protocolRewards: address(chainConfig.protocolRewards) }); ZoraNFTCreatorV1 factoryImpl = new ZoraNFTCreatorV1(address(dropImplementation), editionMetadata, dropMetadata); diff --git a/script/UpgradeERC721DropFactory.s.sol b/script/UpgradeERC721DropFactory.s.sol index 28d3f18..591f43c 100644 --- a/script/UpgradeERC721DropFactory.s.sol +++ b/script/UpgradeERC721DropFactory.s.sol @@ -59,7 +59,8 @@ contract UpgradeERC721DropFactory is ZoraDropsDeployBase { _factoryUpgradeGate: IFactoryUpgradeGate(deployment.factoryUpgradeGate), _marketFilterDAOAddress: chainConfig.subscriptionMarketFilterAddress, _mintFeeAmount: chainConfig.mintFeeAmount, - _mintFeeRecipient: payable(chainConfig.mintFeeRecipient) + _mintFeeRecipient: payable(chainConfig.mintFeeRecipient), + _protocolRewards: chainConfig.protocolRewards }); deployment.dropImplementation = address(dropImplementation); diff --git a/script/ZoraDropsDeployBase.sol b/script/ZoraDropsDeployBase.sol index e10c6b5..1b4e9ff 100644 --- a/script/ZoraDropsDeployBase.sol +++ b/script/ZoraDropsDeployBase.sol @@ -9,7 +9,7 @@ import {IERC721Drop} from "../src/interfaces/IERC721Drop.sol"; /// @notice Deployment drops for base where abstract contract ZoraDropsDeployBase is ScriptDeploymentConfig { - + /// @notice Get deployment configuration struct as JSON /// @param deployment deploymet struct /// @return deploymentJson string JSON of the deployment info diff --git a/src/DeploymentConfig.sol b/src/DeploymentConfig.sol index d627ee9..d68d7cf 100644 --- a/src/DeploymentConfig.sol +++ b/src/DeploymentConfig.sol @@ -22,6 +22,8 @@ struct ChainConfig { address subscriptionMarketFilterOwner; /// @notice Auto-approved hyperstructure on mainnet for enabling ZORA v3 with less gas. Deprecated – safe to set to address(0x) address zoraERC721TransferHelper; + /// @notice The Protocol Rewards contract + address protocolRewards; } /// @notice Deployment addresses – set to new deployed addresses by the scripts. @@ -51,6 +53,8 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script /// @notice File used for demo metadata on verification test mint string constant DEMO_IPFS_METADATA_FILE = "ipfs://bafkreigu544g6wjvqcysurpzy5pcskbt45a5f33m6wgythpgb3rfqi3lzi"; + address constant DEFAULT_CREATE_REFERRAL = address(0); + /// // These are the JSON key constants to standardize writing and reading configuration /// @@ -62,6 +66,7 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script string constant SUBSCRIPTION_MARKET_FILTER_ADDRESS = "SUBSCRIPTION_MARKET_FILTER_ADDRESS"; string constant SUBSCRIPTION_MARKET_FILTER_OWNER = "SUBSCRIPTION_MARKET_FILTER_OWNER"; string constant ZORA_ERC721_TRANSFER_HELPER = "ZORA_ERC721_TRANSFER_HELPER"; + string constant PROTOCOL_REWARDS = "PROTOCOL_REWARDS"; string constant DROP_METADATA_RENDERER = "DROP_METADATA_RENDERER"; string constant EDITION_METADATA_RENDERER = "EDITION_METADATA_RENDERER"; @@ -86,8 +91,8 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script chainConfig.mintFeeAmount = json.readUint(getKeyPrefix(MINT_FEE_AMOUNT)); chainConfig.mintFeeRecipient = json.readAddress(getKeyPrefix(MINT_FEE_RECIPIENT)); chainConfig.subscriptionMarketFilterAddress = json.readAddress(getKeyPrefix(SUBSCRIPTION_MARKET_FILTER_ADDRESS)); - chainConfig.subscriptionMarketFilterOwner = json.readAddress(getKeyPrefix(SUBSCRIPTION_MARKET_FILTER_OWNER)); chainConfig.zoraERC721TransferHelper = json.readAddress(getKeyPrefix(ZORA_ERC721_TRANSFER_HELPER)); + chainConfig.protocolRewards = json.readAddress(getKeyPrefix(PROTOCOL_REWARDS)); } /// @notice Get the deployment configuration struct from the JSON configuration file diff --git a/src/ERC721Drop.sol b/src/ERC721Drop.sol index d12b5c1..eafb28d 100644 --- a/src/ERC721Drop.sol +++ b/src/ERC721Drop.sol @@ -24,6 +24,9 @@ import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/se import {MerkleProofUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import {MathUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; +import {IProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/interfaces/IProtocolRewards.sol"; +import {ERC721Rewards} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC721/ERC721Rewards.sol"; +import {ERC721RewardsStorageV1} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC721/ERC721RewardsStorageV1.sol"; import {IMetadataRenderer} from "./interfaces/IMetadataRenderer.sol"; import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"; @@ -58,9 +61,11 @@ contract ERC721Drop is PublicMulticall, OwnableSkeleton, FundsReceiver, - Version(13), + Version(14), ERC721DropStorageV1, - ERC721DropStorageV2 + ERC721DropStorageV2, + ERC721Rewards, + ERC721RewardsStorageV1 { /// @dev This is the max mint batch size for the optimized ERC721A mint contract uint256 internal immutable MAX_MINT_BATCH_SIZE = 8; @@ -181,8 +186,9 @@ contract ERC721Drop is IFactoryUpgradeGate _factoryUpgradeGate, address _marketFilterDAOAddress, uint256 _mintFeeAmount, - address payable _mintFeeRecipient - ) initializer { + address payable _mintFeeRecipient, + address _protocolRewards + ) initializer ERC721Rewards(_protocolRewards, _mintFeeRecipient) { zoraERC721TransferHelper = _zoraERC721TransferHelper; factoryUpgradeGate = _factoryUpgradeGate; marketFilterDAOAddress = _marketFilterDAOAddress; @@ -200,6 +206,7 @@ contract ERC721Drop is /// @param _setupCalls Bytes-encoded list of setup multicalls /// @param _metadataRenderer Renderer contract to use /// @param _metadataRendererInit Renderer data initial contract + /// @param _createReferral The platform where the collection was created function initialize( string memory _contractName, string memory _contractSymbol, @@ -209,7 +216,8 @@ contract ERC721Drop is uint16 _royaltyBPS, bytes[] calldata _setupCalls, IMetadataRenderer _metadataRenderer, - bytes memory _metadataRendererInit + bytes memory _metadataRendererInit, + address _createReferral ) public initializer { // Setup ERC721A __ERC721A_init(_contractName, _contractSymbol); @@ -240,6 +248,11 @@ contract ERC721Drop is config.metadataRenderer = _metadataRenderer; config.royaltyBPS = _royaltyBPS; config.fundsRecipient = _fundsRecipient; + + if (_createReferral != address(0)) { + _setCreateReferral(_createReferral); + } + _metadataRenderer.initializeWithData(_metadataRendererInit); } @@ -481,48 +494,56 @@ contract ERC721Drop is return _handlePurchase(recipient, quantity, comment); } + /// @notice Mint a quantity of tokens with a comment that will pay out rewards + /// @param recipient recipient of the tokens + /// @param quantity quantity to purchase + /// @param comment comment to include in the IERC721Drop.Sale event + /// @param mintReferral The finder of the mint + /// @return tokenId of the first token minted + function mintWithRewards(address recipient, uint256 quantity, string calldata comment, address mintReferral) + external + payable + nonReentrant + canMintTokens(quantity) + onlyPublicSaleActive + returns (uint256) + { + return _handleMintWithRewards(recipient, quantity, comment, mintReferral); + } + + function _handleMintWithRewards(address recipient, uint256 quantity, string calldata comment, address mintReferral) internal returns (uint256) { + _mintSupplyRoyalty(quantity); + _requireCanPurchaseQuantity(recipient, quantity); + + uint256 salePrice = salesConfig.publicSalePrice; + + _handleRewards(msg.value, quantity, salePrice, config.fundsRecipient != address(0) ? config.fundsRecipient : address(this), createReferral, mintReferral); + + _mintNFTs(recipient, quantity); + + uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; + + _emitSaleEvents(_msgSender(), recipient, quantity, salePrice, firstMintedTokenId, comment); + + 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; - if (msg.value != (salePrice + ZORA_MINT_FEE) * quantity) { - revert Purchase_WrongPrice((salePrice + ZORA_MINT_FEE) * quantity); - } - - // If max purchase per address == 0 there is no limit. - // Any other number, the per address mint limit is that. - if ( - salesConfig.maxSalePurchasePerAddress != 0 && - _numberMinted(recipient) + - quantity - - presaleMintsByAddress[recipient] > - salesConfig.maxSalePurchasePerAddress - ) { - revert Purchase_TooManyForAddress(); - } + _requireLegacyFee(msg.value, salePrice, quantity); _mintNFTs(recipient, quantity); uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; _payoutZoraFee(quantity); - emit IERC721Drop.Sale({ - to: recipient, - quantity: quantity, - pricePerToken: salePrice, - firstPurchasedTokenId: firstMintedTokenId - }); - if(bytes(comment).length > 0) { - emit IERC721Drop.MintComment({ - sender: _msgSender(), - tokenContract: address(this), - tokenId: firstMintedTokenId, - quantity: quantity, - comment: comment - }); - } + _emitSaleEvents(_msgSender(), recipient, quantity, salePrice, firstMintedTokenId, comment); + return firstMintedTokenId; } @@ -654,44 +675,28 @@ contract ERC721Drop is _mintSupplyRoyalty(quantity); _requireCanMintQuantity(quantity); - if ( - !MerkleProofUpgradeable.verify( - merkleProof, - salesConfig.presaleMerkleRoot, - keccak256( - // address, uint256, uint256 - abi.encode(_msgSender(), maxQuantity, pricePerToken) - ) - ) - ) { - revert Presale_MerkleNotApproved(); - } + address msgSender = _msgSender(); - if (msg.value != (pricePerToken + ZORA_MINT_FEE) * quantity) { - revert Purchase_WrongPrice( - (pricePerToken + ZORA_MINT_FEE) * quantity - ); - } + _requireMerkleApproval(msgSender, maxQuantity, pricePerToken, merkleProof); - presaleMintsByAddress[_msgSender()] += quantity; - if (presaleMintsByAddress[_msgSender()] > maxQuantity) { - revert Presale_TooManyForAddress(); - } + _requireLegacyFee(msg.value, pricePerToken, quantity); + + _requireCanPurchasePresale(msgSender, quantity, maxQuantity); - _mintNFTs(_msgSender(), quantity); + _mintNFTs(msgSender, quantity); uint256 firstMintedTokenId = _lastMintedTokenId() - quantity; _payoutZoraFee(quantity); emit IERC721Drop.Sale({ - to: _msgSender(), + to: msgSender, quantity: quantity, pricePerToken: pricePerToken, firstPurchasedTokenId: firstMintedTokenId }); if (bytes(comment).length > 0) { emit IERC721Drop.MintComment({ - sender: _msgSender(), + sender: msgSender, tokenContract: address(this), tokenId: firstMintedTokenId, quantity: quantity, @@ -702,6 +707,58 @@ contract ERC721Drop is return firstMintedTokenId; } + /// @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 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 calldata comment, + address mintReferral + ) internal returns (uint256) { + _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; + } + /** *** ---------------------------------- *** *** *** @@ -750,14 +807,11 @@ contract ERC721Drop is /// @notice Hook to filter operators (no-op if no filters are registered) /// @dev Part of ERC721A token hooks /// @param from Transfer from user - /// @param to Transfer to user - /// @param startTokenId Token ID to start with - /// @param quantity Quantity of token being transferred function _beforeTokenTransfers( address from, - address to, - uint256 startTokenId, - uint256 quantity + address, + uint256, + uint256 ) internal virtual override { if ( from != address(0) && // skip on mints @@ -1136,16 +1190,9 @@ contract ERC721Drop is function withdraw() external nonReentrant { address sender = _msgSender(); - uint256 funds = address(this).balance; + _verifyWithdrawAccess(sender); - // Check if withdraw is allowed for sender - if ( - !hasRole(DEFAULT_ADMIN_ROLE, sender) && - !hasRole(SALES_MANAGER_ROLE, sender) && - sender != config.fundsRecipient - ) { - revert Access_WithdrawNotAllowed(); - } + uint256 funds = address(this).balance; // Payout recipient (bool successFunds, ) = config.fundsRecipient.call{ @@ -1166,6 +1213,29 @@ contract ERC721Drop is ); } + /// @notice This withdraws ETH from the protocol rewards contract to an address specified by the contract owner. + function withdrawRewards(address to, uint256 amount) external nonReentrant { + _verifyWithdrawAccess(msg.sender); + + bytes memory data = abi.encodeWithSelector(IProtocolRewards.withdraw.selector, to, amount); + + (bool success, ) = address(protocolRewards).call(data); + + if (!success) { + revert ProtocolRewards_WithdrawSendFailure(); + } + } + + function _verifyWithdrawAccess(address msgSender) internal view { + if ( + !hasRole(DEFAULT_ADMIN_ROLE, msgSender) && + !hasRole(SALES_MANAGER_ROLE, msgSender) && + msgSender != config.fundsRecipient + ) { + revert Access_WithdrawNotAllowed(); + } + } + // ,-. // `-' // /|\ @@ -1290,12 +1360,58 @@ 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(); } } + function _requireCanPurchaseQuantity(address recipient, uint256 quantity) internal view { + // If max purchase per address == 0 there is no limit. + // Any other number, the per address mint limit is that. + if ( + salesConfig.maxSalePurchasePerAddress != 0 + && _numberMinted(recipient) + quantity - presaleMintsByAddress[recipient] + > salesConfig.maxSalePurchasePerAddress + ) { + revert Purchase_TooManyForAddress(); + } + } + + function _requireCanPurchasePresale(address recipient, uint256 quantity, uint256 maxQuantity) internal { + presaleMintsByAddress[recipient] += quantity; + + if (presaleMintsByAddress[recipient] > maxQuantity) { + revert Presale_TooManyForAddress(); + } + } + + function _requireMerkleApproval( + address recipient, + uint256 maxQuantity, + uint256 pricePerToken, + bytes32[] calldata merkleProof + ) internal view { + if ( + !MerkleProofUpgradeable.verify( + merkleProof, + salesConfig.presaleMerkleRoot, + keccak256( + // address, uint256, uint256 + abi.encode(recipient, maxQuantity, pricePerToken) + ) + ) + ) { + revert Presale_MerkleNotApproved(); + } + } + function _mintSupplyRoyalty(uint256 mintQuantity) internal { uint32 royaltySchedule = royaltyMintSchedule; if (royaltySchedule == 0) { @@ -1321,6 +1437,35 @@ contract ERC721Drop is royaltyMintSchedule = newSchedule; } + function updateCreateReferral(address recipient) external { + if (msg.sender != createReferral) revert ONLY_CREATE_REFERRAL(); + + _setCreateReferral(recipient); + } + + function _setCreateReferral(address recipient) internal { + createReferral = recipient; + } + + function _emitSaleEvents(address msgSender, address recipient, uint256 quantity, uint256 pricePerToken, uint256 firstMintedTokenId, string memory comment) internal { + emit IERC721Drop.Sale({ + to: recipient, + 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 + }); + } + } + /// @notice ERC165 supports interface /// @param interfaceId interface id to check if supported function supportsInterface(bytes4 interfaceId) diff --git a/src/ZoraNFTCreatorV1.sol b/src/ZoraNFTCreatorV1.sol index 0aa9013..d093ad6 100644 --- a/src/ZoraNFTCreatorV1.sol +++ b/src/ZoraNFTCreatorV1.sol @@ -14,7 +14,7 @@ import {ERC721Drop} from "./ERC721Drop.sol"; import {IContractMetadata} from "./interfaces/IContractMetadata.sol"; /// @notice Zora NFT Creator V1 -contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetadata, Version(7) { +contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetadata, Version(8) { string private constant CANNOT_BE_ZERO = "Cannot be 0 address"; /// @notice Emitted when a edition is created reserving the corresponding token IDs. @@ -85,7 +85,8 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad address payable fundsRecipient, bytes[] memory setupCalls, IMetadataRenderer metadataRenderer, - bytes memory metadataInitializer + bytes memory metadataInitializer, + address createReferral ) public returns (address payable newDropAddress) { ERC721DropProxy newDrop = new ERC721DropProxy(implementation, ""); @@ -99,7 +100,8 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad _royaltyBPS: royaltyBPS, _setupCalls: setupCalls, _metadataRenderer: metadataRenderer, - _metadataRendererInit: metadataInitializer + _metadataRendererInit: metadataInitializer, + _createReferral: createReferral }); } @@ -152,7 +154,8 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad address payable fundsRecipient, IERC721Drop.SalesConfiguration memory saleConfig, IMetadataRenderer metadataRenderer, - bytes memory metadataInitializer + bytes memory metadataInitializer, + address createReferral ) public returns (address) { bytes[] memory setupData = new bytes[](1); setupData[0] = abi.encodeWithSelector( @@ -174,7 +177,8 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad royaltyBPS: royaltyBPS, setupCalls: setupData, metadataRenderer: metadataRenderer, - metadataInitializer: metadataInitializer + metadataInitializer: metadataInitializer, + createReferral: createReferral }); emit CreatedDrop({ @@ -252,7 +256,39 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad fundsRecipient: fundsRecipient, saleConfig: saleConfig, metadataRenderer: dropMetadataRenderer, - metadataInitializer: metadataInitializer + metadataInitializer: metadataInitializer, + createReferral: address(0) + }); + } + + function createDropWithReferral( + string memory name, + string memory symbol, + address defaultAdmin, + uint64 editionSize, + uint16 royaltyBPS, + address payable fundsRecipient, + IERC721Drop.SalesConfiguration memory saleConfig, + string memory metadataURIBase, + string memory metadataContractURI, + address createReferral + ) external returns (address) { + bytes memory metadataInitializer = abi.encode( + metadataURIBase, + metadataContractURI + ); + return + setupDropsContract({ + defaultAdmin: defaultAdmin, + name: name, + symbol: symbol, + royaltyBPS: royaltyBPS, + editionSize: editionSize, + fundsRecipient: fundsRecipient, + saleConfig: saleConfig, + metadataRenderer: dropMetadataRenderer, + metadataInitializer: metadataInitializer, + createReferral: createReferral }); } @@ -327,7 +363,42 @@ contract ZoraNFTCreatorV1 is OwnableUpgradeable, UUPSUpgradeable, IContractMetad saleConfig: saleConfig, fundsRecipient: fundsRecipient, metadataRenderer: editionMetadataRenderer, - metadataInitializer: metadataInitializer + metadataInitializer: metadataInitializer, + createReferral: address(0) + }); + } + + function createEditionWithReferral( + string memory name, + string memory symbol, + uint64 editionSize, + uint16 royaltyBPS, + address payable fundsRecipient, + address defaultAdmin, + IERC721Drop.SalesConfiguration memory saleConfig, + string memory description, + string memory animationURI, + string memory imageURI, + address createReferral + ) external returns (address) { + bytes memory metadataInitializer = abi.encode( + description, + imageURI, + animationURI + ); + + return + setupDropsContract({ + name: name, + symbol: symbol, + defaultAdmin: defaultAdmin, + editionSize: editionSize, + royaltyBPS: royaltyBPS, + saleConfig: saleConfig, + fundsRecipient: fundsRecipient, + metadataRenderer: editionMetadataRenderer, + metadataInitializer: metadataInitializer, + createReferral: createReferral }); } } diff --git a/src/interfaces/IERC721Drop.sol b/src/interfaces/IERC721Drop.sol index dd8d6e2..1dae224 100644 --- a/src/interfaces/IERC721Drop.sol +++ b/src/interfaces/IERC721Drop.sol @@ -31,6 +31,8 @@ interface IERC721Drop { error Withdraw_FundsSendFailure(); /// @notice Mint fee send failure error MintFee_FundsSendFailure(); + /// @notice Protocol Rewards withdraw failure + error ProtocolRewards_WithdrawSendFailure(); /// @notice Call to external metadata renderer failed. error ExternalMetadataRenderer_CallFailed(); diff --git a/test/ERC721Drop.t.sol b/test/ERC721Drop.t.sol index 68368c7..a399882 100644 --- a/test/ERC721Drop.t.sol +++ b/test/ERC721Drop.t.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; import {IERC721AUpgradeable} from "erc721a-upgradeable/IERC721AUpgradeable.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; +import {RewardsSettings} from "@zoralabs/protocol-rewards/dist/contracts/abstract/RewardSplits.sol"; import {ERC721Drop} from "../src/ERC721Drop.sol"; import {DummyMetadataRenderer} from "./utils/DummyMetadataRenderer.sol"; @@ -33,35 +35,35 @@ contract ERC721DropTest is Test { ); event Sale( - address indexed to, - uint256 indexed quantity, - uint256 indexed pricePerToken, - uint256 firstPurchasedTokenId + address indexed to, uint256 indexed purchaseQuantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId ); event MintComment( - address indexed sender, - address indexed tokenContract, - uint256 indexed tokenId, - uint256 quantity, - string comment + address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 purchaseQuantity, string comment ); + address internal creator; + address internal collector; + address internal mintReferral; + address internal createReferral; + address internal zora; + + ProtocolRewards protocolRewards; ERC721Drop zoraNFTBase; MockUser mockUser; DummyMetadataRenderer public dummyRenderer = new DummyMetadataRenderer(); FactoryUpgradeGate public factoryUpgradeGate; address public constant DEFAULT_OWNER_ADDRESS = address(0x23499); - address payable public constant DEFAULT_FUNDS_RECIPIENT_ADDRESS = - payable(address(0x21303)); - address payable public constant DEFAULT_ZORA_DAO_ADDRESS = - payable(address(0x999)); + address payable public constant DEFAULT_FUNDS_RECIPIENT_ADDRESS = payable(address(0x21303)); + address payable public constant DEFAULT_ZORA_DAO_ADDRESS = payable(address(0x999)); address public constant UPGRADE_GATE_ADMIN_ADDRESS = address(0x942924224); address public constant mediaContract = address(0x123456); address public impl; address public ownedSubscriptionManager; address payable public constant mintFeeRecipient = payable(address(0x11)); uint256 public constant mintFee = 777000000000000; // 0.000777 ETH + uint256 public constant TOTAL_REWARD_PER_MINT = 0.000999 ether; + address internal constant DEFAULT_CREATE_REFERRAL = address(0); struct Configuration { IMetadataRenderer metadataRenderer; @@ -81,22 +83,44 @@ contract ERC721DropTest is Test { _royaltyBPS: 800, _setupCalls: setupCalls, _metadataRenderer: dummyRenderer, - _metadataRendererInit: "" + _metadataRendererInit: "", + _createReferral: DEFAULT_CREATE_REFERRAL + }); + + _; + } + + modifier setupZoraNFTBaseWithCreateReferral(uint64 editionSize, address initCreateReferral) { + bytes[] memory setupCalls = new bytes[](0); + zoraNFTBase.initialize({ + _contractName: "Test NFT", + _contractSymbol: "TNFT", + _initialOwner: DEFAULT_OWNER_ADDRESS, + _fundsRecipient: payable(DEFAULT_FUNDS_RECIPIENT_ADDRESS), + _editionSize: editionSize, + _royaltyBPS: 800, + _setupCalls: setupCalls, + _metadataRenderer: dummyRenderer, + _metadataRendererInit: "", + _createReferral: initCreateReferral }); _; } function setUp() public { + creator = makeAddr("creator"); + collector = makeAddr("collector"); + mintReferral = makeAddr("mintReferral"); + createReferral = makeAddr("createReferral"); + zora = makeAddr("zora"); + + protocolRewards = new ProtocolRewards(); + vm.prank(DEFAULT_ZORA_DAO_ADDRESS); factoryUpgradeGate = new FactoryUpgradeGate(UPGRADE_GATE_ADMIN_ADDRESS); - vm.etch( - address(0x000000000000AAeB6D7670E522A718067333cd4E), - address(new OperatorFilterRegistry()).code - ); - ownedSubscriptionManager = address( - new OwnedSubscriptionManager(address(0x123456)) - ); + vm.etch(address(0x000000000000AAeB6D7670E522A718067333cd4E), address(new OperatorFilterRegistry()).code); + ownedSubscriptionManager = address(new OwnedSubscriptionManager(address(0x123456))); vm.prank(DEFAULT_ZORA_DAO_ADDRESS); impl = address( @@ -105,12 +129,11 @@ contract ERC721DropTest is Test { factoryUpgradeGate, address(0x0), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ) ); - address payable newDrop = payable( - address(new ERC721DropProxy(impl, "")) - ); + address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); } @@ -122,37 +145,26 @@ contract ERC721DropTest is Test { factoryUpgradeGate, address(subscriptionAddress), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ) ); - address payable newDrop = payable( - address(new ERC721DropProxy(impl, "")) - ); + address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); _; } function test_Init() public setupZoraNFTBase(10) { - require( - zoraNFTBase.owner() == DEFAULT_OWNER_ADDRESS, - "Default owner set wrong" - ); + require(zoraNFTBase.owner() == DEFAULT_OWNER_ADDRESS, "Default owner set wrong"); - ( - IMetadataRenderer renderer, - uint64 editionSize, - uint16 royaltyBPS, - address payable fundsRecipient - ) = zoraNFTBase.config(); + (IMetadataRenderer renderer, uint64 editionSize, uint16 royaltyBPS, address payable fundsRecipient) = + zoraNFTBase.config(); require(address(renderer) == address(dummyRenderer)); require(editionSize == 10, "EditionSize is wrong"); require(royaltyBPS == 800, "RoyaltyBPS is wrong"); - require( - fundsRecipient == payable(DEFAULT_FUNDS_RECIPIENT_ADDRESS), - "FundsRecipient is wrong" - ); + require(fundsRecipient == payable(DEFAULT_FUNDS_RECIPIENT_ADDRESS), "FundsRecipient is wrong"); string memory name = zoraNFTBase.name(); string memory symbol = zoraNFTBase.symbol(); @@ -170,7 +182,8 @@ contract ERC721DropTest is Test { _royaltyBPS: 800, _setupCalls: setupCalls, _metadataRenderer: dummyRenderer, - _metadataRendererInit: "" + _metadataRendererInit: "", + _createReferral: DEFAULT_CREATE_REFERRAL }); } @@ -204,15 +217,10 @@ contract ERC721DropTest is Test { factoryWithSubscriptionAddress(ownedSubscriptionManager) setupZoraNFTBase(10) { - IOperatorFilterRegistry operatorFilterRegistry = IOperatorFilterRegistry( - 0x000000000000AAeB6D7670E522A718067333cd4E - ); + IOperatorFilterRegistry operatorFilterRegistry = + IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); vm.startPrank(address(0x123456)); - operatorFilterRegistry.updateOperator( - ownedSubscriptionManager, - address(0xcafeea3), - true - ); + operatorFilterRegistry.updateOperator(ownedSubscriptionManager, address(0xcafeea3), true); vm.stopPrank(); vm.startPrank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.manageMarketFilterDAOSubscription(true); @@ -221,10 +229,7 @@ contract ERC721DropTest is Test { vm.stopPrank(); vm.prank(address(0xcafeea3)); vm.expectRevert( - abi.encodeWithSelector( - OperatorFilterRegistryErrorsAndEvents.AddressFiltered.selector, - address(0xcafeea3) - ) + abi.encodeWithSelector(OperatorFilterRegistryErrorsAndEvents.AddressFiltered.selector, address(0xcafeea3)) ); zoraNFTBase.transferFrom(DEFAULT_OWNER_ADDRESS, address(0x123456), 1); vm.prank(DEFAULT_OWNER_ADDRESS); @@ -249,10 +254,7 @@ contract ERC721DropTest is Test { factoryWithSubscriptionAddress(ownedSubscriptionManager) setupZoraNFTBase(10) { - bytes memory baseCall = abi.encodeWithSelector( - IOperatorFilterRegistry.register.selector, - address(zoraNFTBase) - ); + bytes memory baseCall = abi.encodeWithSelector(IOperatorFilterRegistry.register.selector, address(zoraNFTBase)); vm.startPrank(address(0xcafecafe)); vm.expectRevert(IERC721Drop.Access_OnlyAdmin.selector); zoraNFTBase.updateMarketFilterSettings(baseCall); @@ -265,41 +267,26 @@ contract ERC721DropTest is Test { setupZoraNFTBase(10) { vm.startPrank(address(DEFAULT_OWNER_ADDRESS)); - bytes memory baseCall = abi.encodeWithSelector( - IOperatorFilterRegistry.register.selector, - address(zoraNFTBase) - ); + bytes memory baseCall = abi.encodeWithSelector(IOperatorFilterRegistry.register.selector, address(zoraNFTBase)); zoraNFTBase.updateMarketFilterSettings(baseCall); vm.stopPrank(); } function test_RoyaltyInfo() public setupZoraNFTBase(10) { // assert 800 royaltyAmount or 8% - (address recipient, uint256 royaltyAmount) = zoraNFTBase.royaltyInfo( - 10, - 1 ether - ); + ( , uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); assertEq(royaltyAmount, 0.08 ether); } - function test_NoRoyaltyInfoNoFundsRecipientAddress() - public - setupZoraNFTBase(10) - { + function test_NoRoyaltyInfoNoFundsRecipientAddress() public setupZoraNFTBase(10) { vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setFundsRecipient(payable(address(0))); // assert 800 royaltyAmount or 8% - (address recipient, uint256 royaltyAmount) = zoraNFTBase.royaltyInfo( - 10, - 1 ether - ); + ( , uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); assertEq(royaltyAmount, 0 ether); } - function test_Purchase( - uint64 salePrice, - uint32 purchaseQuantity - ) public setupZoraNFTBase(purchaseQuantity) { + function test_Purchase(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -317,28 +304,20 @@ contract ERC721DropTest is Test { vm.deal(address(456), paymentAmount); vm.prank(address(456)); vm.expectEmit(true, true, true, true); - emit Sale( - address(456), - purchaseQuantity, - salePrice, - 0 - ); + emit Sale(address(456), purchaseQuantity, salePrice, 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" - ); + require(zoraNFTBase.ownerOf(1) == address(456), "owner is wrong for new minted token"); assertEq(address(zoraNFTBase).balance, paymentAmount - zoraFee); assertEq(mintFeeRecipient.balance, zoraFee); } - function test_PurchaseWithComment( - uint64 salePrice, - uint32 purchaseQuantity - ) public setupZoraNFTBase(purchaseQuantity) { + function test_PurchaseWithComment(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -356,17 +335,14 @@ contract ERC721DropTest is Test { vm.deal(address(456), paymentAmount); vm.prank(address(456)); vm.expectEmit(true, true, true, true); - emit MintComment( - address(456), - address(zoraNFTBase), - 0, - purchaseQuantity, - "test comment" - ); + emit MintComment(address(456), address(zoraNFTBase), 0, purchaseQuantity, "test comment"); zoraNFTBase.purchaseWithComment{value: paymentAmount}(purchaseQuantity, "test comment"); } - function test_PurchaseWithRecipient(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { + function test_PurchaseWithRecipient(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -389,12 +365,15 @@ contract ERC721DropTest is Test { vm.prank(minter); zoraNFTBase.purchaseWithRecipient{value: paymentAmount}(recipient, purchaseQuantity, ""); - for (uint256 i; i < purchaseQuantity; ) { + for (uint256 i; i < purchaseQuantity;) { assertEq(zoraNFTBase.ownerOf(++i), recipient); } } - function test_PurchaseWithRecipientAndComment(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { + function test_PurchaseWithRecipientAndComment(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -416,18 +395,15 @@ contract ERC721DropTest is Test { vm.deal(minter, paymentAmount); vm.expectEmit(true, true, true, true); - emit MintComment( - minter, - address(zoraNFTBase), - 0, - purchaseQuantity, - "test comment" - ); + emit MintComment(minter, address(zoraNFTBase), 0, purchaseQuantity, "test comment"); vm.prank(minter); zoraNFTBase.purchaseWithRecipient{value: paymentAmount}(recipient, purchaseQuantity, "test comment"); } - function testRevert_PurchaseWithInvalidRecipient(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { + function testRevert_PurchaseWithInvalidRecipient(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -443,7 +419,6 @@ contract ERC721DropTest is Test { (, uint256 zoraFee) = zoraNFTBase.zoraFeeForAmount(purchaseQuantity); uint256 paymentAmount = uint256(salePrice) * purchaseQuantity + zoraFee; - address minter = makeAddr("minter"); address recipient = address(0); @@ -452,7 +427,299 @@ contract ERC721DropTest is Test { vm.expectRevert(abi.encodeWithSignature("MintToZeroAddress()")); vm.prank(minter); zoraNFTBase.purchaseWithRecipient{value: paymentAmount}(recipient, purchaseQuantity, ""); - } + } + + function test_FreeMintRewards(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 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + + RewardsSettings memory settings = zoraNFTBase.computeFreeMintRewards(purchaseQuantity); + + vm.deal(collector, totalReward); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalReward}(collector, purchaseQuantity, "test comment", address(0)); + + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.creatorReward + settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.mintReferralReward + settings.createReferralReward); + } + + function test_FreeMintRewardsWithMintReferral(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 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + + RewardsSettings memory settings = zoraNFTBase.computeFreeMintRewards(purchaseQuantity); + + vm.deal(collector, totalReward); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalReward}(collector, purchaseQuantity, "test comment", mintReferral); + + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.creatorReward + settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.createReferralReward); + assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); + } + + function test_FreeMintRewardsWithCreateReferral(uint32 purchaseQuantity) + public + setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) + { + 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 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + + RewardsSettings memory settings = zoraNFTBase.computeFreeMintRewards(purchaseQuantity); + + vm.deal(collector, totalReward); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalReward}(collector, purchaseQuantity, "test comment", address(0)); + + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.creatorReward + settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.mintReferralReward); + assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); + } + + function test_FreeMintRewardsWithMintAndCreateReferrals(uint32 purchaseQuantity) + public + setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) + { + 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 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + + RewardsSettings memory settings = zoraNFTBase.computeFreeMintRewards(purchaseQuantity); + + vm.deal(collector, totalReward); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalReward}(collector, purchaseQuantity, "test comment", mintReferral); + + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.creatorReward + settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward); + assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); + assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); + } + + function testRevert_FreeMintRewardsInsufficientEth(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) + }); + + vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()")); + zoraNFTBase.mintWithRewards(collector, purchaseQuantity, "test comment", address(0)); + } + + function test_PaidMintRewards(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { + vm.assume(salePrice > 0); + vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); + + vm.prank(DEFAULT_OWNER_ADDRESS); + zoraNFTBase.setSaleConfiguration({ + publicSaleStart: 0, + publicSaleEnd: type(uint64).max, + presaleStart: 0, + presaleEnd: 0, + publicSalePrice: salePrice, + maxSalePurchasePerAddress: purchaseQuantity + 1, + presaleMerkleRoot: bytes32(0) + }); + + RewardsSettings memory settings = zoraNFTBase.computePaidMintRewards(purchaseQuantity); + + uint256 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + uint256 totalSales = uint256(salePrice) * purchaseQuantity; + uint256 totalPayment = totalSales + totalReward; + + vm.deal(collector, totalPayment); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalPayment}(collector, purchaseQuantity, "test comment", address(0)); + + assertEq(address(zoraNFTBase).balance, totalSales); + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.mintReferralReward + settings.createReferralReward); + } + + function test_PaidMintRewardsWithMintReferral(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { + vm.assume(salePrice > 0); + vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); + + vm.prank(DEFAULT_OWNER_ADDRESS); + zoraNFTBase.setSaleConfiguration({ + publicSaleStart: 0, + publicSaleEnd: type(uint64).max, + presaleStart: 0, + presaleEnd: 0, + publicSalePrice: salePrice, + maxSalePurchasePerAddress: purchaseQuantity + 1, + presaleMerkleRoot: bytes32(0) + }); + + RewardsSettings memory settings = zoraNFTBase.computePaidMintRewards(purchaseQuantity); + uint256 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + uint256 totalSales = uint256(salePrice) * purchaseQuantity; + uint256 totalPayment = totalSales + totalReward; + + vm.deal(collector, totalPayment); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalPayment}(collector, purchaseQuantity, "test comment", mintReferral); + + assertEq(address(zoraNFTBase).balance, totalSales); + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.createReferralReward); + assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); + } + + function test_PaidMintRewardsWithCreateReferral(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) + { + vm.assume(salePrice > 0); + vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); + + vm.prank(DEFAULT_OWNER_ADDRESS); + zoraNFTBase.setSaleConfiguration({ + publicSaleStart: 0, + publicSaleEnd: type(uint64).max, + presaleStart: 0, + presaleEnd: 0, + publicSalePrice: salePrice, + maxSalePurchasePerAddress: purchaseQuantity + 1, + presaleMerkleRoot: bytes32(0) + }); + + RewardsSettings memory settings = zoraNFTBase.computePaidMintRewards(purchaseQuantity); + + uint256 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + uint256 totalSales = uint256(salePrice) * purchaseQuantity; + uint256 totalPayment = totalSales + totalReward; + + vm.deal(collector, totalPayment); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalPayment}(collector, purchaseQuantity, "test comment", address(0)); + + assertEq(address(zoraNFTBase).balance, totalSales); + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.mintReferralReward); + assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); + } + + function test_PaidMintRewardsWithMintAndCreateReferrals(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) + { + vm.assume(salePrice > 0); + vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); + + vm.prank(DEFAULT_OWNER_ADDRESS); + zoraNFTBase.setSaleConfiguration({ + publicSaleStart: 0, + publicSaleEnd: type(uint64).max, + presaleStart: 0, + presaleEnd: 0, + publicSalePrice: salePrice, + maxSalePurchasePerAddress: purchaseQuantity + 1, + presaleMerkleRoot: bytes32(0) + }); + + RewardsSettings memory settings = zoraNFTBase.computePaidMintRewards(purchaseQuantity); + + uint256 totalReward = zoraNFTBase.computeTotalReward(purchaseQuantity); + uint256 totalSales = uint256(salePrice) * purchaseQuantity; + uint256 totalPayment = totalSales + totalReward; + + vm.deal(collector, totalPayment); + vm.prank(collector); + zoraNFTBase.mintWithRewards{value: totalPayment}(collector, purchaseQuantity, "test comment", mintReferral); + + assertEq(address(zoraNFTBase).balance, totalSales); + assertEq(protocolRewards.balanceOf(DEFAULT_FUNDS_RECIPIENT_ADDRESS), settings.firstMinterReward); + assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward); + assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); + assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); + } + + function testRevert_PaidMintRewardsInsufficientEth(uint64 salePrice, uint32 purchaseQuantity) + public + setupZoraNFTBase(purchaseQuantity) + { + vm.assume(salePrice > 0); + vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); + + vm.prank(DEFAULT_OWNER_ADDRESS); + zoraNFTBase.setSaleConfiguration({ + publicSaleStart: 0, + publicSaleEnd: type(uint64).max, + presaleStart: 0, + presaleEnd: 0, + publicSalePrice: salePrice, + maxSalePurchasePerAddress: purchaseQuantity + 1, + presaleMerkleRoot: bytes32(0) + }); + + vm.expectRevert(abi.encodeWithSignature("INVALID_ETH_AMOUNT()")); + zoraNFTBase.mintWithRewards(collector, purchaseQuantity, "test comment", address(0)); + } function test_UpgradeApproved() public setupZoraNFTBase(10) { address newImpl = address( @@ -461,17 +728,15 @@ contract ERC721DropTest is Test { factoryUpgradeGate, address(0x0), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ) ); address[] memory lastImpls = new address[](1); lastImpls[0] = impl; vm.prank(UPGRADE_GATE_ADMIN_ADDRESS); - factoryUpgradeGate.registerNewUpgradePath({ - _newImpl: newImpl, - _supportedPrevImpls: lastImpls - }); + factoryUpgradeGate.registerNewUpgradePath({_newImpl: newImpl, _supportedPrevImpls: lastImpls}); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.upgradeTo(newImpl); } @@ -483,17 +748,13 @@ contract ERC721DropTest is Test { factoryUpgradeGate, address(0x0), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ) ); vm.prank(DEFAULT_OWNER_ADDRESS); - vm.expectRevert( - abi.encodeWithSelector( - IERC721Drop.Admin_InvalidUpgradeAddress.selector, - newImpl - ) - ); + vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Admin_InvalidUpgradeAddress.selector, newImpl)); zoraNFTBase.upgradeTo(newImpl); } @@ -550,10 +811,7 @@ contract ERC721DropTest is Test { zoraNFTBase.adminMint(DEFAULT_OWNER_ADDRESS, 1); assertEq(zoraNFTBase.saleDetails().maxSupply, 10); assertEq(zoraNFTBase.saleDetails().totalMinted, 1); - require( - zoraNFTBase.ownerOf(1) == DEFAULT_OWNER_ADDRESS, - "Owner is wrong for new minted token" - ); + require(zoraNFTBase.ownerOf(1) == DEFAULT_OWNER_ADDRESS, "Owner is wrong for new minted token"); } function test_MulticallAccessControl() public setupZoraNFTBase(10) { @@ -568,25 +826,14 @@ contract ERC721DropTest is Test { presaleMerkleRoot: bytes32(0) }); - address notAdmin = address(0x444); bytes[] memory calls = new bytes[](2); - calls[0] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - address(0x456), - 1 - ); - calls[1] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - address(0x123), - 3 - ); + calls[0] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x456), 1); + calls[1] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); vm.expectRevert( abi.encodeWithSelector( IERC721Drop.Access_MissingRoleOrAdmin.selector, - bytes32( - 0xf0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9 - ) + bytes32(0xf0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9) ) ); zoraNFTBase.multicall(calls); @@ -603,47 +850,14 @@ contract ERC721DropTest is Test { function test_MintMulticall() public setupZoraNFTBase(10) { vm.startPrank(DEFAULT_OWNER_ADDRESS); bytes[] memory calls = new bytes[](3); - calls[0] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - DEFAULT_OWNER_ADDRESS, - 5 - ); - calls[1] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - address(0x123), - 3 - ); + calls[0] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, DEFAULT_OWNER_ADDRESS, 5); + calls[1] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); calls[2] = abi.encodeWithSelector(IERC721Drop.saleDetails.selector); bytes[] memory results = zoraNFTBase.multicall(calls); - ( - bool saleActive, - bool presaleActive, - uint256 publicSalePrice, - , - , - , - , - , - , - , - - ) = abi.decode( - results[2], - ( - bool, - bool, - uint256, - uint64, - uint64, - uint64, - uint64, - bytes32, - uint256, - uint256, - uint256 - ) - ); + (bool saleActive, bool presaleActive, uint256 publicSalePrice,,,,,,,,) = abi.decode( + results[2], (bool, bool, uint256, uint64, uint64, uint64, uint64, bytes32, uint256, uint256, uint256) + ); assertTrue(!saleActive); assertTrue(!presaleActive); assertEq(publicSalePrice, 0); @@ -657,25 +871,10 @@ contract ERC721DropTest is Test { vm.startPrank(DEFAULT_OWNER_ADDRESS); bytes[] memory calls = new bytes[](3); calls[0] = abi.encodeWithSelector( - IERC721Drop.setSaleConfiguration.selector, - 0.1 ether, - 2, - 0, - type(uint64).max, - 0, - 0, - bytes32(0) - ); - calls[1] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - address(0x123), - 3 - ); - calls[2] = abi.encodeWithSelector( - IERC721Drop.adminMint.selector, - address(0x123), - 3 + IERC721Drop.setSaleConfiguration.selector, 0.1 ether, 2, 0, type(uint64).max, 0, 0, bytes32(0) ); + calls[1] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); + calls[2] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); bytes[] memory results = zoraNFTBase.multicall(calls); IERC721Drop.SaleDetails memory saleDetails = zoraNFTBase.saleDetails(); @@ -712,12 +911,7 @@ contract ERC721DropTest is Test { }); (, uint256 fee) = zoraNFTBase.zoraFeeForAmount(1); vm.prank(address(456)); - vm.expectRevert( - abi.encodeWithSelector( - IERC721Drop.Purchase_WrongPrice.selector, - 0.15 ether + fee - ) - ); + vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Purchase_WrongPrice.selector, 0.15 ether + fee)); zoraNFTBase.purchase{value: 0.12 ether}(1); } @@ -729,20 +923,14 @@ contract ERC721DropTest is Test { vm.prank(DEFAULT_OWNER_ADDRESS); vm.expectEmit(true, true, true, true); emit FundsWithdrawn( - DEFAULT_OWNER_ADDRESS, - DEFAULT_FUNDS_RECIPIENT_ADDRESS, - leftoverFunds, - payable(address(0)), - 0 + DEFAULT_OWNER_ADDRESS, DEFAULT_FUNDS_RECIPIENT_ADDRESS, leftoverFunds, payable(address(0)), 0 ); zoraNFTBase.withdraw(); assertEq(DEFAULT_FUNDS_RECIPIENT_ADDRESS.balance, amount); } - function test_WithdrawNoZoraFee( - uint128 amount - ) public setupZoraNFTBase(10) { + function test_WithdrawNoZoraFee(uint128 amount) public setupZoraNFTBase(10) { vm.assume(amount > 0.01 ether); address payable fundsRecipientTarget = payable(address(0x0)); @@ -753,13 +941,7 @@ contract ERC721DropTest is Test { vm.deal(address(zoraNFTBase), amount); vm.prank(DEFAULT_OWNER_ADDRESS); vm.expectEmit(true, true, true, true); - emit FundsWithdrawn( - DEFAULT_OWNER_ADDRESS, - fundsRecipientTarget, - amount, - payable(address(0)), - 0 - ); + emit FundsWithdrawn(DEFAULT_OWNER_ADDRESS, fundsRecipientTarget, amount, payable(address(0)), 0); zoraNFTBase.withdraw(); assertTrue(fundsRecipientTarget.balance == uint256(amount)); @@ -781,9 +963,7 @@ contract ERC721DropTest is Test { (, uint256 limitFee) = zoraNFTBase.zoraFeeForAmount(limit); vm.deal(address(456), 100_000_000 ether); vm.prank(address(456)); - zoraNFTBase.purchase{value: 0.1 ether * uint256(limit) + limitFee}( - limit - ); + zoraNFTBase.purchase{value: 0.1 ether * uint256(limit) + limitFee}(limit); assertEq(zoraNFTBase.saleDetails().totalMinted, limit); @@ -791,10 +971,9 @@ contract ERC721DropTest is Test { vm.deal(address(444), 1_000_000 ether); vm.prank(address(444)); vm.expectRevert(IERC721Drop.Purchase_TooManyForAddress.selector); - zoraNFTBase.purchase{ - value: (0.1 ether * (uint256(limit) + 1)) + - (fee * (uint256(limit) + 1)) - }(uint256(limit) + 1); + zoraNFTBase.purchase{value: (0.1 ether * (uint256(limit) + 1)) + (fee * (uint256(limit) + 1))}( + uint256(limit) + 1 + ); assertEq(zoraNFTBase.saleDetails().totalMinted, limit); } @@ -811,15 +990,12 @@ contract ERC721DropTest is Test { presaleMerkleRoot: bytes32(0) }); - (, , , , , uint64 presaleEndLookup, ) = zoraNFTBase.salesConfig(); + (,,,,, uint64 presaleEndLookup,) = zoraNFTBase.salesConfig(); assertEq(presaleEndLookup, 100); address SALES_MANAGER_ADDR = address(0x11002); vm.startPrank(DEFAULT_OWNER_ADDRESS); - zoraNFTBase.grantRole( - zoraNFTBase.SALES_MANAGER_ROLE(), - SALES_MANAGER_ADDR - ); + zoraNFTBase.grantRole(zoraNFTBase.SALES_MANAGER_ROLE(), SALES_MANAGER_ADDR); vm.stopPrank(); vm.prank(SALES_MANAGER_ADDR); zoraNFTBase.setSaleConfiguration({ @@ -832,22 +1008,12 @@ contract ERC721DropTest is Test { presaleMerkleRoot: bytes32(0) }); - ( - , - , - , - , - uint64 presaleStartLookup2, - uint64 presaleEndLookup2, - - ) = zoraNFTBase.salesConfig(); + (,,,, uint64 presaleStartLookup2, uint64 presaleEndLookup2,) = zoraNFTBase.salesConfig(); assertEq(presaleEndLookup2, 0); assertEq(presaleStartLookup2, 100); } - function test_GlobalLimit( - uint16 limit - ) public setupZoraNFTBase(uint64(limit)) { + function test_GlobalLimit(uint16 limit) public setupZoraNFTBase(uint64(limit)) { vm.assume(limit > 0); vm.startPrank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.adminMint(DEFAULT_OWNER_ADDRESS, limit); @@ -876,16 +1042,11 @@ contract ERC721DropTest is Test { vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.adminMint(address(0x1234), 2); vm.prank(DEFAULT_OWNER_ADDRESS); - vm.expectRevert( - IERC721Drop.Admin_UnableToFinalizeNotOpenEdition.selector - ); + vm.expectRevert(IERC721Drop.Admin_UnableToFinalizeNotOpenEdition.selector); zoraNFTBase.finalizeOpenEdition(); } - function test_ValidFinalizeOpenEdition() - public - setupZoraNFTBase(type(uint64).max) - { + function test_ValidFinalizeOpenEdition() public setupZoraNFTBase(type(uint64).max) { vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ publicSaleStart: 0, @@ -913,10 +1074,7 @@ contract ERC721DropTest is Test { address minter = address(0x32402); vm.startPrank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.adminMint(DEFAULT_OWNER_ADDRESS, 1); - require( - zoraNFTBase.balanceOf(DEFAULT_OWNER_ADDRESS) == 1, - "Wrong balance" - ); + require(zoraNFTBase.balanceOf(DEFAULT_OWNER_ADDRESS) == 1, "Wrong balance"); zoraNFTBase.grantRole(zoraNFTBase.MINTER_ROLE(), minter); vm.stopPrank(); vm.prank(minter); @@ -977,12 +1135,7 @@ contract ERC721DropTest is Test { toMint[2] = address(0x12); toMint[3] = address(0x13); bytes32 minterRole = zoraNFTBase.MINTER_ROLE(); - vm.expectRevert( - abi.encodeWithSignature( - "Access_MissingRoleOrAdmin(bytes32)", - minterRole - ) - ); + vm.expectRevert(abi.encodeWithSignature("Access_MissingRoleOrAdmin(bytes32)", minterRole)); zoraNFTBase.adminMintAirdrop(toMint); } @@ -997,9 +1150,7 @@ contract ERC721DropTest is Test { function test_AdminMintBatchFails() public setupZoraNFTBase(1000) { vm.startPrank(address(0x10)); bytes32 role = zoraNFTBase.MINTER_ROLE(); - vm.expectRevert( - abi.encodeWithSignature("Access_MissingRoleOrAdmin(bytes32)", role) - ); + vm.expectRevert(abi.encodeWithSignature("Access_MissingRoleOrAdmin(bytes32)", role)); zoraNFTBase.adminMint(address(0x10), 100); } @@ -1028,39 +1179,24 @@ contract ERC721DropTest is Test { vm.stopPrank(); vm.prank(address(1)); - vm.expectRevert( - IERC721AUpgradeable.TransferCallerNotOwnerNorApproved.selector - ); + vm.expectRevert(IERC721AUpgradeable.TransferCallerNotOwnerNorApproved.selector); zoraNFTBase.burn(1); } - function test_AdminMetadataRendererUpdateCall() - public - setupZoraNFTBase(10) - { + function test_AdminMetadataRendererUpdateCall() public setupZoraNFTBase(10) { vm.startPrank(DEFAULT_OWNER_ADDRESS); assertEq(dummyRenderer.someState(), ""); zoraNFTBase.callMetadataRenderer( - abi.encodeWithSelector( - DummyMetadataRenderer.updateSomeState.selector, - "new state", - address(zoraNFTBase) - ) + abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase)) ); assertEq(dummyRenderer.someState(), "new state"); } - function test_NonAdminMetadataRendererUpdateCall() - public - setupZoraNFTBase(10) - { + function test_NonAdminMetadataRendererUpdateCall() public setupZoraNFTBase(10) { vm.startPrank(address(0x99493)); assertEq(dummyRenderer.someState(), ""); - bytes memory targetCall = abi.encodeWithSelector( - DummyMetadataRenderer.updateSomeState.selector, - "new state", - address(zoraNFTBase) - ); + bytes memory targetCall = + abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase)); vm.expectRevert(IERC721Drop.Access_OnlyAdmin.selector); zoraNFTBase.callMetadataRenderer(targetCall); assertEq(dummyRenderer.someState(), ""); @@ -1072,13 +1208,19 @@ contract ERC721DropTest is Test { zoraNFTBase.updateRoyaltyMintSchedule(1); } - function test_SupplyRoyaltyPurchase(uint32 royaltyMintSchedule, uint32 editionSize, uint256 mintQuantity) public setupZoraNFTBase(editionSize) { - vm.assume(royaltyMintSchedule > 1 && royaltyMintSchedule <= editionSize && editionSize <= 100000 && mintQuantity > 0 && mintQuantity <= editionSize); + function test_SupplyRoyaltyPurchase(uint32 royaltyMintSchedule, uint32 editionSize, uint256 mintQuantity) + public + setupZoraNFTBase(editionSize) + { + vm.assume( + royaltyMintSchedule > 1 && royaltyMintSchedule <= editionSize && editionSize <= 100000 && mintQuantity > 0 + && mintQuantity <= editionSize + ); uint256 totalRoyaltyMintsForSale = editionSize / royaltyMintSchedule; vm.assume(mintQuantity <= editionSize - totalRoyaltyMintsForSale); vm.startPrank(DEFAULT_OWNER_ADDRESS); - + zoraNFTBase.updateRoyaltyMintSchedule(royaltyMintSchedule); zoraNFTBase.setSaleConfiguration({ @@ -1207,15 +1349,9 @@ contract ERC721DropTest is Test { function test_EIP165() public view { require(zoraNFTBase.supportsInterface(0x01ffc9a7), "supports 165"); require(zoraNFTBase.supportsInterface(0x80ac58cd), "supports 721"); - require( - zoraNFTBase.supportsInterface(0x5b5e139f), - "supports 721-metdata" - ); + require(zoraNFTBase.supportsInterface(0x5b5e139f), "supports 721-metdata"); require(zoraNFTBase.supportsInterface(0x2a55205a), "supports 2981"); require(zoraNFTBase.supportsInterface(0x49064906), "supports 4906"); - require( - !zoraNFTBase.supportsInterface(0x0000000), - "doesnt allow non-interface" - ); + require(!zoraNFTBase.supportsInterface(0x0000000), "doesnt allow non-interface"); } } diff --git a/test/ZoraNFTCreatorV1.t.sol b/test/ZoraNFTCreatorV1.t.sol index 7c2cc88..acff13e 100644 --- a/test/ZoraNFTCreatorV1.t.sol +++ b/test/ZoraNFTCreatorV1.t.sol @@ -2,6 +2,9 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; +import {IERC721AUpgradeable} from "erc721a-upgradeable/IERC721AUpgradeable.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; + import {IMetadataRenderer} from "../src/interfaces/IMetadataRenderer.sol"; import "../src/ZoraNFTCreatorV1.sol"; import "../src/ZoraNFTCreatorProxy.sol"; @@ -23,15 +26,20 @@ contract ZoraNFTCreatorV1Test is Test { ZoraNFTCreatorV1 public creator; EditionMetadataRenderer public editionMetadataRenderer; DropMetadataRenderer public dropMetadataRenderer; + ProtocolRewards internal protocolRewards; + address internal constant DEFAULT_CREATE_REFERRAL = address(0); function setUp() public { + protocolRewards = new ProtocolRewards(); + vm.prank(DEFAULT_ZORA_DAO_ADDRESS); dropImpl = new ERC721Drop( address(1234), FactoryUpgradeGate(address(0)), address(0), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ); editionMetadataRenderer = new EditionMetadataRenderer(); dropMetadataRenderer = new DropMetadataRenderer(); @@ -132,7 +140,8 @@ contract ZoraNFTCreatorV1Test is Test { presaleMerkleRoot: bytes32(0) }), mockRenderer, - "" + "", + DEFAULT_CREATE_REFERRAL ); ERC721Drop drop = ERC721Drop(payable(deployedDrop)); ERC721Drop.SaleDetails memory saleDetails = drop.saleDetails(); diff --git a/test/merkle/MerkleDrop.t.sol b/test/merkle/MerkleDrop.t.sol index e227053..447c86a 100644 --- a/test/merkle/MerkleDrop.t.sol +++ b/test/merkle/MerkleDrop.t.sol @@ -2,15 +2,17 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; + import {IERC721Drop} from "../../src/interfaces/IERC721Drop.sol"; import {ERC721Drop} from "../../src/ERC721Drop.sol"; import {DummyMetadataRenderer} from "../utils/DummyMetadataRenderer.sol"; import {FactoryUpgradeGate} from "../../src/FactoryUpgradeGate.sol"; import {ERC721DropProxy} from "../../src/ERC721DropProxy.sol"; - import {MerkleData} from "./MerkleData.sol"; contract ZoraNFTBaseTest is Test { + ProtocolRewards internal protocolRewards; ERC721Drop zoraNFTBase; DummyMetadataRenderer public dummyRenderer = new DummyMetadataRenderer(); MerkleData public merkleData; @@ -22,6 +24,7 @@ contract ZoraNFTBaseTest is Test { address public constant mediaContract = address(0x123456); address payable public constant mintFeeRecipient = payable(address(0x1234)); uint256 public constant mintFee = 0.000777 ether; + address internal constant DEFAULT_CREATE_REFERRAL = address(0); modifier setupZoraNFTBase() { bytes[] memory setupCalls = new bytes[](0); @@ -34,22 +37,25 @@ contract ZoraNFTBaseTest is Test { _royaltyBPS: 800, _setupCalls: setupCalls, _metadataRenderer: dummyRenderer, - _metadataRendererInit: "" + _metadataRendererInit: "", + _createReferral: DEFAULT_CREATE_REFERRAL }); _; } function setUp() public { - vm.prank(DEFAULT_ZORA_DAO_ADDRESS); + protocolRewards = new ProtocolRewards(); + vm.prank(DEFAULT_ZORA_DAO_ADDRESS); address impl = address( new ERC721Drop( address(1234), FactoryUpgradeGate(address(0)), address(0), mintFee, - mintFeeRecipient + mintFeeRecipient, + address(protocolRewards) ) ); address payable newDrop = payable( @@ -265,7 +271,8 @@ contract ZoraNFTBaseTest is Test { _royaltyBPS: 800, _setupCalls: setupCalls, _metadataRenderer: dummyRenderer, - _metadataRendererInit: "" + _metadataRendererInit: "", + _createReferral: DEFAULT_CREATE_REFERRAL }); vm.startPrank(DEFAULT_OWNER_ADDRESS); diff --git a/yarn.lock b/yarn.lock index 7ed0686..b926055 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,9 +29,9 @@ js-tokens "^4.0.0" "@babel/runtime@^7.20.1", "@babel/runtime@^7.5.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" - integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== dependencies: regenerator-runtime "^0.13.11" @@ -251,125 +251,125 @@ signale "^1.4.0" tslib "^1" -"@esbuild/android-arm64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz#4aa8d8afcffb4458736ca9b32baa97d7cb5861ea" - integrity sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw== +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== "@esbuild/android-arm@0.15.13": version "0.15.13" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.13.tgz#ce11237a13ee76d5eae3908e47ba4ddd380af86a" integrity sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw== -"@esbuild/android-arm@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.18.tgz#74a7e95af4ee212ebc9db9baa87c06a594f2a427" - integrity sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw== - -"@esbuild/android-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.18.tgz#1dcd13f201997c9fe0b204189d3a0da4eb4eb9b6" - integrity sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg== - -"@esbuild/darwin-arm64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz#444f3b961d4da7a89eb9bd35cfa4415141537c2a" - integrity sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ== - -"@esbuild/darwin-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz#a6da308d0ac8a498c54d62e0b2bfb7119b22d315" - integrity sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A== - -"@esbuild/freebsd-arm64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz#b83122bb468889399d0d63475d5aea8d6829c2c2" - integrity sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA== - -"@esbuild/freebsd-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz#af59e0e03fcf7f221b34d4c5ab14094862c9c864" - integrity sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew== - -"@esbuild/linux-arm64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz#8551d72ba540c5bce4bab274a81c14ed01eafdcf" - integrity sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ== - -"@esbuild/linux-arm@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz#e09e76e526df4f665d4d2720d28ff87d15cdf639" - integrity sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg== - -"@esbuild/linux-ia32@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz#47878860ce4fe73a36fd8627f5647bcbbef38ba4" - integrity sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ== +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== "@esbuild/linux-loong64@0.15.13": version "0.15.13" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz#64e8825bf0ce769dac94ee39d92ebe6272020dfc" integrity sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag== -"@esbuild/linux-loong64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz#3f8fbf5267556fc387d20b2e708ce115de5c967a" - integrity sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ== - -"@esbuild/linux-mips64el@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz#9d896d8f3c75f6c226cbeb840127462e37738226" - integrity sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA== - -"@esbuild/linux-ppc64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz#3d9deb60b2d32c9985bdc3e3be090d30b7472783" - integrity sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ== - -"@esbuild/linux-riscv64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz#8a943cf13fd24ff7ed58aefb940ef178f93386bc" - integrity sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA== - -"@esbuild/linux-s390x@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz#66cb01f4a06423e5496facabdce4f7cae7cb80e5" - integrity sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw== - -"@esbuild/linux-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz#23c26050c6c5d1359c7b774823adc32b3883b6c9" - integrity sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA== - -"@esbuild/netbsd-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz#789a203d3115a52633ff6504f8cbf757f15e703b" - integrity sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg== - -"@esbuild/openbsd-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz#d7b998a30878f8da40617a10af423f56f12a5e90" - integrity sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA== - -"@esbuild/sunos-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz#ecad0736aa7dae07901ba273db9ef3d3e93df31f" - integrity sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg== - -"@esbuild/win32-arm64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz#58dfc177da30acf956252d7c8ae9e54e424887c4" - integrity sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg== - -"@esbuild/win32-ia32@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz#340f6163172b5272b5ae60ec12c312485f69232b" - integrity sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw== - -"@esbuild/win32-x64@0.17.18": - version "0.17.18" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz#3a8e57153905308db357fd02f57c180ee3a0a1fa" - integrity sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg== +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== "@ethersproject/abi@^5.7.0": version "5.7.0" @@ -635,11 +635,16 @@ dependencies: "@noble/hashes" "1.3.0" -"@noble/hashes@1.3.0", "@noble/hashes@~1.3.0": +"@noble/hashes@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== +"@noble/hashes@~1.3.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -662,16 +667,28 @@ fastq "^1.6.0" "@oclif/command@^1", "@oclif/command@^1.8.15": - version "1.8.24" - resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.24.tgz#203ad9e2b2dc2336c0333f100978aada50d53007" - integrity sha512-FbSChfBO2QFeC5eEeXmi8+kZvBCDzYdpEKhOMaz0sfKMerwSlKxsqWQPGWCjTHaowIUMtnMD3VZ8yfX5qE7SAQ== + version "1.8.35" + resolved "https://registry.yarnpkg.com/@oclif/command/-/command-1.8.35.tgz#7023f48a6b058d33ccb578c28a1522fba192efd2" + integrity sha512-oILFTe3n6WjEbhXaSJd6FPsU4H97WxkC3Q0+Y63pfTXIZ424Fb9Hlg1CazscWcJqCrhuuUag6mItdgYo0kpinw== dependencies: "@oclif/config" "^1.18.2" "@oclif/errors" "^1.3.6" "@oclif/help" "^1.0.1" - "@oclif/parser" "^3.8.10" + "@oclif/parser" "^3.8.16" debug "^4.1.1" - semver "^7.5.0" + semver "^7.5.4" + +"@oclif/config@1.18.15": + version "1.18.15" + resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.15.tgz#3be95862dda32d759fc61bcadff1e7819915a112" + integrity sha512-eBTiFXGfXSzghc4Yjp3EutYU+6MrHX1kzk4j5i4CsR5AEor43ynXFrzpO6v7IwbR1KyUo+9SYE2D69Y+sHIMpg== + dependencies: + "@oclif/errors" "^1.3.6" + "@oclif/parser" "^3.8.15" + debug "^4.3.4" + globby "^11.1.0" + is-wsl "^2.1.1" + tslib "^2.5.0" "@oclif/config@1.18.2": version "1.18.2" @@ -685,29 +702,17 @@ is-wsl "^2.1.1" tslib "^2.0.0" -"@oclif/config@1.18.6": - version "1.18.6" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.6.tgz#37367026b3110a2f04875509b1920a8ee4489f21" - integrity sha512-OWhCpdu4QqggOPX1YPZ4XVmLLRX+lhGjXV6RNA7sogOwLqlEmSslnN/lhR5dkhcWZbKWBQH29YCrB3LDPRu/IA== - dependencies: - "@oclif/errors" "^1.3.6" - "@oclif/parser" "^3.8.9" - debug "^4.3.4" - globby "^11.1.0" - is-wsl "^2.1.1" - tslib "^2.3.1" - "@oclif/config@^1", "@oclif/config@^1.18.2": - version "1.18.8" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.8.tgz#efaccbd0381f90a98fa69c9131e14c5a91fc0659" - integrity sha512-FetS52+emaZQui0roFSdbBP8ddBkIezEoH2NcjLJRjqkMGdE9Z1V+jsISVqTYXk2KJ1gAI0CHDXFjJlNBYbJBg== + version "1.18.16" + resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.16.tgz#3235d260ab1eb8388ebb6255bca3dd956249d796" + integrity sha512-VskIxVcN22qJzxRUq+raalq6Q3HUde7sokB7/xk5TqRZGEKRVbFeqdQBxDWwQeudiJEgcNiMvIFbMQ43dY37FA== dependencies: "@oclif/errors" "^1.3.6" - "@oclif/parser" "^3.8.10" + "@oclif/parser" "^3.8.16" debug "^4.3.4" globby "^11.1.0" is-wsl "^2.1.1" - tslib "^2.5.0" + tslib "^2.6.1" "@oclif/errors@1.3.5": version "1.3.5" @@ -732,11 +737,11 @@ wrap-ansi "^7.0.0" "@oclif/help@^1.0.1": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@oclif/help/-/help-1.0.5.tgz#0a370d0340fcf167ec3cb7a4f3074ebb3db8a94a" - integrity sha512-77ZXqVXcd+bQ6EafN56KbL4PbNtZM/Lq4GQElekNav+CPIgPNKT3AtMTQrc0fWke6bb/BTLB+1Fu1gWgx643jQ== + version "1.0.14" + resolved "https://registry.yarnpkg.com/@oclif/help/-/help-1.0.14.tgz#da5f9fdf6f57b40b133f095cbb9c78c480975ca3" + integrity sha512-Hu2/Dyo91cgLNaqN3wkvkBGuZ7eqb0TQNVKrzGButZyaBpJzmwW4L6D4tAF390WDYZG7EubmLePlNYb+rNB4jw== dependencies: - "@oclif/config" "1.18.6" + "@oclif/config" "1.18.15" "@oclif/errors" "1.3.6" chalk "^4.1.2" indent-string "^4.0.0" @@ -751,15 +756,15 @@ resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== -"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.10", "@oclif/parser@^3.8.9": - version "3.8.10" - resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.10.tgz#7b1048566e1d3f45ed09ca92b2e30f09bd9647e1" - integrity sha512-J4l/NcnfbIU84+NNdy6bxq9yJt4joFWNvpk59hq+uaQPUNtjmNJDVGuRvf6GUOxHNgRsVK1JRmd/Ez+v7Z9GqQ== +"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.15", "@oclif/parser@^3.8.16": + version "3.8.16" + resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.16.tgz#bedfc55153075b8b2925657f8865035aa877515c" + integrity sha512-jeleXSh5izmBQ6vwyCJmbFPahPpd/ajxASi25FaYAWcvwVMzP/vKAKQXKWZun6T9K/gd6ywSsTpfAXiZAjBd6g== dependencies: "@oclif/errors" "^1.3.6" "@oclif/linewrap" "^1.0.0" chalk "^4.1.0" - tslib "^2.5.0" + tslib "^2.6.1" "@oclif/plugin-help@^3": version "3.3.1" @@ -817,16 +822,16 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== +"@types/node@*", "@types/node@^20.1.2": + version "20.4.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.6.tgz#b66b66c9bb5d49b199f03399e341c9d6036e9e88" + integrity sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA== + "@types/node@^12.7.1": version "12.20.55" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== -"@types/node@^20.1.2": - version "20.1.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.2.tgz#8fd63447e3f99aba6c3168fd2ec4580d5b97886f" - integrity sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g== - "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" @@ -837,23 +842,30 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== -"@wagmi/chains@0.2.16": - version "0.2.16" - resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-0.2.16.tgz#a726716e4619ec1c192b312e23f9c38407617aa0" - integrity sha512-rkWaI2PxCnbD8G07ZZff5QXftnSkYL0h5f4DkHCG3fGYYr/ZDvmCL4bMae7j7A9sAif1csPPBmbCzHp3R5ogCQ== +"@types/ws@^8.5.4": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== + dependencies: + "@types/node" "*" + +"@wagmi/chains@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-1.3.0.tgz#a17438d44abe98fdf1ec3a91df115c6bfaed39c0" + integrity sha512-7tyr1irTZQpA4/4HoIiJP3XYZuJIZuWiZ1V1j5WEG3cjm8TXIlMEzO0N+hT/cZKw4/UtF2EukvB8GkDWa2S77w== -"@wagmi/chains@0.2.22": - version "0.2.22" - resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-0.2.22.tgz#25e511e134a00742e4fbf5108613dadf876c5bd9" - integrity sha512-TdiOzJT6TO1JrztRNjTA5Quz+UmQlbvWFG8N41u9tta0boHA1JCAzGGvU6KuIcOmJfRJkKOUIt67wlbopCpVHg== +"@wagmi/chains@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@wagmi/chains/-/chains-1.6.0.tgz#eb992ad28dbaaab729b5bcab3e5b461e8a035656" + integrity sha512-5FRlVxse5P4ZaHG3GTvxwVANSmYJas1eQrTBHhjxVtqXoorm0aLmCHbhmN8Xo1yu09PaWKlleEvfE98yH4AgIw== "@wagmi/cli@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@wagmi/cli/-/cli-1.0.1.tgz#f705648c71c7b19e028d5a5a1a74c1c15496c9c8" - integrity sha512-SZwT7RglyVDipDTPL/dEKfrAJ3GdSKfdhaF6CFoseIgSiOLkj3xbakvAqdjYSkYnnpjrqLXc3WKZCnszQryctA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/@wagmi/cli/-/cli-1.3.0.tgz#e090e6167cdd36a37adbf0f6d03108e82c539c99" + integrity sha512-/YXmdp0XWgQEwRSVO8IjVB8KY5HK+6+eqJsZI3a+y3XMH4T/NxVBoT/JxTqV6HEivr3HOLgDcTzvQhNy3mZ0HA== dependencies: - "@wagmi/chains" "0.2.22" - abitype "0.8.1" + "@wagmi/chains" "1.3.0" + abitype "0.8.7" abort-controller "^3.0.0" bundle-require "^3.1.2" cac "^6.7.12" @@ -873,18 +885,23 @@ pathe "^1.0.0" picocolors "^1.0.0" prettier "^2.8.1" - viem "~0.3.18" + viem "^1.0.0" zod "^3.21.4" -abitype@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.8.1.tgz#9575a21da88bb4094a262a653e526a088ab06041" - integrity sha512-n8Di6AWb3i7HnEkBvecU6pG0a5nj5YwMvdAIwPLsQK95ulRy/XS113s/RXvSfTX1iOQJYFrEO3/q4SMWu7OwTA== +"@zoralabs/protocol-rewards@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@zoralabs/protocol-rewards/-/protocol-rewards-1.0.2.tgz#7727b3b6bbba57c26aae088884ff168542f745ed" + integrity sha512-r+4EGY9HKHXTwY89VFciI4wvjgh9ZJPuPGKBoAY6TwXXk8bN1h4CathbUmzkjC8hCw4knItEKTgebbHNpslAcg== -abitype@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.8.2.tgz#cacd330d07488a4020d84f54fc361361234b9c83" - integrity sha512-B1ViNMGpfx/qjVQi0RTc2HEFHuR9uoCoTEkwELT5Y7pBPtBbctYijz9BK6+Kd0hQ3S70FhYTO2dWWk0QNUEXMA== +abitype@0.8.7: + version "0.8.7" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.8.7.tgz#e4b3f051febd08111f486c0cc6a98fa72d033622" + integrity sha512-wQ7hV8Yg/yKmGyFpqrNZufCxbszDe5es4AZGYPBitocfSqXtjrTG9JMWFcc4N30ukl2ve48aBTwt7NJxVQdU3w== + +abitype@0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.3.tgz#294d25288ee683d72baf4e1fed757034e3c8c277" + integrity sha512-dz4qCQLurx97FQhnb/EIYTk/ldQ+oafEDUqC0VVIeQS1Q48/YWt/9YNfMmp9SLFqN41ktxny3c8aYxHjmFIB/w== abort-controller@^3.0.0: version "3.0.0" @@ -970,6 +987,18 @@ array.prototype.flat@^1.2.3: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1151,9 +1180,9 @@ chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: supports-color "^7.1.0" chalk@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== change-case@^4.1.2: version "4.1.2" @@ -1419,9 +1448,9 @@ dotenv@^10.0.0: integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== dotenv@^9.0.0: version "9.0.2" @@ -1468,11 +1497,12 @@ emoji-regex@^9.2.2: integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== enquirer@^2.3.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" + strip-ansi "^6.0.1" error-ex@^1.3.1: version "1.3.2" @@ -1482,17 +1512,18 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" @@ -1512,14 +1543,18 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.10" es-main@^1.0.2: version "1.2.0" @@ -1680,32 +1715,32 @@ esbuild@0.15.13: esbuild-windows-arm64 "0.15.13" esbuild@^0.17.6: - version "0.17.18" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.18.tgz#f4f8eb6d77384d68cd71c53eb6601c7efe05e746" - integrity sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w== + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== optionalDependencies: - "@esbuild/android-arm" "0.17.18" - "@esbuild/android-arm64" "0.17.18" - "@esbuild/android-x64" "0.17.18" - "@esbuild/darwin-arm64" "0.17.18" - "@esbuild/darwin-x64" "0.17.18" - "@esbuild/freebsd-arm64" "0.17.18" - "@esbuild/freebsd-x64" "0.17.18" - "@esbuild/linux-arm" "0.17.18" - "@esbuild/linux-arm64" "0.17.18" - "@esbuild/linux-ia32" "0.17.18" - "@esbuild/linux-loong64" "0.17.18" - "@esbuild/linux-mips64el" "0.17.18" - "@esbuild/linux-ppc64" "0.17.18" - "@esbuild/linux-riscv64" "0.17.18" - "@esbuild/linux-s390x" "0.17.18" - "@esbuild/linux-x64" "0.17.18" - "@esbuild/netbsd-x64" "0.17.18" - "@esbuild/openbsd-x64" "0.17.18" - "@esbuild/sunos-x64" "0.17.18" - "@esbuild/win32-arm64" "0.17.18" - "@esbuild/win32-ia32" "0.17.18" - "@esbuild/win32-x64" "0.17.18" + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" escalade@^3.1.1: version "3.1.1" @@ -1776,10 +1811,10 @@ external-editor@^3.1.0: iconv-lite "^0.4.24" tmp "^0.0.33" -fast-glob@^3.2.11, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1809,7 +1844,7 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -1955,7 +1990,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== @@ -2009,15 +2044,15 @@ glob@7.1.6: path-is-absolute "^1.0.0" glob@^10.2.7: - version "10.2.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" - integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== dependencies: foreground-child "^3.1.0" jackspeak "^2.0.3" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2" - path-scurry "^1.7.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^7.0.0: version "7.2.3" @@ -2051,13 +2086,13 @@ globby@^11.0.0, globby@^11.0.1, globby@^11.0.3, globby@^11.1.0: slash "^3.0.0" globby@^13.1.3: - version "13.1.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" - integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + version "13.2.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" + integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== dependencies: dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" + fast-glob "^3.3.0" + ignore "^5.2.4" merge2 "^1.4.1" slash "^4.0.0" @@ -2186,7 +2221,7 @@ ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -2272,9 +2307,9 @@ is-ci@^3.0.1: ci-info "^3.2.0" is-core-module@^2.11.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" @@ -2381,15 +2416,11 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: has-symbols "^1.0.2" is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.11" is-unicode-supported@^1.1.0: version "1.3.0" @@ -2415,6 +2446,11 @@ is-wsl@^2.1.1: dependencies: is-docker "^2.0.0" +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2426,23 +2462,23 @@ isomorphic-ws@5.0.0: integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== jackspeak@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.0.tgz#497cbaedc902ec3f31d5d61be804d2364ff9ddad" - integrity sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.2.tgz#707c62733924b8dc2a0a629dc6248577788b5385" + integrity sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" joycon@^3.0.1: version "3.1.1" @@ -2640,10 +2676,10 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1" - integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== map-obj@^1.0.0: version "1.0.1" @@ -2715,7 +2751,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -2730,9 +2766,9 @@ minimatch@^5.0.1: brace-expansion "^2.0.1" minimatch@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" - integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -2745,15 +2781,10 @@ minimist-options@^4.0.2: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" - integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== mixme@^0.5.1: version "0.5.9" @@ -2793,9 +2824,9 @@ node-domexception@^1.0.0: integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== node-fetch@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" - integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + version "3.3.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" + integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== dependencies: data-uri-to-buffer "^4.0.0" fetch-blob "^3.1.4" @@ -2882,9 +2913,9 @@ onetime@^6.0.0: mimic-fn "^4.0.0" ora@^6.1.2: - version "6.3.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-6.3.0.tgz#a314600999f514a989a0904f5c17c8b7c1f7c878" - integrity sha512-1/D8uRFY0ay2kgBpmAwmSA404w4OoPVhHMqRqtjvrcK/dnzcEZxMJ+V4DUbyICu8IIVRclHcOf5wlD1tMY4GUQ== + version "6.3.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-6.3.1.tgz#a4e9e5c2cf5ee73c259e8b410273e706a2ad3ed6" + integrity sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ== dependencies: chalk "^5.0.0" cli-cursor "^4.0.0" @@ -3061,13 +3092,13 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.8.0.tgz#809e09690c63817c76d0183f19a5b21b530ff7d2" - integrity sha512-IjTrKseM404/UAWA8bBbL3Qp6O2wXkanuIE3seCxBH7ctRuvH1QRawy1N3nVDHGkdeZsjOsSe/8AQBL/VQCy2g== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: - lru-cache "^9.1.1" - minipass "^5.0.0" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-type@^4.0.0: version "4.0.0" @@ -3075,9 +3106,9 @@ path-type@^4.0.0: integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pathe@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.0.tgz#e2e13f6c62b31a3289af4ba19886c230f295ec03" - integrity sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w== + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== picocolors@^1.0.0: version "1.0.0" @@ -3100,9 +3131,9 @@ pify@^4.0.1: integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pirates@^4.0.1: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-conf@^2.1.0: version "2.1.0" @@ -3235,7 +3266,7 @@ regenerator-runtime@^0.13.11: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regexp.prototype.flags@^1.4.3: +regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== @@ -3282,9 +3313,9 @@ reusify@^1.0.4: integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rollup@^3.2.5: - version "3.21.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.6.tgz#f5649ccdf8fcc7729254faa457cbea9547eb86db" - integrity sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg== + version "3.27.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.27.0.tgz#15bd07e2e1cbfa9255bf6a3f04a432621c2f3550" + integrity sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg== optionalDependencies: fsevents "~2.3.2" @@ -3295,6 +3326,16 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -3315,21 +3356,14 @@ safe-regex-test@^1.0.0: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== "semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== +semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -3400,9 +3434,9 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== signal-exit@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.1.tgz#96a61033896120ec9335d96851d902cc98f0ba2a" - integrity sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw== + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== signale@^1.4.0: version "1.4.0" @@ -3568,9 +3602,9 @@ string_decoder@^1.1.1: ansi-regex "^5.0.1" strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" @@ -3597,9 +3631,9 @@ strip-indent@^3.0.0: min-indent "^1.0.0" sucrase@^3.20.3: - version "3.32.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" - integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== dependencies: "@jridgewell/gen-mapping" "^0.3.2" commander "^4.0.0" @@ -3688,10 +3722,10 @@ tslib@^1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.3.1, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.5.0, tslib@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== tsup@^6.7.0: version "6.7.0" @@ -3741,6 +3775,36 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -3751,9 +3815,9 @@ typed-array-length@^1.0.4: is-typed-array "^1.1.9" typescript@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== unbox-primitive@^1.0.2: version "1.0.2" @@ -3802,18 +3866,19 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -viem@~0.3.18: - version "0.3.19" - resolved "https://registry.yarnpkg.com/viem/-/viem-0.3.19.tgz#71b88e9de66ce070f3096709d3558de46380b692" - integrity sha512-7OlSgiB7e+OFz9OqTOZ/Mpx8GAAVKCxsaPDJRuR8QtixlruUHPfHBHOemkX+O/Drn6B7l04iCUZjCvSB8OtVKg== +viem@^1.0.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/viem/-/viem-1.5.2.tgz#b8b9b464c4fb211c1daec6253b3e2559b69607b7" + integrity sha512-hPs4TJ9ONZw44K8lh24I5+Qntu62DEP85yhPsGqSSyr2d9yROY/9AisLLTlrlsudhg+A+BnLQGAuqvj/X+i8Ow== dependencies: "@adraffy/ens-normalize" "1.9.0" "@noble/curves" "1.0.0" "@noble/hashes" "1.3.0" "@scure/bip32" "1.3.0" "@scure/bip39" "1.2.0" - "@wagmi/chains" "0.2.16" - abitype "0.8.2" + "@types/ws" "^8.5.4" + "@wagmi/chains" "1.6.0" + abitype "0.9.3" isomorphic-ws "5.0.0" ws "8.12.0" @@ -3867,17 +3932,16 @@ which-pm@2.0.0: load-yaml-file "^0.2.0" path-exists "^4.0.0" -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.10, which-typed-array@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" which@^1.2.9: version "1.3.1" From 17160a864226055da14ae564d0b15aef5c4f4d87 Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Fri, 8 Sep 2023 16:44:56 -0700 Subject: [PATCH 07/10] Add version to addresses files (#149) * add version to addresses files * fix yarn lock * fix update * test fork remove pgn * adding version to forge scripts --- .github/workflows/test_fork.yml | 2 +- addresses/1.json | 1 + addresses/10.json | 1 + addresses/11155111.json | 1 + addresses/420.json | 1 + addresses/424.json | 1 + addresses/5.json | 1 + addresses/58008.json | 1 + addresses/7777777.json | 1 + addresses/8453.json | 1 + addresses/84531.json | 1 + addresses/999.json | 1 + foundry.toml | 7 +- script/Deploy.s.sol | 3 + script/UpgradeERC721DropFactory.s.sol | 3 +- script/ZoraDropsDeployBase.sol | 6 +- src/DeploymentConfig.sol | 3 + src/ERC721Drop.sol | 6 +- test/ERC721Drop.t.sol | 4 +- test/ZoraNFTCreatorV1.t.sol | 2 +- test/merkle/MerkleDrop.t.sol | 147 ++++------------------ yarn.lock | 175 ++++++++++++-------------- 22 files changed, 141 insertions(+), 228 deletions(-) diff --git a/.github/workflows/test_fork.yml b/.github/workflows/test_fork.yml index 6ddfd3e..6aae877 100644 --- a/.github/workflows/test_fork.yml +++ b/.github/workflows/test_fork.yml @@ -35,6 +35,6 @@ jobs: run: | forge test -vvv --match-test fork env: - FORK_TEST_CHAINS: mainnet,goerli,optimism,optimism_goerli,zora,zora_goerli,base_goerli,base,pgn_sepolia,pgn + FORK_TEST_CHAINS: mainnet,goerli,optimism,optimism_goerli,zora,zora_goerli,base_goerli,base # ,pgn_sepolia,pgn ALCHEMY_KEY: ${{ secrets.ALCHEMY_KEY }} id: test diff --git a/addresses/1.json b/addresses/1.json index 45cb0ad..de21c12 100644 --- a/addresses/1.json +++ b/addresses/1.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x5914d9a241008b9f02f22811bf3a77e02b84d226", "EDITION_METADATA_RENDERER": "0x192ce8267cbab9c3c477d61e85d7f0c5fe3b46af", "ERC721DROP_IMPL": "0x8237F421357F87a23ed0CFf3a5586172F210A21B", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x8Da5aC3A39D3B8BCaA1FC15A01506cf4F5e79830", "ZORA_NFT_CREATOR_PROXY": "0xF74B146ce44CC162b601deC3BE331784DB111DC1", "ZORA_NFT_CREATOR_V1_IMPL": "0x932A29Dbfc1B8c3BdfC763eF53F113486A5b5E7D" diff --git a/addresses/10.json b/addresses/10.json index 526d419..dfbc475 100644 --- a/addresses/10.json +++ b/addresses/10.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x96CcF205A366E15E261d77B14586389f80a029e9", "EDITION_METADATA_RENDERER": "0xa2a7D8bcE0bf58D177137ECB94f3Fa6aA06aA7A1", "ERC721DROP_IMPL": "0x3E8524770adD176bE381a0529E09f1c6c3502A5a", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x192D663C3D6813a24a24582A76B8d872c4F6F7f9", "ZORA_NFT_CREATOR_PROXY": "0x7d1a46c6e614A0091c39E102F2798C27c1fA8892", "ZORA_NFT_CREATOR_V1_IMPL": "0x805E0a08dE70f85C01F7848370d5e3fc08aAd0ea", diff --git a/addresses/11155111.json b/addresses/11155111.json index 2d64937..e423d35 100644 --- a/addresses/11155111.json +++ b/addresses/11155111.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x0Cf8733DEd6d9E0905A8cCc8DC767F381A76970a", "EDITION_METADATA_RENDERER": "0xC5c958a65656A84b74100D1d420a1819fEA18d41", "ERC721DROP_IMPL": "0xF706f5A8030C1e7D344D2Ef32Dff6B8568B3d07B", + "ERC721DROP_IMPL_VERSION": 11, "FACTORY_UPGRADE_GATE": "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3", "ZORA_NFT_CREATOR_PROXY": "0x87cfd516c5ea86e50b950678CA970a8a28de27ac", "ZORA_NFT_CREATOR_V1_IMPL": "0x96315ee3C58d16A40DA8Ee05008bA1F6654ea358" diff --git a/addresses/420.json b/addresses/420.json index fac3e4d..832636a 100644 --- a/addresses/420.json +++ b/addresses/420.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0xCe6B190956D73dA045bA348743E4C1cb6652f37f", "EDITION_METADATA_RENDERER": "0x169007EF8fF4d2a225f361654e4B8280910fD8FC", "ERC721DROP_IMPL": "0x61Cb091f8EC70029E393D31BA8F6D533c1308408", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x9B414A3F7872bdd2E6513689214BD2Debbe48340", "ZORA_NFT_CREATOR_PROXY": "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3", "ZORA_NFT_CREATOR_V1_IMPL": "0xbe83E15eED1FD666C241960f50549bE9D639743c", diff --git a/addresses/424.json b/addresses/424.json index 700b843..3ebf820 100644 --- a/addresses/424.json +++ b/addresses/424.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0xd77783B9df27BC9ABd438d1ddE67e3afB64618e0", "EDITION_METADATA_RENDERER": "0xC647382DFbb02ddf39dde7fDEbb5D844a832BE33", "ERC721DROP_IMPL": "0x0ef82DaB14798E63F1B99479Ba689e3f6A6fEb6C", + "ERC721DROP_IMPL_VERSION": 13, "FACTORY_UPGRADE_GATE": "0x973577d5B73a9b2508296F81260415151d0a955E", "ZORA_NFT_CREATOR_PROXY": "0x48d8db63724444C6270749fEe80bBDB6CF33677f", "ZORA_NFT_CREATOR_V1_IMPL": "0x97eb05B8db496B12244BCcf17CF377d00a99b67a", diff --git a/addresses/5.json b/addresses/5.json index 5f9b3f6..993aaa5 100644 --- a/addresses/5.json +++ b/addresses/5.json @@ -4,6 +4,7 @@ "EDITION_METADATA_RENDERER": "0x2f5C21EF9DdFf9A1FE76a1c55dd5112fcf2EfD39", "DROP_METADATA_RENDERER": "0x5956Fd16c4d8c4b4711F2551971aBB7c2F4aF677", "ERC721DROP_IMPL": "0xe4c17055048aEe01D0d122804816fEe5E6ac4A67", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x942C03C7afE5c8118BDB728Aa06d1b894B1cD9A8", "ZORA_NFT_CREATOR_PROXY": "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519", "ZORA_NFT_CREATOR_V1_IMPL": "0x0209aAEC870BE5C1cC243eE18eF6e80d545e9F32" diff --git a/addresses/58008.json b/addresses/58008.json index 8e88817..f4b52c6 100644 --- a/addresses/58008.json +++ b/addresses/58008.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x973577d5B73a9b2508296F81260415151d0a955E", "EDITION_METADATA_RENDERER": "0x0ef82DaB14798E63F1B99479Ba689e3f6A6fEb6C", "ERC721DROP_IMPL": "0x48d8db63724444C6270749fEe80bBDB6CF33677f", + "ERC721DROP_IMPL_VERSION": 13, "FACTORY_UPGRADE_GATE": "0x97eb05B8db496B12244BCcf17CF377d00a99b67a", "ZORA_NFT_CREATOR_PROXY": "0x418B87c2C9579d27FC3D66605545AB9889737E60", "ZORA_NFT_CREATOR_V1_IMPL": "0x39C51a7957651ea176733F19125BD9c253894D6F", diff --git a/addresses/7777777.json b/addresses/7777777.json index add45f1..94dd725 100644 --- a/addresses/7777777.json +++ b/addresses/7777777.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x4A0ad3Ef9bE8095590D854bC8481C9E50922a3c0", "EDITION_METADATA_RENDERER": "0xCA7bF48453B72e4E175267127B4Ed7EB12F83b93", "ERC721DROP_IMPL": "0x53a85FbD2955EF713AA489Ae0C48523E727a0c07", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x446A4135FB31007064107EFfDC15B8843B72B6F6", "ZORA_NFT_CREATOR_PROXY": "0xA2c2A96A232113Dd4993E8b048EEbc3371AE8d85", "ZORA_NFT_CREATOR_V1_IMPL": "0xfFFD7409031B1aeb731271C6C2D59771523Ff8a8", diff --git a/addresses/8453.json b/addresses/8453.json index ca7945c..096beb2 100644 --- a/addresses/8453.json +++ b/addresses/8453.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0xF77330C8b1c41f2e44470763Cf9E3ACa78Db4381", "EDITION_METADATA_RENDERER": "0x2008C05685F9fA15BBD75d80e9A44ab0c7230577", "ERC721DROP_IMPL": "0x8Ca5e648C5dFEfcdDa06d627F4b490B719ccFD98", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x532142aE8e53a5F92B9dE1a43F1FFD6eF789e65e", "ZORA_NFT_CREATOR_PROXY": "0x58C3ccB2dcb9384E5AB9111CD1a5DEA916B0f33c", "ZORA_NFT_CREATOR_V1_IMPL": "0x76CC78EF3aafD52e716a8e37F3dBbE0C42c51d54", diff --git a/addresses/84531.json b/addresses/84531.json index b634a46..bbeda85 100644 --- a/addresses/84531.json +++ b/addresses/84531.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0x0Cf8733DEd6d9E0905A8cCc8DC767F381A76970a", "EDITION_METADATA_RENDERER": "0xC5c958a65656A84b74100D1d420a1819fEA18d41", "ERC721DROP_IMPL": "0x39Bcc1e15b8ec15684F17fEf298151F4A544B591", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x3C1ebcF36Ca9DD9371c9aA99c274e4988906c6E3", "ZORA_NFT_CREATOR_PROXY": "0x87cfd516c5ea86e50b950678CA970a8a28de27ac", "ZORA_NFT_CREATOR_V1_IMPL": "0x489f8fFbd5f5eA8875c2EbC5CA9ED1214BD77F42" diff --git a/addresses/999.json b/addresses/999.json index 395e58e..77588d7 100644 --- a/addresses/999.json +++ b/addresses/999.json @@ -2,6 +2,7 @@ "DROP_METADATA_RENDERER": "0xb9583D05Ba9ba8f7F14CCEe3Da10D2bc0A72f519", "EDITION_METADATA_RENDERER": "0x481c56e15A9B2987Bd6041043e1d807697505d23", "ERC721DROP_IMPL": "0x293997C6a1f2A1cA3aB971f548c4D95585E46282", + "ERC721DROP_IMPL_VERSION": 14, "FACTORY_UPGRADE_GATE": "0x2068BA7Be6e22b97d21f5eb6e152A36d2Dc27da2", "ZORA_NFT_CREATOR_PROXY": "0xeB29A4e5b84fef428c072debA2444e93c080CE87", "ZORA_NFT_CREATOR_V1_IMPL": "0xe4c17055048aEe01D0d122804816fEe5E6ac4A67" diff --git a/foundry.toml b/foundry.toml index 5a0b463..b4317a3 100644 --- a/foundry.toml +++ b/foundry.toml @@ -22,11 +22,8 @@ pgn_sepolia = { key = "", chain = 7777777, url = "https://explorer.sepolia.publi mainnet = "https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}" goerli = "https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}" -# for optimism, since we are just using this for deployment/fork testing, -# we can use these since they're lower volume. - -optimism = "https://mainnet.optimism.io" -optimism_goerli = "https://goerli.optimism.io" +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" diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 99ae2fa..f6100fd 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -63,12 +63,15 @@ contract Deploy is ZoraDropsDeployBase { // vm.stopBroadcast(); + uint256 dropImplementationVersion = dropImplementation.contractVersion(); + return getDeploymentJSON( DropDeployment({ dropMetadata: address(dropMetadata), editionMetadata: address(editionMetadata), dropImplementation: address(dropImplementation), + dropImplementationVersion: dropImplementationVersion, factoryUpgradeGate: address(factoryUpgradeGate), factory: address(factory), factoryImpl: address(factoryImpl) diff --git a/script/UpgradeERC721DropFactory.s.sol b/script/UpgradeERC721DropFactory.s.sol index 591f43c..ae8c36e 100644 --- a/script/UpgradeERC721DropFactory.s.sol +++ b/script/UpgradeERC721DropFactory.s.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.13; import "forge-std/console2.sol"; import {ZoraDropsDeployBase} from "./ZoraDropsDeployBase.sol"; -import {ChainConfig, DropDeployment} from '../src/DeploymentConfig.sol'; +import {ChainConfig, DropDeployment} from "../src/DeploymentConfig.sol"; import {ERC721Drop} from "../src/ERC721Drop.sol"; import {ERC721DropProxy} from "../src/ERC721DropProxy.sol"; @@ -64,6 +64,7 @@ contract UpgradeERC721DropFactory is ZoraDropsDeployBase { }); deployment.dropImplementation = address(dropImplementation); + deployment.dropImplementationVersion = dropImplementation.contractVersion(); console2.log("Drop IMPL: "); console2.log(address(dropImplementation)); diff --git a/script/ZoraDropsDeployBase.sol b/script/ZoraDropsDeployBase.sol index 1b4e9ff..4d9e537 100644 --- a/script/ZoraDropsDeployBase.sol +++ b/script/ZoraDropsDeployBase.sol @@ -2,14 +2,13 @@ pragma solidity ^0.8.13; import "forge-std/Script.sol"; -import {ScriptDeploymentConfig, DropDeployment} from '../src/DeploymentConfig.sol'; +import {ScriptDeploymentConfig, DropDeployment} from "../src/DeploymentConfig.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {ZoraNFTCreatorV1} from "../src/ZoraNFTCreatorV1.sol"; import {IERC721Drop} from "../src/interfaces/IERC721Drop.sol"; -/// @notice Deployment drops for base where +/// @notice Deployment drops for base where abstract contract ZoraDropsDeployBase is ScriptDeploymentConfig { - /// @notice Get deployment configuration struct as JSON /// @param deployment deploymet struct /// @return deploymentJson string JSON of the deployment info @@ -19,6 +18,7 @@ abstract contract ZoraDropsDeployBase is ScriptDeploymentConfig { vm.serializeAddress(deploymentJsonKey, DROP_METADATA_RENDERER, deployment.dropMetadata); vm.serializeAddress(deploymentJsonKey, EDITION_METADATA_RENDERER, deployment.editionMetadata); vm.serializeAddress(deploymentJsonKey, ERC721DROP_IMPL, deployment.dropImplementation); + vm.serializeUint(deploymentJsonKey, ERC721DROP_IMPL_VERSION, deployment.dropImplementationVersion); vm.serializeAddress(deploymentJsonKey, FACTORY_UPGRADE_GATE, deployment.factoryUpgradeGate); vm.serializeAddress(deploymentJsonKey, ZORA_NFT_CREATOR_PROXY, deployment.factory); // Get the JSON key as a seralized string diff --git a/src/DeploymentConfig.sol b/src/DeploymentConfig.sol index d68d7cf..47246eb 100644 --- a/src/DeploymentConfig.sol +++ b/src/DeploymentConfig.sol @@ -34,6 +34,8 @@ struct DropDeployment { address editionMetadata; /// @notice Implementation contract for the drop contract address dropImplementation; + /// @notice Implementation version for the drop contract + uint256 dropImplementationVersion; /// @notice Factory upgrade gate immutable registry for allowing upgrades address factoryUpgradeGate; /// @notice Factory proxy contract that creates zora drops style NFT contracts @@ -71,6 +73,7 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script string constant DROP_METADATA_RENDERER = "DROP_METADATA_RENDERER"; string constant EDITION_METADATA_RENDERER = "EDITION_METADATA_RENDERER"; string constant ERC721DROP_IMPL = "ERC721DROP_IMPL"; + string constant ERC721DROP_IMPL_VERSION = "ERC721DROP_IMPL_VERSION"; string constant FACTORY_UPGRADE_GATE = "FACTORY_UPGRADE_GATE"; string constant ZORA_NFT_CREATOR_PROXY = "ZORA_NFT_CREATOR_PROXY"; string constant ZORA_NFT_CREATOR_V1_IMPL = "ZORA_NFT_CREATOR_V1_IMPL"; diff --git a/src/ERC721Drop.sol b/src/ERC721Drop.sol index eafb28d..5ab6d04 100644 --- a/src/ERC721Drop.sol +++ b/src/ERC721Drop.sol @@ -24,9 +24,9 @@ import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/se import {MerkleProofUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import {MathUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; -import {IProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/interfaces/IProtocolRewards.sol"; -import {ERC721Rewards} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC721/ERC721Rewards.sol"; -import {ERC721RewardsStorageV1} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC721/ERC721RewardsStorageV1.sol"; +import {IProtocolRewards} from "@zoralabs/protocol-rewards/src/interfaces/IProtocolRewards.sol"; +import {ERC721Rewards} from "@zoralabs/protocol-rewards/src/abstract/ERC721/ERC721Rewards.sol"; +import {ERC721RewardsStorageV1} from "@zoralabs/protocol-rewards/src/abstract/ERC721/ERC721RewardsStorageV1.sol"; import {IMetadataRenderer} from "./interfaces/IMetadataRenderer.sol"; import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"; diff --git a/test/ERC721Drop.t.sol b/test/ERC721Drop.t.sol index a399882..62817ae 100644 --- a/test/ERC721Drop.t.sol +++ b/test/ERC721Drop.t.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; import {IERC721AUpgradeable} from "erc721a-upgradeable/IERC721AUpgradeable.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; -import {RewardsSettings} from "@zoralabs/protocol-rewards/dist/contracts/abstract/RewardSplits.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/src/ProtocolRewards.sol"; +import {RewardsSettings} from "@zoralabs/protocol-rewards/src/abstract/RewardSplits.sol"; import {ERC721Drop} from "../src/ERC721Drop.sol"; import {DummyMetadataRenderer} from "./utils/DummyMetadataRenderer.sol"; diff --git a/test/ZoraNFTCreatorV1.t.sol b/test/ZoraNFTCreatorV1.t.sol index acff13e..281be1d 100644 --- a/test/ZoraNFTCreatorV1.t.sol +++ b/test/ZoraNFTCreatorV1.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; import {IERC721AUpgradeable} from "erc721a-upgradeable/IERC721AUpgradeable.sol"; -import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/src/ProtocolRewards.sol"; import {IMetadataRenderer} from "../src/interfaces/IMetadataRenderer.sol"; import "../src/ZoraNFTCreatorV1.sol"; diff --git a/test/merkle/MerkleDrop.t.sol b/test/merkle/MerkleDrop.t.sol index 447c86a..9cd2bde 100644 --- a/test/merkle/MerkleDrop.t.sol +++ b/test/merkle/MerkleDrop.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.10; import {Test} from "forge-std/Test.sol"; -import {ProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/ProtocolRewards.sol"; +import {ProtocolRewards} from "@zoralabs/protocol-rewards/src/ProtocolRewards.sol"; import {IERC721Drop} from "../../src/interfaces/IERC721Drop.sol"; import {ERC721Drop} from "../../src/ERC721Drop.sol"; @@ -17,10 +17,8 @@ contract ZoraNFTBaseTest is Test { DummyMetadataRenderer public dummyRenderer = new DummyMetadataRenderer(); MerkleData public merkleData; address public constant DEFAULT_OWNER_ADDRESS = address(0x23499); - address payable public constant DEFAULT_FUNDS_RECIPIENT_ADDRESS = - payable(address(0x21303)); - address payable public constant DEFAULT_ZORA_DAO_ADDRESS = - payable(address(0x999)); + address payable public constant DEFAULT_FUNDS_RECIPIENT_ADDRESS = payable(address(0x21303)); + address payable public constant DEFAULT_ZORA_DAO_ADDRESS = payable(address(0x999)); address public constant mediaContract = address(0x123456); address payable public constant mintFeeRecipient = payable(address(0x1234)); uint256 public constant mintFee = 0.000777 ether; @@ -48,19 +46,8 @@ contract ZoraNFTBaseTest is Test { protocolRewards = new ProtocolRewards(); vm.prank(DEFAULT_ZORA_DAO_ADDRESS); - address impl = address( - new ERC721Drop( - address(1234), - FactoryUpgradeGate(address(0)), - address(0), - mintFee, - mintFeeRecipient, - address(protocolRewards) - ) - ); - address payable newDrop = payable( - address(new ERC721DropProxy(impl, "")) - ); + address impl = address(new ERC721Drop(address(1234), FactoryUpgradeGate(address(0)), address(0), mintFee, mintFeeRecipient, address(protocolRewards))); + address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); merkleData = new MerkleData(); } @@ -74,9 +61,7 @@ contract ZoraNFTBaseTest is Test { presaleEnd: type(uint64).max, publicSalePrice: 0 ether, maxSalePurchasePerAddress: 0, - presaleMerkleRoot: merkleData - .getTestSetByName("test-3-addresses") - .root + presaleMerkleRoot: merkleData.getTestSetByName("test-3-addresses").root }); vm.stopPrank(); @@ -87,35 +72,19 @@ contract ZoraNFTBaseTest is Test { vm.deal(address(item.user), 1 ether); vm.startPrank(address(item.user)); - zoraNFTBase.purchasePresale{value: item.mintPrice + fee}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: item.mintPrice + fee}(1, item.maxMint, item.mintPrice, item.proof); assertEq(zoraNFTBase.saleDetails().maxSupply, 10); assertEq(zoraNFTBase.saleDetails().totalMinted, 1); - require( - zoraNFTBase.ownerOf(1) == address(item.user), - "owner is wrong for new minted token" - ); + require(zoraNFTBase.ownerOf(1) == address(item.user), "owner is wrong for new minted token"); vm.stopPrank(); item = merkleData.getTestSetByName("test-3-addresses").entries[1]; vm.deal(address(item.user), 1 ether); vm.startPrank(address(item.user)); - zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 2}( - 2, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 2}(2, item.maxMint, item.mintPrice, item.proof); assertEq(zoraNFTBase.saleDetails().maxSupply, 10); assertEq(zoraNFTBase.saleDetails().totalMinted, 3); - require( - zoraNFTBase.ownerOf(2) == address(item.user), - "owner is wrong for new minted token" - ); + require(zoraNFTBase.ownerOf(2) == address(item.user), "owner is wrong for new minted token"); vm.stopPrank(); } @@ -128,9 +97,7 @@ contract ZoraNFTBaseTest is Test { presaleEnd: type(uint64).max, publicSalePrice: 0 ether, maxSalePurchasePerAddress: 0, - presaleMerkleRoot: merkleData - .getTestSetByName("test-3-addresses") - .root + presaleMerkleRoot: merkleData.getTestSetByName("test-3-addresses").root }); vm.stopPrank(); @@ -141,18 +108,8 @@ contract ZoraNFTBaseTest is Test { vm.deal(address(item.user), 1 ether); vm.startPrank(address(item.user)); - vm.expectRevert( - abi.encodeWithSelector( - IERC721Drop.Purchase_WrongPrice.selector, - item.mintPrice + fee - ) - ); - zoraNFTBase.purchasePresale{value: item.mintPrice - 1}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Purchase_WrongPrice.selector, item.mintPrice + fee)); + zoraNFTBase.purchasePresale{value: item.mintPrice - 1}(1, item.maxMint, item.mintPrice, item.proof); assertEq(zoraNFTBase.saleDetails().maxSupply, 10); assertEq(zoraNFTBase.saleDetails().totalMinted, 0); vm.stopPrank(); @@ -167,9 +124,7 @@ contract ZoraNFTBaseTest is Test { presaleEnd: type(uint64).max, publicSalePrice: 0 ether, maxSalePurchasePerAddress: 0, - presaleMerkleRoot: merkleData - .getTestSetByName("test-3-addresses") - .root + presaleMerkleRoot: merkleData.getTestSetByName("test-3-addresses").root }); vm.stopPrank(); @@ -181,21 +136,13 @@ contract ZoraNFTBaseTest is Test { vm.expectRevert(IERC721Drop.Presale_MerkleNotApproved.selector); item.proof[1] = item.proof[1] & bytes32(bytes4(0xcafecafe)); - zoraNFTBase.purchasePresale{value: item.mintPrice - 1}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: item.mintPrice - 1}(1, item.maxMint, item.mintPrice, item.proof); assertEq(zoraNFTBase.saleDetails().maxSupply, 10); assertEq(zoraNFTBase.saleDetails().totalMinted, 0); vm.stopPrank(); } - function test_MerklePurchaseAndPublicSalePurchaseLimits() - public - setupZoraNFTBase - { + function test_MerklePurchaseAndPublicSalePurchaseLimits() public setupZoraNFTBase { vm.startPrank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ publicSaleStart: 0, @@ -217,44 +164,18 @@ contract ZoraNFTBaseTest is Test { vm.startPrank(address(item.user)); vm.expectRevert(IERC721Drop.Presale_TooManyForAddress.selector); - zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 3}( - 3, - item.maxMint, - item.mintPrice, - item.proof - ); - - zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); - zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 3}(3, item.maxMint, item.mintPrice, item.proof); + + zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}(1, item.maxMint, item.mintPrice, item.proof); + zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}(1, item.maxMint, item.mintPrice, item.proof); assertEq(zoraNFTBase.saleDetails().totalMinted, 2); - require( - zoraNFTBase.ownerOf(1) == address(item.user), - "owner is wrong for new minted token" - ); + require(zoraNFTBase.ownerOf(1) == address(item.user), "owner is wrong for new minted token"); vm.expectRevert(IERC721Drop.Presale_TooManyForAddress.selector); - zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: (item.mintPrice + fee) * 1}(1, item.maxMint, item.mintPrice, item.proof); zoraNFTBase.purchase{value: 0.1 ether + fee}(1); - require( - zoraNFTBase.ownerOf(3) == address(item.user), - "owner is wrong for new minted token" - ); + require(zoraNFTBase.ownerOf(3) == address(item.user), "owner is wrong for new minted token"); vm.expectRevert(IERC721Drop.Purchase_TooManyForAddress.selector); zoraNFTBase.purchase{value: 0.1 ether + fee}(1); vm.stopPrank(); @@ -294,12 +215,7 @@ contract ZoraNFTBaseTest is Test { vm.startPrank(address(item.user)); vm.expectRevert(IERC721Drop.Mint_SoldOut.selector); - zoraNFTBase.purchasePresale{value: item.mintPrice}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: item.mintPrice}(1, item.maxMint, item.mintPrice, item.proof); vm.stopPrank(); } @@ -314,23 +230,14 @@ contract ZoraNFTBaseTest is Test { presaleEnd: 0, publicSalePrice: 0 ether, maxSalePurchasePerAddress: 0, - presaleMerkleRoot: merkleData - .getTestSetByName("test-3-addresses") - .root + presaleMerkleRoot: merkleData.getTestSetByName("test-3-addresses").root }); vm.stopPrank(); vm.deal(address(0x10), 1 ether); vm.startPrank(address(0x10)); - MerkleData.MerkleEntry memory item = merkleData - .getTestSetByName("test-3-addresses") - .entries[0]; + MerkleData.MerkleEntry memory item = merkleData.getTestSetByName("test-3-addresses").entries[0]; vm.expectRevert(IERC721Drop.Presale_Inactive.selector); - zoraNFTBase.purchasePresale{value: item.mintPrice}( - 1, - item.maxMint, - item.mintPrice, - item.proof - ); + zoraNFTBase.purchasePresale{value: item.mintPrice}(1, item.maxMint, item.mintPrice, item.proof); } } diff --git a/yarn.lock b/yarn.lock index b926055..343b21f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,32 +8,33 @@ integrity sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ== "@babel/code-frame@^7.0.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" - integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.10.tgz#1c20e612b768fefa75f6e90d6ecb86329247f0a3" + integrity sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA== dependencies: - "@babel/highlight" "^7.22.5" + "@babel/highlight" "^7.22.10" + chalk "^2.4.2" "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== -"@babel/highlight@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" - integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== +"@babel/highlight@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" + integrity sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ== dependencies: "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.0.0" + chalk "^2.4.2" js-tokens "^4.0.0" "@babel/runtime@^7.20.1", "@babel/runtime@^7.5.5": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" - integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682" + integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ== dependencies: - regenerator-runtime "^0.13.11" + regenerator-runtime "^0.14.0" "@changesets/apply-release-plan@^6.1.4": version "6.1.4" @@ -578,33 +579,28 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@1.4.14": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@^0.3.9": - version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + version "0.3.19" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" + integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@manypkg/find-root@^1.1.0": version "1.1.0" @@ -628,7 +624,14 @@ globby "^11.0.0" read-yaml-file "^1.1.0" -"@noble/curves@1.0.0", "@noble/curves@~1.0.0": +"@noble/curves@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + +"@noble/curves@~1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== @@ -640,7 +643,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== -"@noble/hashes@~1.3.0": +"@noble/hashes@1.3.1", "@noble/hashes@~1.3.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== @@ -678,17 +681,17 @@ debug "^4.1.1" semver "^7.5.4" -"@oclif/config@1.18.15": - version "1.18.15" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.15.tgz#3be95862dda32d759fc61bcadff1e7819915a112" - integrity sha512-eBTiFXGfXSzghc4Yjp3EutYU+6MrHX1kzk4j5i4CsR5AEor43ynXFrzpO6v7IwbR1KyUo+9SYE2D69Y+sHIMpg== +"@oclif/config@1.18.16", "@oclif/config@^1", "@oclif/config@^1.18.2": + version "1.18.16" + resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.16.tgz#3235d260ab1eb8388ebb6255bca3dd956249d796" + integrity sha512-VskIxVcN22qJzxRUq+raalq6Q3HUde7sokB7/xk5TqRZGEKRVbFeqdQBxDWwQeudiJEgcNiMvIFbMQ43dY37FA== dependencies: "@oclif/errors" "^1.3.6" - "@oclif/parser" "^3.8.15" + "@oclif/parser" "^3.8.16" debug "^4.3.4" globby "^11.1.0" is-wsl "^2.1.1" - tslib "^2.5.0" + tslib "^2.6.1" "@oclif/config@1.18.2": version "1.18.2" @@ -702,18 +705,6 @@ is-wsl "^2.1.1" tslib "^2.0.0" -"@oclif/config@^1", "@oclif/config@^1.18.2": - version "1.18.16" - resolved "https://registry.yarnpkg.com/@oclif/config/-/config-1.18.16.tgz#3235d260ab1eb8388ebb6255bca3dd956249d796" - integrity sha512-VskIxVcN22qJzxRUq+raalq6Q3HUde7sokB7/xk5TqRZGEKRVbFeqdQBxDWwQeudiJEgcNiMvIFbMQ43dY37FA== - dependencies: - "@oclif/errors" "^1.3.6" - "@oclif/parser" "^3.8.16" - debug "^4.3.4" - globby "^11.1.0" - is-wsl "^2.1.1" - tslib "^2.6.1" - "@oclif/errors@1.3.5": version "1.3.5" resolved "https://registry.yarnpkg.com/@oclif/errors/-/errors-1.3.5.tgz#a1e9694dbeccab10fe2fe15acb7113991bed636c" @@ -737,11 +728,11 @@ wrap-ansi "^7.0.0" "@oclif/help@^1.0.1": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@oclif/help/-/help-1.0.14.tgz#da5f9fdf6f57b40b133f095cbb9c78c480975ca3" - integrity sha512-Hu2/Dyo91cgLNaqN3wkvkBGuZ7eqb0TQNVKrzGButZyaBpJzmwW4L6D4tAF390WDYZG7EubmLePlNYb+rNB4jw== + version "1.0.15" + resolved "https://registry.yarnpkg.com/@oclif/help/-/help-1.0.15.tgz#5e36e576b8132a4906d2662204ad9de7ece87e8f" + integrity sha512-Yt8UHoetk/XqohYX76DfdrUYLsPKMc5pgkzsZVHDyBSkLiGRzujVaGZdjr32ckVZU9q3a47IjhWxhip7Dz5W/g== dependencies: - "@oclif/config" "1.18.15" + "@oclif/config" "1.18.16" "@oclif/errors" "1.3.6" chalk "^4.1.2" indent-string "^4.0.0" @@ -756,7 +747,7 @@ resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== -"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.15", "@oclif/parser@^3.8.16": +"@oclif/parser@^3.8.0", "@oclif/parser@^3.8.16": version "3.8.16" resolved "https://registry.yarnpkg.com/@oclif/parser/-/parser-3.8.16.tgz#bedfc55153075b8b2925657f8865035aa877515c" integrity sha512-jeleXSh5izmBQ6vwyCJmbFPahPpd/ajxASi25FaYAWcvwVMzP/vKAKQXKWZun6T9K/gd6ywSsTpfAXiZAjBd6g== @@ -823,9 +814,9 @@ integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*", "@types/node@^20.1.2": - version "20.4.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.6.tgz#b66b66c9bb5d49b199f03399e341c9d6036e9e88" - integrity sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA== + version "20.5.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.0.tgz#7fc8636d5f1aaa3b21e6245e97d56b7f56702313" + integrity sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q== "@types/node@^12.7.1": version "12.20.55" @@ -889,9 +880,9 @@ zod "^3.21.4" "@zoralabs/protocol-rewards@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@zoralabs/protocol-rewards/-/protocol-rewards-1.0.2.tgz#7727b3b6bbba57c26aae088884ff168542f745ed" - integrity sha512-r+4EGY9HKHXTwY89VFciI4wvjgh9ZJPuPGKBoAY6TwXXk8bN1h4CathbUmzkjC8hCw4knItEKTgebbHNpslAcg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/@zoralabs/protocol-rewards/-/protocol-rewards-1.1.1.tgz#e482c93598e92ce172f4e92584534e0521ffa8b2" + integrity sha512-lD5Jf/qWDQMG6rhnq1y2BHVEYIewDSUeAJwQD/1YIyXw1ANksLTmZZbrq8jXfFK2GbJeCzDqXKbFXSWidtyodw== abitype@0.8.7: version "0.8.7" @@ -1162,7 +1153,7 @@ capital-case@^1.0.4: tslib "^2.0.3" upper-case-first "^2.0.2" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2: +chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2306,10 +2297,10 @@ is-ci@^3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" @@ -2462,9 +2453,9 @@ isomorphic-ws@5.0.0: integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== jackspeak@^2.0.3: - version "2.2.2" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.2.tgz#707c62733924b8dc2a0a629dc6248577788b5385" - integrity sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg== + version "2.2.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.3.tgz#ac63c57c18d254dc78a1f4ecd1cdeb4daeb6e616" + integrity sha512-pF0kfjmg8DJLxDrizHoCZGUFz4P4czQ3HyfW4BU0ffebYkzAVlBywp5zaxW/TM+r0sGbmrQdi8EQQVTJFxnGsQ== dependencies: "@isaacs/cliui" "^8.0.2" optionalDependencies: @@ -2677,9 +2668,9 @@ lru-cache@^6.0.0: yallist "^4.0.0" "lru-cache@^9.1.1 || ^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" - integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== map-obj@^1.0.0: version "1.0.1" @@ -2782,9 +2773,9 @@ minimist-options@^4.0.2: kind-of "^6.0.3" "minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" - integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== + version "7.0.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.3.tgz#05ea638da44e475037ed94d1c7efcc76a25e1974" + integrity sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg== mixme@^0.5.1: version "0.5.9" @@ -3261,10 +3252,10 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== regexp.prototype.flags@^1.5.0: version "1.5.0" @@ -3291,11 +3282,11 @@ resolve-from@^5.0.0: integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve@^1.1.6, resolve@^1.10.0: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== dependencies: - is-core-module "^2.11.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -3313,9 +3304,9 @@ reusify@^1.0.4: integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rollup@^3.2.5: - version "3.27.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.27.0.tgz#15bd07e2e1cbfa9255bf6a3f04a432621c2f3550" - integrity sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg== + version "3.28.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.28.0.tgz#a3c70004b01934760c0cb8df717c7a1d932389a2" + integrity sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw== optionalDependencies: fsevents "~2.3.2" @@ -3722,7 +3713,7 @@ tslib@^1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.5.0, tslib@^2.6.1: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== @@ -3867,12 +3858,12 @@ validate-npm-package-license@^3.0.1: spdx-expression-parse "^3.0.0" viem@^1.0.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/viem/-/viem-1.5.2.tgz#b8b9b464c4fb211c1daec6253b3e2559b69607b7" - integrity sha512-hPs4TJ9ONZw44K8lh24I5+Qntu62DEP85yhPsGqSSyr2d9yROY/9AisLLTlrlsudhg+A+BnLQGAuqvj/X+i8Ow== + version "1.6.0" + resolved "https://registry.yarnpkg.com/viem/-/viem-1.6.0.tgz#8befa678c3ac79b9558dfd1708130b2ecb1994f4" + integrity sha512-ae9Twkd0q2Qlj4yYpWjb4DzYAhKY0ibEpRH8FJaTywZXNpTjFidSdBaT0CVn1BaH7O7cnX4/O47zvDUMGJD1AA== dependencies: "@adraffy/ens-normalize" "1.9.0" - "@noble/curves" "1.0.0" + "@noble/curves" "1.1.0" "@noble/hashes" "1.3.0" "@scure/bip32" "1.3.0" "@scure/bip39" "1.2.0" @@ -4080,6 +4071,6 @@ yocto-queue@^1.0.0: integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== zod@^3.21.4: - version "3.21.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" - integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== + version "3.22.1" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.1.tgz#815f850baf933fef96c1061322dbe579b1a80c27" + integrity sha512-+qUhAMl414+Elh+fRNtpU+byrwjDFOS1N7NioLY+tSlcADTx4TkCUua/hxJvxwDXcV4397/nZ420jy4n4+3WUg== From adfd22c6cb313764d7ae5fd69fb2a01a7e62230c Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Fri, 8 Sep 2023 16:45:20 -0700 Subject: [PATCH 08/10] 08 03 added mainnet (#147) * added two foundry verifier configs * added mainnet --- foundry.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/foundry.toml b/foundry.toml index b4317a3..c39ae2b 100644 --- a/foundry.toml +++ b/foundry.toml @@ -12,6 +12,10 @@ gas_reports = ['*'] fs_permissions = [{ access = "read", path = "./addresses"}, { access = "read", path = "./chainConfigs"}, { access = "read", path = "./package.json" }] [etherscan] +optimism = { key = "$OPT_ETHERSCAN_API_KEY" } +base = { key = "ANY_KEY_IS_OKAY" } +mainnet = { key = "$ETHERSCAN_API_KEY" } + zora_mainnet = { key = "", chain = 7777777, url = "https://explorer.zora.energy/api\\?" } zora_testnet = { key = "", chain = 999, url = "https://explorer.testnet.zora.energy/api\\?" } From 9228c58fd558e134bf0359e562fb8b2b41589d9e Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Fri, 8 Sep 2023 17:41:42 -0700 Subject: [PATCH 09/10] move to base and optimism dedicated rpcs (#151) --- foundry.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/foundry.toml b/foundry.toml index c39ae2b..085d0b2 100644 --- a/foundry.toml +++ b/foundry.toml @@ -32,7 +32,7 @@ optimism_goerli = "https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_KEY}" zora = "https://rpc.zora.energy" zora_goerli = "https://testnet.rpc.zora.energy" -base = "https://developer-access-mainnet.base.org" -base_goerli = "https://goerli.base.org" +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" pgn_sepolia = "https://sepolia.publicgoods.network" From 30ab758afb72461f31b71eebb17ef0f31bcc3fef Mon Sep 17 00:00:00 2001 From: Iain Nash Date: Thu, 14 Sep 2023 17:37:21 -0400 Subject: [PATCH 10/10] remove operator filterer registry from 721 (#150) --- DEPLOYING.md | 11 - script/Deploy.s.sol | 4 - script/TestUpgradeAndMint.s.sol | 2 - script/UpgradeERC721DropFactory.s.sol | 3 - src/DeploymentConfig.sol | 7 - src/ERC721Drop.sol | 79 --- src/filter/OwnedSubscriptionManager.sol | 14 - src/interfaces/IOperatorFilterRegistry.sol | 30 - test/ERC721Drop.t.sol | 265 +++------ test/ZoraNFTCreatorV1.t.sol | 1 - test/filter/OperatorFilterRegistry.sol | 530 ------------------ .../OperatorFilterRegistryErrorsAndEvents.sol | 30 - test/merkle/MerkleDrop.t.sol | 10 +- 13 files changed, 74 insertions(+), 912 deletions(-) delete mode 100644 src/filter/OwnedSubscriptionManager.sol delete mode 100644 src/interfaces/IOperatorFilterRegistry.sol delete mode 100644 test/filter/OperatorFilterRegistry.sol delete mode 100644 test/filter/OperatorFilterRegistryErrorsAndEvents.sol diff --git a/DEPLOYING.md b/DEPLOYING.md index 2a2760b..0b10b5e 100644 --- a/DEPLOYING.md +++ b/DEPLOYING.md @@ -7,17 +7,6 @@ Make sure required addresses / multisigs are setup for 1. funds recipient 2. contract factory upgrade owner address -Ensure that the default operator-filterer-registry deployment is on the current chain. - -If not, use the mainnet default filter address to re-deploy on the chain using ImmutableCreate2Factory (required also for seaport). - -To deploy ImmutableCreate2Factory, follow the steps in the seaport deploy scripts: https://github.com/ProjectOpenSea/seaport/blob/main/docs/Deployment.md#setting-up-factory-on-a-new-chain - -example call: -cast send 0x0000000000FFe8B47B3e2130213B802212439497 'function safeCreate2(bytes32,bytes)' [...] --rpc-url $(rpc base) --interactive - -copied from the mainnet deploy txn: https://etherscan.io/tx/0x4c2038f55147cae309c2e597a5323b42b63fd556a15d2f1b5a799eee1b3ddf04 - ### 1. Setup `chainConfigs` file. Use `1.json` for reference. We are ordering keys alphabetically. diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index f6100fd..e361a60 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -8,7 +8,6 @@ import {ERC721Drop} from "../src/ERC721Drop.sol"; import {ERC721DropProxy} from "../src/ERC721DropProxy.sol"; import {ZoraNFTCreatorV1} from "../src/ZoraNFTCreatorV1.sol"; import {ZoraNFTCreatorProxy} from "../src/ZoraNFTCreatorProxy.sol"; -import {IOperatorFilterRegistry} from "../src/interfaces/IOperatorFilterRegistry.sol"; import {FactoryUpgradeGate} from "../src/FactoryUpgradeGate.sol"; import {DropMetadataRenderer} from "../src/metadata/DropMetadataRenderer.sol"; import {EditionMetadataRenderer} from "../src/metadata/EditionMetadataRenderer.sol"; @@ -25,8 +24,6 @@ contract Deploy is ZoraDropsDeployBase { console2.log("Factory Owner", chainConfig.factoryOwner); console2.log("Fee Recipient", chainConfig.mintFeeRecipient); console2.log("Fee Amount", chainConfig.mintFeeAmount); - console2.log("Filterer Registry", chainConfig.subscriptionMarketFilterAddress); - console2.log("Filterer Subscription", chainConfig.subscriptionMarketFilterOwner); console2.log("Setup contracts ---"); @@ -41,7 +38,6 @@ contract Deploy is ZoraDropsDeployBase { ERC721Drop dropImplementation = new ERC721Drop({ _zoraERC721TransferHelper: address(0x0), _factoryUpgradeGate: factoryUpgradeGate, - _marketFilterDAOAddress: address(chainConfig.subscriptionMarketFilterAddress), _mintFeeAmount: chainConfig.mintFeeAmount, _mintFeeRecipient: payable(chainConfig.mintFeeRecipient), _protocolRewards: address(chainConfig.protocolRewards) diff --git a/script/TestUpgradeAndMint.s.sol b/script/TestUpgradeAndMint.s.sol index 8000657..8a88016 100644 --- a/script/TestUpgradeAndMint.s.sol +++ b/script/TestUpgradeAndMint.s.sol @@ -11,8 +11,6 @@ import {ZoraNFTCreatorV1} from "../src/ZoraNFTCreatorV1.sol"; import {IERC721Drop} from "../src/interfaces/IERC721Drop.sol"; import {ZoraNFTCreatorProxy} from "../src/ZoraNFTCreatorProxy.sol"; -import {IOperatorFilterRegistry} from "../src/interfaces/IOperatorFilterRegistry.sol"; -import {OwnedSubscriptionManager} from "../src/filter/OwnedSubscriptionManager.sol"; import {FactoryUpgradeGate} from "../src/FactoryUpgradeGate.sol"; import {DropMetadataRenderer} from "../src/metadata/DropMetadataRenderer.sol"; import {EditionMetadataRenderer} from "../src/metadata/EditionMetadataRenderer.sol"; diff --git a/script/UpgradeERC721DropFactory.s.sol b/script/UpgradeERC721DropFactory.s.sol index ae8c36e..58c6bfa 100644 --- a/script/UpgradeERC721DropFactory.s.sol +++ b/script/UpgradeERC721DropFactory.s.sol @@ -9,8 +9,6 @@ import {ERC721Drop} from "../src/ERC721Drop.sol"; import {ERC721DropProxy} from "../src/ERC721DropProxy.sol"; import {ZoraNFTCreatorV1} from "../src/ZoraNFTCreatorV1.sol"; import {ZoraNFTCreatorProxy} from "../src/ZoraNFTCreatorProxy.sol"; -import {IOperatorFilterRegistry} from "../src/interfaces/IOperatorFilterRegistry.sol"; -import {OwnedSubscriptionManager} from "../src/filter/OwnedSubscriptionManager.sol"; import {FactoryUpgradeGate} from "../src/FactoryUpgradeGate.sol"; import {DropMetadataRenderer} from "../src/metadata/DropMetadataRenderer.sol"; import {EditionMetadataRenderer} from "../src/metadata/EditionMetadataRenderer.sol"; @@ -57,7 +55,6 @@ contract UpgradeERC721DropFactory is ZoraDropsDeployBase { ERC721Drop dropImplementation = new ERC721Drop({ _zoraERC721TransferHelper: chainConfig.zoraERC721TransferHelper, _factoryUpgradeGate: IFactoryUpgradeGate(deployment.factoryUpgradeGate), - _marketFilterDAOAddress: chainConfig.subscriptionMarketFilterAddress, _mintFeeAmount: chainConfig.mintFeeAmount, _mintFeeRecipient: payable(chainConfig.mintFeeRecipient), _protocolRewards: chainConfig.protocolRewards diff --git a/src/DeploymentConfig.sol b/src/DeploymentConfig.sol index 47246eb..cbf9a83 100644 --- a/src/DeploymentConfig.sol +++ b/src/DeploymentConfig.sol @@ -16,10 +16,6 @@ struct ChainConfig { uint256 mintFeeAmount; /// @notice Mint fee recipient user address mintFeeRecipient; - /// @notice Subscription address for operator-filterer-registry (opensea / cori) - address subscriptionMarketFilterAddress; - /// @notice Owner for subscription of operator-filterer-registry (opensea / cori) - address subscriptionMarketFilterOwner; /// @notice Auto-approved hyperstructure on mainnet for enabling ZORA v3 with less gas. Deprecated – safe to set to address(0x) address zoraERC721TransferHelper; /// @notice The Protocol Rewards contract @@ -65,8 +61,6 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script string constant FACTORY_UPGRADE_GATE_OWNER = "FACTORY_OWNER"; string constant MINT_FEE_AMOUNT = "MINT_FEE_AMOUNT"; string constant MINT_FEE_RECIPIENT = "MINT_FEE_RECIPIENT"; - string constant SUBSCRIPTION_MARKET_FILTER_ADDRESS = "SUBSCRIPTION_MARKET_FILTER_ADDRESS"; - string constant SUBSCRIPTION_MARKET_FILTER_OWNER = "SUBSCRIPTION_MARKET_FILTER_OWNER"; string constant ZORA_ERC721_TRANSFER_HELPER = "ZORA_ERC721_TRANSFER_HELPER"; string constant PROTOCOL_REWARDS = "PROTOCOL_REWARDS"; @@ -93,7 +87,6 @@ abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, Script chainConfig.factoryUpgradeGateOwner = json.readAddress(getKeyPrefix(FACTORY_UPGRADE_GATE_OWNER)); chainConfig.mintFeeAmount = json.readUint(getKeyPrefix(MINT_FEE_AMOUNT)); chainConfig.mintFeeRecipient = json.readAddress(getKeyPrefix(MINT_FEE_RECIPIENT)); - chainConfig.subscriptionMarketFilterAddress = json.readAddress(getKeyPrefix(SUBSCRIPTION_MARKET_FILTER_ADDRESS)); chainConfig.zoraERC721TransferHelper = json.readAddress(getKeyPrefix(ZORA_ERC721_TRANSFER_HELPER)); chainConfig.protocolRewards = json.readAddress(getKeyPrefix(PROTOCOL_REWARDS)); } diff --git a/src/ERC721Drop.sol b/src/ERC721Drop.sol index 5ab6d04..826fa2e 100644 --- a/src/ERC721Drop.sol +++ b/src/ERC721Drop.sol @@ -29,7 +29,6 @@ import {ERC721Rewards} from "@zoralabs/protocol-rewards/src/abstract/ERC721/ERC7 import {ERC721RewardsStorageV1} from "@zoralabs/protocol-rewards/src/abstract/ERC721/ERC721RewardsStorageV1.sol"; import {IMetadataRenderer} from "./interfaces/IMetadataRenderer.sol"; -import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"; import {IERC721Drop} from "./interfaces/IERC721Drop.sol"; import {IOwnable} from "./interfaces/IOwnable.sol"; import {IERC4906} from "./interfaces/IERC4906.sol"; @@ -97,12 +96,6 @@ contract ERC721Drop is // /// @notice Empty string for blank comments // string constant EMPTY_STRING = ""; - /// @notice Market filter DAO address for opensea filter registry - address public immutable marketFilterDAOAddress; - - IOperatorFilterRegistry immutable operatorFilterRegistry = - IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); - /// @notice Only allow for users with admin access modifier onlyAdmin() { if (!hasRole(DEFAULT_ADMIN_ROLE, _msgSender())) { @@ -178,20 +171,17 @@ contract ERC721Drop is /// @dev Marked as an initializer to prevent storage being used of base implementation. Can only be init'd by a proxy. /// @param _zoraERC721TransferHelper Transfer helper /// @param _factoryUpgradeGate Factory upgrade gate address - /// @param _marketFilterDAOAddress Market filter DAO address /// @param _mintFeeAmount Mint fee amount in wei /// @param _mintFeeRecipient Mint fee recipient address constructor( address _zoraERC721TransferHelper, IFactoryUpgradeGate _factoryUpgradeGate, - address _marketFilterDAOAddress, uint256 _mintFeeAmount, address payable _mintFeeRecipient, address _protocolRewards ) initializer ERC721Rewards(_protocolRewards, _mintFeeRecipient) { zoraERC721TransferHelper = _zoraERC721TransferHelper; factoryUpgradeGate = _factoryUpgradeGate; - marketFilterDAOAddress = _marketFilterDAOAddress; ZORA_MINT_FEE = _mintFeeAmount; ZORA_MINT_FEE_RECIPIENT = _mintFeeRecipient; } @@ -759,75 +749,6 @@ contract ERC721Drop is return firstMintedTokenId; } - /** - *** ---------------------------------- *** - *** *** - *** ADMIN OPERATOR FILTERING *** - *** *** - *** ---------------------------------- *** - ***/ - - /// @notice Proxy to update market filter settings in the main registry contracts - /// @notice Requires admin permissions - /// @param args Calldata args to pass to the registry - function updateMarketFilterSettings(bytes calldata args) - external - onlyAdmin - returns (bytes memory) - { - (bool success, bytes memory ret) = address(operatorFilterRegistry).call( - args - ); - if (!success) { - revert RemoteOperatorFilterRegistryCallFailed(); - } - return ret; - } - - /// @notice Manage subscription to the DAO for marketplace filtering based off royalty payouts. - /// @param enable Enable filtering to non-royalty payout marketplaces - function manageMarketFilterDAOSubscription(bool enable) external onlyAdmin { - address self = address(this); - if (marketFilterDAOAddress == address(0x0)) { - revert MarketFilterDAOAddressNotSupportedForChain(); - } - if (!operatorFilterRegistry.isRegistered(self) && enable) { - operatorFilterRegistry.registerAndSubscribe( - self, - marketFilterDAOAddress - ); - } else if (enable) { - operatorFilterRegistry.subscribe(self, marketFilterDAOAddress); - } else { - operatorFilterRegistry.unsubscribe(self, false); - operatorFilterRegistry.unregister(self); - } - } - - /// @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); - } - } - } - /** *** ---------------------------------- *** *** *** diff --git a/src/filter/OwnedSubscriptionManager.sol b/src/filter/OwnedSubscriptionManager.sol deleted file mode 100644 index c69943c..0000000 --- a/src/filter/OwnedSubscriptionManager.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import {IOperatorFilterRegistry} from "../../src/interfaces/IOperatorFilterRegistry.sol"; -import {OwnableWithConfirmation} from "../../src/utils/OwnableWithConfirmation.sol"; - -contract OwnedSubscriptionManager is OwnableWithConfirmation { - IOperatorFilterRegistry immutable registry = - IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); - - constructor(address _initialOwner) OwnableWithConfirmation(_initialOwner) { - registry.register(address(this)); - } -} diff --git a/src/interfaces/IOperatorFilterRegistry.sol b/src/interfaces/IOperatorFilterRegistry.sol deleted file mode 100644 index ff7b9b9..0000000 --- a/src/interfaces/IOperatorFilterRegistry.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -interface IOperatorFilterRegistry { - function isOperatorAllowed(address registrant, address operator) external view returns (bool); - function register(address registrant) external; - function registerAndSubscribe(address registrant, address subscription) external; - function registerAndCopyEntries(address registrant, address registrantToCopy) external; - function updateOperator(address registrant, address operator, bool filtered) external; - function updateOperators(address registrant, address[] calldata operators, bool filtered) external; - function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; - function subscribe(address registrant, address registrantToSubscribe) external; - function unsubscribe(address registrant, bool copyExistingEntries) external; - function subscriptionOf(address addr) external returns (address registrant); - function subscribers(address registrant) external returns (address[] memory); - function subscriberAt(address registrant, uint256 index) external returns (address); - function copyEntriesOf(address registrant, address registrantToCopy) external; - function isOperatorFiltered(address registrant, address operator) external returns (bool); - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); - function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); - function filteredOperators(address addr) external returns (address[] memory); - function filteredCodeHashes(address addr) external returns (bytes32[] memory); - function filteredOperatorAt(address registrant, uint256 index) external returns (address); - function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); - function isRegistered(address addr) external returns (bool); - function codeHashOf(address addr) external returns (bytes32); - - function unregister(address registrant) external; -} \ No newline at end of file diff --git a/test/ERC721Drop.t.sol b/test/ERC721Drop.t.sol index 62817ae..d57fd9b 100644 --- a/test/ERC721Drop.t.sol +++ b/test/ERC721Drop.t.sol @@ -10,14 +10,10 @@ import {RewardsSettings} from "@zoralabs/protocol-rewards/src/abstract/RewardSpl import {ERC721Drop} from "../src/ERC721Drop.sol"; import {DummyMetadataRenderer} from "./utils/DummyMetadataRenderer.sol"; import {MockUser} from "./utils/MockUser.sol"; -import {IOperatorFilterRegistry} from "../src/interfaces/IOperatorFilterRegistry.sol"; import {IMetadataRenderer} from "../src/interfaces/IMetadataRenderer.sol"; import {IERC721Drop} from "../src/interfaces/IERC721Drop.sol"; import {FactoryUpgradeGate} from "../src/FactoryUpgradeGate.sol"; import {ERC721DropProxy} from "../src/ERC721DropProxy.sol"; -import {OperatorFilterRegistry} from "./filter/OperatorFilterRegistry.sol"; -import {OperatorFilterRegistryErrorsAndEvents} from "./filter/OperatorFilterRegistryErrorsAndEvents.sol"; -import {OwnedSubscriptionManager} from "../src/filter/OwnedSubscriptionManager.sol"; contract ERC721DropTest is Test { /// @notice Event emitted when the funds are withdrawn from the minting contract @@ -26,21 +22,11 @@ contract ERC721DropTest is Test { /// @param amount amount that was withdrawn /// @param feeRecipient user getting withdraw fee (if any) /// @param feeAmount amount of the fee getting sent (if any) - event FundsWithdrawn( - address indexed withdrawnBy, - address indexed withdrawnTo, - uint256 amount, - address feeRecipient, - uint256 feeAmount - ); - - event Sale( - address indexed to, uint256 indexed purchaseQuantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId - ); - - event MintComment( - address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 purchaseQuantity, string comment - ); + event FundsWithdrawn(address indexed withdrawnBy, address indexed withdrawnTo, uint256 amount, address feeRecipient, uint256 feeAmount); + + event Sale(address indexed to, uint256 indexed purchaseQuantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId); + + event MintComment(address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 purchaseQuantity, string comment); address internal creator; address internal collector; @@ -59,7 +45,6 @@ contract ERC721DropTest is Test { address public constant UPGRADE_GATE_ADMIN_ADDRESS = address(0x942924224); address public constant mediaContract = address(0x123456); address public impl; - address public ownedSubscriptionManager; address payable public constant mintFeeRecipient = payable(address(0x11)); uint256 public constant mintFee = 777000000000000; // 0.000777 ETH uint256 public constant TOTAL_REWARD_PER_MINT = 0.000999 ether; @@ -119,35 +104,31 @@ contract ERC721DropTest is Test { vm.prank(DEFAULT_ZORA_DAO_ADDRESS); factoryUpgradeGate = new FactoryUpgradeGate(UPGRADE_GATE_ADMIN_ADDRESS); - vm.etch(address(0x000000000000AAeB6D7670E522A718067333cd4E), address(new OperatorFilterRegistry()).code); - ownedSubscriptionManager = address(new OwnedSubscriptionManager(address(0x123456))); vm.prank(DEFAULT_ZORA_DAO_ADDRESS); impl = address( - new ERC721Drop( - address(0x1234), - factoryUpgradeGate, - address(0x0), - mintFee, - mintFeeRecipient, - address(protocolRewards) - ) + new ERC721Drop({ + _zoraERC721TransferHelper: address(0x1234), + _factoryUpgradeGate: factoryUpgradeGate, + _mintFeeAmount: mintFee, + _mintFeeRecipient: mintFeeRecipient, + _protocolRewards: address(protocolRewards) + }) ); address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); } - modifier factoryWithSubscriptionAddress(address subscriptionAddress) { + modifier withFactory() { vm.prank(DEFAULT_ZORA_DAO_ADDRESS); impl = address( - new ERC721Drop( - address(0x1234), - factoryUpgradeGate, - address(subscriptionAddress), - mintFee, - mintFeeRecipient, - address(protocolRewards) - ) + new ERC721Drop({ + _zoraERC721TransferHelper: address(0x1234), + _factoryUpgradeGate: factoryUpgradeGate, + _mintFeeAmount: mintFee, + _mintFeeRecipient: mintFeeRecipient, + _protocolRewards: address(protocolRewards) + }) ); address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); @@ -158,8 +139,7 @@ contract ERC721DropTest is Test { function test_Init() public setupZoraNFTBase(10) { require(zoraNFTBase.owner() == DEFAULT_OWNER_ADDRESS, "Default owner set wrong"); - (IMetadataRenderer renderer, uint64 editionSize, uint16 royaltyBPS, address payable fundsRecipient) = - zoraNFTBase.config(); + (IMetadataRenderer renderer, uint64 editionSize, uint16 royaltyBPS, address payable fundsRecipient) = zoraNFTBase.config(); require(address(renderer) == address(dummyRenderer)); require(editionSize == 10, "EditionSize is wrong"); @@ -212,69 +192,9 @@ contract ERC721DropTest is Test { assertTrue(!zoraNFTBase.isAdmin(address(0))); } - function test_SubscriptionEnabled() - public - factoryWithSubscriptionAddress(ownedSubscriptionManager) - setupZoraNFTBase(10) - { - IOperatorFilterRegistry operatorFilterRegistry = - IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); - vm.startPrank(address(0x123456)); - operatorFilterRegistry.updateOperator(ownedSubscriptionManager, address(0xcafeea3), true); - vm.stopPrank(); - vm.startPrank(DEFAULT_OWNER_ADDRESS); - zoraNFTBase.manageMarketFilterDAOSubscription(true); - zoraNFTBase.adminMint(DEFAULT_OWNER_ADDRESS, 10); - zoraNFTBase.setApprovalForAll(address(0xcafeea3), true); - vm.stopPrank(); - vm.prank(address(0xcafeea3)); - vm.expectRevert( - abi.encodeWithSelector(OperatorFilterRegistryErrorsAndEvents.AddressFiltered.selector, address(0xcafeea3)) - ); - zoraNFTBase.transferFrom(DEFAULT_OWNER_ADDRESS, address(0x123456), 1); - vm.prank(DEFAULT_OWNER_ADDRESS); - zoraNFTBase.manageMarketFilterDAOSubscription(false); - vm.prank(address(0xcafeea3)); - zoraNFTBase.transferFrom(DEFAULT_OWNER_ADDRESS, address(0x123456), 1); - } - - function test_OnlyAdminEnableSubscription() - public - factoryWithSubscriptionAddress(ownedSubscriptionManager) - setupZoraNFTBase(10) - { - vm.startPrank(address(0xcafecafe)); - vm.expectRevert(IERC721Drop.Access_OnlyAdmin.selector); - zoraNFTBase.manageMarketFilterDAOSubscription(true); - vm.stopPrank(); - } - - function test_ProxySubscriptionAccessOnlyAdmin() - public - factoryWithSubscriptionAddress(ownedSubscriptionManager) - setupZoraNFTBase(10) - { - bytes memory baseCall = abi.encodeWithSelector(IOperatorFilterRegistry.register.selector, address(zoraNFTBase)); - vm.startPrank(address(0xcafecafe)); - vm.expectRevert(IERC721Drop.Access_OnlyAdmin.selector); - zoraNFTBase.updateMarketFilterSettings(baseCall); - vm.stopPrank(); - } - - function test_ProxySubscriptionAccess() - public - factoryWithSubscriptionAddress(ownedSubscriptionManager) - setupZoraNFTBase(10) - { - vm.startPrank(address(DEFAULT_OWNER_ADDRESS)); - bytes memory baseCall = abi.encodeWithSelector(IOperatorFilterRegistry.register.selector, address(zoraNFTBase)); - zoraNFTBase.updateMarketFilterSettings(baseCall); - vm.stopPrank(); - } - function test_RoyaltyInfo() public setupZoraNFTBase(10) { // assert 800 royaltyAmount or 8% - ( , uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); + (, uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); assertEq(royaltyAmount, 0.08 ether); } @@ -282,7 +202,7 @@ contract ERC721DropTest is Test { vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setFundsRecipient(payable(address(0))); // assert 800 royaltyAmount or 8% - ( , uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); + (, uint256 royaltyAmount) = zoraNFTBase.royaltyInfo(10, 1 ether); assertEq(royaltyAmount, 0 ether); } @@ -314,10 +234,7 @@ contract ERC721DropTest is Test { assertEq(mintFeeRecipient.balance, zoraFee); } - function test_PurchaseWithComment(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function test_PurchaseWithComment(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -339,10 +256,7 @@ contract ERC721DropTest is Test { zoraNFTBase.purchaseWithComment{value: paymentAmount}(purchaseQuantity, "test comment"); } - function test_PurchaseWithRecipient(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function test_PurchaseWithRecipient(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -365,15 +279,12 @@ contract ERC721DropTest is Test { vm.prank(minter); zoraNFTBase.purchaseWithRecipient{value: paymentAmount}(recipient, purchaseQuantity, ""); - for (uint256 i; i < purchaseQuantity;) { + for (uint256 i; i < purchaseQuantity; ) { assertEq(zoraNFTBase.ownerOf(++i), recipient); } } - function test_PurchaseWithRecipientAndComment(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function test_PurchaseWithRecipientAndComment(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -400,10 +311,7 @@ contract ERC721DropTest is Test { zoraNFTBase.purchaseWithRecipient{value: paymentAmount}(recipient, purchaseQuantity, "test comment"); } - function testRevert_PurchaseWithInvalidRecipient(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function testRevert_PurchaseWithInvalidRecipient(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); zoraNFTBase.setSaleConfiguration({ @@ -482,10 +390,7 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); } - function test_FreeMintRewardsWithCreateReferral(uint32 purchaseQuantity) - public - setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) - { + function test_FreeMintRewardsWithCreateReferral(uint32 purchaseQuantity) public setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); @@ -512,10 +417,9 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); } - function test_FreeMintRewardsWithMintAndCreateReferrals(uint32 purchaseQuantity) - public - setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) - { + function test_FreeMintRewardsWithMintAndCreateReferrals( + uint32 purchaseQuantity + ) public setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); @@ -543,10 +447,7 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); } - function testRevert_FreeMintRewardsInsufficientEth(uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function testRevert_FreeMintRewardsInsufficientEth(uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); vm.prank(DEFAULT_OWNER_ADDRESS); @@ -564,10 +465,7 @@ contract ERC721DropTest is Test { zoraNFTBase.mintWithRewards(collector, purchaseQuantity, "test comment", address(0)); } - function test_PaidMintRewards(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function test_PaidMintRewards(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(salePrice > 0); vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); @@ -597,10 +495,7 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(mintFeeRecipient), settings.zoraReward + settings.mintReferralReward + settings.createReferralReward); } - function test_PaidMintRewardsWithMintReferral(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function test_PaidMintRewardsWithMintReferral(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(salePrice > 0); vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); @@ -630,10 +525,10 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(mintReferral), settings.mintReferralReward); } - function test_PaidMintRewardsWithCreateReferral(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) - { + function test_PaidMintRewardsWithCreateReferral( + uint64 salePrice, + uint32 purchaseQuantity + ) public setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) { vm.assume(salePrice > 0); vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); @@ -664,10 +559,10 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); } - function test_PaidMintRewardsWithMintAndCreateReferrals(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) - { + function test_PaidMintRewardsWithMintAndCreateReferrals( + uint64 salePrice, + uint32 purchaseQuantity + ) public setupZoraNFTBaseWithCreateReferral(purchaseQuantity, createReferral) { vm.assume(salePrice > 0); vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); @@ -699,10 +594,7 @@ contract ERC721DropTest is Test { assertEq(protocolRewards.balanceOf(createReferral), settings.createReferralReward); } - function testRevert_PaidMintRewardsInsufficientEth(uint64 salePrice, uint32 purchaseQuantity) - public - setupZoraNFTBase(purchaseQuantity) - { + function testRevert_PaidMintRewardsInsufficientEth(uint64 salePrice, uint32 purchaseQuantity) public setupZoraNFTBase(purchaseQuantity) { vm.assume(salePrice > 0); vm.assume(purchaseQuantity < 100 && purchaseQuantity > 0); @@ -723,14 +615,13 @@ contract ERC721DropTest is Test { function test_UpgradeApproved() public setupZoraNFTBase(10) { address newImpl = address( - new ERC721Drop( - address(0x3333), - factoryUpgradeGate, - address(0x0), - mintFee, - mintFeeRecipient, - address(protocolRewards) - ) + new ERC721Drop({ + _zoraERC721TransferHelper: address(0x3333), + _factoryUpgradeGate: factoryUpgradeGate, + _mintFeeAmount: mintFee, + _mintFeeRecipient: mintFeeRecipient, + _protocolRewards: address(protocolRewards) + }) ); address[] memory lastImpls = new address[](1); @@ -742,16 +633,7 @@ contract ERC721DropTest is Test { } function test_UpgradeFailsNotApproved() public setupZoraNFTBase(10) { - address newImpl = address( - new ERC721Drop( - address(0x3333), - factoryUpgradeGate, - address(0x0), - mintFee, - mintFeeRecipient, - address(protocolRewards) - ) - ); + address newImpl = address(new ERC721Drop(address(0x3333), factoryUpgradeGate, mintFee, mintFeeRecipient, address(protocolRewards))); vm.prank(DEFAULT_OWNER_ADDRESS); vm.expectRevert(abi.encodeWithSelector(IERC721Drop.Admin_InvalidUpgradeAddress.selector, newImpl)); @@ -831,10 +713,7 @@ contract ERC721DropTest is Test { calls[1] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); vm.expectRevert( - abi.encodeWithSelector( - IERC721Drop.Access_MissingRoleOrAdmin.selector, - bytes32(0xf0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9) - ) + abi.encodeWithSelector(IERC721Drop.Access_MissingRoleOrAdmin.selector, bytes32(0xf0887ba65ee2024ea881d91b74c2450ef19e1557f03bed3ea9f16b037cbe2dc9)) ); zoraNFTBase.multicall(calls); @@ -855,8 +734,9 @@ contract ERC721DropTest is Test { calls[2] = abi.encodeWithSelector(IERC721Drop.saleDetails.selector); bytes[] memory results = zoraNFTBase.multicall(calls); - (bool saleActive, bool presaleActive, uint256 publicSalePrice,,,,,,,,) = abi.decode( - results[2], (bool, bool, uint256, uint64, uint64, uint64, uint64, bytes32, uint256, uint256, uint256) + (bool saleActive, bool presaleActive, uint256 publicSalePrice, , , , , , , , ) = abi.decode( + results[2], + (bool, bool, uint256, uint64, uint64, uint64, uint64, bytes32, uint256, uint256, uint256) ); assertTrue(!saleActive); assertTrue(!presaleActive); @@ -870,9 +750,7 @@ contract ERC721DropTest is Test { function test_UpdatePriceMulticall() public setupZoraNFTBase(10) { vm.startPrank(DEFAULT_OWNER_ADDRESS); bytes[] memory calls = new bytes[](3); - calls[0] = abi.encodeWithSelector( - IERC721Drop.setSaleConfiguration.selector, 0.1 ether, 2, 0, type(uint64).max, 0, 0, bytes32(0) - ); + calls[0] = abi.encodeWithSelector(IERC721Drop.setSaleConfiguration.selector, 0.1 ether, 2, 0, type(uint64).max, 0, 0, bytes32(0)); calls[1] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); calls[2] = abi.encodeWithSelector(IERC721Drop.adminMint.selector, address(0x123), 3); bytes[] memory results = zoraNFTBase.multicall(calls); @@ -922,9 +800,7 @@ contract ERC721DropTest is Test { vm.prank(DEFAULT_OWNER_ADDRESS); vm.expectEmit(true, true, true, true); - emit FundsWithdrawn( - DEFAULT_OWNER_ADDRESS, DEFAULT_FUNDS_RECIPIENT_ADDRESS, leftoverFunds, payable(address(0)), 0 - ); + emit FundsWithdrawn(DEFAULT_OWNER_ADDRESS, DEFAULT_FUNDS_RECIPIENT_ADDRESS, leftoverFunds, payable(address(0)), 0); zoraNFTBase.withdraw(); assertEq(DEFAULT_FUNDS_RECIPIENT_ADDRESS.balance, amount); @@ -971,9 +847,7 @@ contract ERC721DropTest is Test { vm.deal(address(444), 1_000_000 ether); vm.prank(address(444)); vm.expectRevert(IERC721Drop.Purchase_TooManyForAddress.selector); - zoraNFTBase.purchase{value: (0.1 ether * (uint256(limit) + 1)) + (fee * (uint256(limit) + 1))}( - uint256(limit) + 1 - ); + zoraNFTBase.purchase{value: (0.1 ether * (uint256(limit) + 1)) + (fee * (uint256(limit) + 1))}(uint256(limit) + 1); assertEq(zoraNFTBase.saleDetails().totalMinted, limit); } @@ -990,7 +864,7 @@ contract ERC721DropTest is Test { presaleMerkleRoot: bytes32(0) }); - (,,,,, uint64 presaleEndLookup,) = zoraNFTBase.salesConfig(); + (, , , , , uint64 presaleEndLookup, ) = zoraNFTBase.salesConfig(); assertEq(presaleEndLookup, 100); address SALES_MANAGER_ADDR = address(0x11002); @@ -1008,7 +882,7 @@ contract ERC721DropTest is Test { presaleMerkleRoot: bytes32(0) }); - (,,,, uint64 presaleStartLookup2, uint64 presaleEndLookup2,) = zoraNFTBase.salesConfig(); + (, , , , uint64 presaleStartLookup2, uint64 presaleEndLookup2, ) = zoraNFTBase.salesConfig(); assertEq(presaleEndLookup2, 0); assertEq(presaleStartLookup2, 100); } @@ -1186,17 +1060,14 @@ contract ERC721DropTest is Test { function test_AdminMetadataRendererUpdateCall() public setupZoraNFTBase(10) { vm.startPrank(DEFAULT_OWNER_ADDRESS); assertEq(dummyRenderer.someState(), ""); - zoraNFTBase.callMetadataRenderer( - abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase)) - ); + zoraNFTBase.callMetadataRenderer(abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase))); assertEq(dummyRenderer.someState(), "new state"); } function test_NonAdminMetadataRendererUpdateCall() public setupZoraNFTBase(10) { vm.startPrank(address(0x99493)); assertEq(dummyRenderer.someState(), ""); - bytes memory targetCall = - abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase)); + bytes memory targetCall = abi.encodeWithSelector(DummyMetadataRenderer.updateSomeState.selector, "new state", address(zoraNFTBase)); vm.expectRevert(IERC721Drop.Access_OnlyAdmin.selector); zoraNFTBase.callMetadataRenderer(targetCall); assertEq(dummyRenderer.someState(), ""); @@ -1208,14 +1079,8 @@ contract ERC721DropTest is Test { zoraNFTBase.updateRoyaltyMintSchedule(1); } - function test_SupplyRoyaltyPurchase(uint32 royaltyMintSchedule, uint32 editionSize, uint256 mintQuantity) - public - setupZoraNFTBase(editionSize) - { - vm.assume( - royaltyMintSchedule > 1 && royaltyMintSchedule <= editionSize && editionSize <= 100000 && mintQuantity > 0 - && mintQuantity <= editionSize - ); + function test_SupplyRoyaltyPurchase(uint32 royaltyMintSchedule, uint32 editionSize, uint256 mintQuantity) public setupZoraNFTBase(editionSize) { + vm.assume(royaltyMintSchedule > 1 && royaltyMintSchedule <= editionSize && editionSize <= 100000 && mintQuantity > 0 && mintQuantity <= editionSize); uint256 totalRoyaltyMintsForSale = editionSize / royaltyMintSchedule; vm.assume(mintQuantity <= editionSize - totalRoyaltyMintsForSale); diff --git a/test/ZoraNFTCreatorV1.t.sol b/test/ZoraNFTCreatorV1.t.sol index 281be1d..93afc25 100644 --- a/test/ZoraNFTCreatorV1.t.sol +++ b/test/ZoraNFTCreatorV1.t.sol @@ -36,7 +36,6 @@ contract ZoraNFTCreatorV1Test is Test { dropImpl = new ERC721Drop( address(1234), FactoryUpgradeGate(address(0)), - address(0), mintFee, mintFeeRecipient, address(protocolRewards) diff --git a/test/filter/OperatorFilterRegistry.sol b/test/filter/OperatorFilterRegistry.sol deleted file mode 100644 index 0693511..0000000 --- a/test/filter/OperatorFilterRegistry.sol +++ /dev/null @@ -1,530 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -import {IOperatorFilterRegistry} from "../../src/interfaces/IOperatorFilterRegistry.sol"; -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol"; - -/** - * @title OperatorFilterRegistry - * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: - * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol - * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be - * * restricted according to the isOperatorAllowed function. - */ -contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { - using EnumerableSet for EnumerableSet.AddressSet; - using EnumerableSet for EnumerableSet.Bytes32Set; - - /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) - /// Note that this will also be a smart contract's codehash when making calls from its constructor. - bytes32 constant EOA_CODEHASH = keccak256(""); - - mapping(address => EnumerableSet.AddressSet) private _filteredOperators; - mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; - mapping(address => address) private _registrations; - mapping(address => EnumerableSet.AddressSet) private _subscribers; - - /** - * @notice restricts method caller to the address or EIP-173 "owner()" - */ - modifier onlyAddressOrOwner(address addr) { - if (msg.sender != addr) { - try Ownable(addr).owner() returns (address owner) { - if (msg.sender != owner) { - revert OnlyAddressOrOwner(); - } - } catch (bytes memory reason) { - if (reason.length == 0) { - revert NotOwnable(); - } else { - /// @solidity memory-safe-assembly - assembly { - revert(add(32, reason), mload(reason)) - } - } - } - } - _; - } - - /** - * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns - * true if supplied registrant address is not registered. - */ - function isOperatorAllowed(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - EnumerableSet.AddressSet storage filteredOperatorsRef; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef; - - filteredOperatorsRef = _filteredOperators[registration]; - filteredCodeHashesRef = _filteredCodeHashes[registration]; - - if (filteredOperatorsRef.contains(operator)) { - revert AddressFiltered(operator); - } - if (operator.code.length > 0) { - bytes32 codeHash = operator.codehash; - if (filteredCodeHashesRef.contains(codeHash)) { - revert CodeHashFiltered(operator, codeHash); - } - } - } - return true; - } - - ////////////////// - // AUTH METHODS // - ////////////////// - - /** - * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. - */ - function register(address registrant) external onlyAddressOrOwner(registrant) { - if (_registrations[registrant] != address(0)) { - revert AlreadyRegistered(); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - } - - /** - * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. - * Note that this does not remove any filtered addresses or codeHashes. - * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. - */ - function unregister(address registrant) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = address(0); - emit RegistrationUpdated(registrant, false); - } - - /** - * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. - */ - function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - if (registrant == subscription) { - revert CannotSubscribeToSelf(); - } - address subscriptionRegistration = _registrations[subscription]; - if (subscriptionRegistration == address(0)) { - revert NotRegistered(subscription); - } - if (subscriptionRegistration != subscription) { - revert CannotSubscribeToRegistrantWithSubscription(subscription); - } - - _registrations[registrant] = subscription; - _subscribers[subscription].add(registrant); - emit RegistrationUpdated(registrant, true); - emit SubscriptionUpdated(registrant, subscription, true); - } - - /** - * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another - * address without subscribing. - */ - function registerAndCopyEntries(address registrant, address registrantToCopy) - external - onlyAddressOrOwner(registrant) - { - if (registrantToCopy == registrant) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration != address(0)) { - revert AlreadyRegistered(); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _registrations[registrant] = registrant; - emit RegistrationUpdated(registrant, true); - _copyEntries(registrant, registrantToCopy); - } - - /** - * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. - */ - function updateOperator(address registrant, address operator, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - - if (!filtered) { - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - } else { - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - } - emit OperatorUpdated(registrant, operator, filtered); - } - - /** - * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. - */ - function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) - external - onlyAddressOrOwner(registrant) - { - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - - if (!filtered) { - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - } else { - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - } - emit CodeHashUpdated(registrant, codeHash, filtered); - } - - /** - * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. - */ - function updateOperators(address registrant, address[] calldata operators, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; - uint256 operatorsLength = operators.length; - unchecked { - if (!filtered) { - for (uint256 i = 0; i < operatorsLength; ++i) { - address operator = operators[i]; - bool removed = filteredOperatorsRef.remove(operator); - if (!removed) { - revert AddressNotFiltered(operator); - } - } - } else { - for (uint256 i = 0; i < operatorsLength; ++i) { - address operator = operators[i]; - bool added = filteredOperatorsRef.add(operator); - if (!added) { - revert AddressAlreadyFiltered(operator); - } - } - } - } - emit OperatorsUpdated(registrant, operators, filtered); - } - - /** - * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. - */ - function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) - external - onlyAddressOrOwner(registrant) - { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; - uint256 codeHashesLength = codeHashes.length; - unchecked { - if (!filtered) { - for (uint256 i = 0; i < codeHashesLength; ++i) { - bytes32 codeHash = codeHashes[i]; - bool removed = filteredCodeHashesRef.remove(codeHash); - if (!removed) { - revert CodeHashNotFiltered(codeHash); - } - } - } else { - for (uint256 i = 0; i < codeHashesLength; ++i) { - bytes32 codeHash = codeHashes[i]; - if (codeHash == EOA_CODEHASH) { - revert CannotFilterEOAs(); - } - bool added = filteredCodeHashesRef.add(codeHash); - if (!added) { - revert CodeHashAlreadyFiltered(codeHash); - } - } - } - } - emit CodeHashesUpdated(registrant, codeHashes, filtered); - } - - /** - * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous - * subscription if present. - * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, - * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be - * used. - */ - function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { - if (registrant == newSubscription) { - revert CannotSubscribeToSelf(); - } - if (newSubscription == address(0)) { - revert CannotSubscribeToZeroAddress(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == newSubscription) { - revert AlreadySubscribed(newSubscription); - } - address newSubscriptionRegistration = _registrations[newSubscription]; - if (newSubscriptionRegistration == address(0)) { - revert NotRegistered(newSubscription); - } - if (newSubscriptionRegistration != newSubscription) { - revert CannotSubscribeToRegistrantWithSubscription(newSubscription); - } - - if (registration != registrant) { - _subscribers[registration].remove(registrant); - emit SubscriptionUpdated(registrant, registration, false); - } - _registrations[registrant] = newSubscription; - _subscribers[newSubscription].add(registrant); - emit SubscriptionUpdated(registrant, newSubscription, true); - } - - /** - * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. - */ - function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration == registrant) { - revert NotSubscribed(); - } - _subscribers[registration].remove(registrant); - _registrations[registrant] = registrant; - emit SubscriptionUpdated(registrant, registration, false); - if (copyExistingEntries) { - _copyEntries(registrant, registration); - } - } - - /** - * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. - */ - function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { - if (registrant == registrantToCopy) { - revert CannotCopyFromSelf(); - } - address registration = _registrations[registrant]; - if (registration == address(0)) { - revert NotRegistered(registrant); - } - if (registration != registrant) { - revert CannotUpdateWhileSubscribed(registration); - } - address registrantRegistration = _registrations[registrantToCopy]; - if (registrantRegistration == address(0)) { - revert NotRegistered(registrantToCopy); - } - _copyEntries(registrant, registrantToCopy); - } - - /// @dev helper to copy entries from registrantToCopy to registrant and emit events - function _copyEntries(address registrant, address registrantToCopy) private { - EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; - EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; - uint256 filteredOperatorsLength = filteredOperatorsRef.length(); - uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); - unchecked { - for (uint256 i = 0; i < filteredOperatorsLength; ++i) { - address operator = filteredOperatorsRef.at(i); - bool added = _filteredOperators[registrant].add(operator); - if (added) { - emit OperatorUpdated(registrant, operator, true); - } - } - for (uint256 i = 0; i < filteredCodeHashesLength; ++i) { - bytes32 codehash = filteredCodeHashesRef.at(i); - bool added = _filteredCodeHashes[registrant].add(codehash); - if (added) { - emit CodeHashUpdated(registrant, codehash, true); - } - } - } - } - - ////////////////// - // VIEW METHODS // - ////////////////// - - /** - * @notice Get the subscription address of a given registrant, if any. - */ - function subscriptionOf(address registrant) external view returns (address subscription) { - subscription = _registrations[registrant]; - if (subscription == address(0)) { - revert NotRegistered(registrant); - } else if (subscription == registrant) { - subscription = address(0); - } - } - - /** - * @notice Get the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscribers(address registrant) external view returns (address[] memory) { - return _subscribers[registrant].values(); - } - - /** - * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. - * Note that order is not guaranteed as updates are made. - */ - function subscriberAt(address registrant, uint256 index) external view returns (address) { - return _subscribers[registrant].at(index); - } - - /** - * @notice Returns true if operator is filtered by a given address or its subscription. - */ - function isOperatorFiltered(address registrant, address operator) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].contains(operator); - } - return _filteredOperators[registrant].contains(operator); - } - - /** - * @notice Returns true if a codeHash is filtered by a given address or its subscription. - */ - function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. - */ - function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { - bytes32 codeHash = operatorWithCode.codehash; - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].contains(codeHash); - } - return _filteredCodeHashes[registrant].contains(codeHash); - } - - /** - * @notice Returns true if an address has registered - */ - function isRegistered(address registrant) external view returns (bool) { - return _registrations[registrant] != address(0); - } - - /** - * @notice Returns a list of filtered operators for a given address or its subscription. - */ - function filteredOperators(address registrant) external view returns (address[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].values(); - } - return _filteredOperators[registrant].values(); - } - - /** - * @notice Returns the set of filtered codeHashes for a given address or its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].values(); - } - return _filteredCodeHashes[registrant].values(); - } - - /** - * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredOperators[registration].at(index); - } - return _filteredOperators[registrant].at(index); - } - - /** - * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or - * its subscription. - * Note that order is not guaranteed as updates are made. - */ - function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { - address registration = _registrations[registrant]; - if (registration != registrant) { - return _filteredCodeHashes[registration].at(index); - } - return _filteredCodeHashes[registrant].at(index); - } - - /// @dev Convenience method to compute the code hash of an arbitrary contract - function codeHashOf(address a) external view returns (bytes32) { - return a.codehash; - } -} diff --git a/test/filter/OperatorFilterRegistryErrorsAndEvents.sol b/test/filter/OperatorFilterRegistryErrorsAndEvents.sol deleted file mode 100644 index 03af044..0000000 --- a/test/filter/OperatorFilterRegistryErrorsAndEvents.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; - -contract OperatorFilterRegistryErrorsAndEvents { - error CannotFilterEOAs(); - error AddressAlreadyFiltered(address operator); - error AddressNotFiltered(address operator); - error CodeHashAlreadyFiltered(bytes32 codeHash); - error CodeHashNotFiltered(bytes32 codeHash); - error OnlyAddressOrOwner(); - error NotRegistered(address registrant); - error AlreadyRegistered(); - error AlreadySubscribed(address subscription); - error NotSubscribed(); - error CannotUpdateWhileSubscribed(address subscription); - error CannotSubscribeToSelf(); - error CannotSubscribeToZeroAddress(); - error NotOwnable(); - error AddressFiltered(address filtered); - error CodeHashFiltered(address account, bytes32 codeHash); - error CannotSubscribeToRegistrantWithSubscription(address registrant); - error CannotCopyFromSelf(); - - event RegistrationUpdated(address indexed registrant, bool indexed registered); - event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); - event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); - event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); - event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); - event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); -} diff --git a/test/merkle/MerkleDrop.t.sol b/test/merkle/MerkleDrop.t.sol index 9cd2bde..73a3b0f 100644 --- a/test/merkle/MerkleDrop.t.sol +++ b/test/merkle/MerkleDrop.t.sol @@ -46,7 +46,15 @@ contract ZoraNFTBaseTest is Test { protocolRewards = new ProtocolRewards(); vm.prank(DEFAULT_ZORA_DAO_ADDRESS); - address impl = address(new ERC721Drop(address(1234), FactoryUpgradeGate(address(0)), address(0), mintFee, mintFeeRecipient, address(protocolRewards))); + address impl = address( + new ERC721Drop( + address(1234), + FactoryUpgradeGate(address(0)), + mintFee, + mintFeeRecipient, + address(protocolRewards) + ) + ); address payable newDrop = payable(address(new ERC721DropProxy(impl, ""))); zoraNFTBase = ERC721Drop(newDrop); merkleData = new MerkleData();