Skip to content

Commit

Permalink
Fork tests (#133)
Browse files Browse the repository at this point in the history
* wip on fork tests

* Added fork test for creating an edition

Updated to use foundry version from npm

* moved fork test into its own file
  • Loading branch information
oveddan authored Jul 18, 2023
1 parent 147df38 commit badbe63
Show file tree
Hide file tree
Showing 18 changed files with 287 additions and 113 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/test_fork.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: fork tests

on: push

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'yarn'

- name: Install project dependencies
run: yarn

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run fork tests
run: |
forge test -vvv --match-test fork
env:
FORK_TEST_CHAINS: mainnet,goerli,optimism,optimism_goerli,zora,zora_goerli,base_goerli,base
ALCHEMY_KEY: ${{ secrets.ALCHEMY_KEY }}
id: test
4 changes: 0 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,3 @@
[submodule "lib/ERC721A-Upgradeable"]
path = lib/ERC721A-Upgradeable
url = https://github.com/chiru-labs/ERC721A-Upgradeable
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.4.0
4 changes: 2 additions & 2 deletions addresses/1.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"DROP_METADATA_RENDERER": "0x5914d9a241008B9F02f22811bF3A77e02B84D226",
"EDITION_METADATA_RENDERER": "0x192ce8267CbaB9C3C477D61e85D7f0c5fE3B46Af",
"DROP_METADATA_RENDERER": "0x5914d9a241008b9f02f22811bf3a77e02b84d226",
"EDITION_METADATA_RENDERER": "0x192ce8267cbab9c3c477d61e85d7f0c5fe3b46af",
"ERC721DROP_IMPL": "0x419074d73Cf0852e46b8531b430B1230C348C291",
"FACTORY_UPGRADE_GATE": "0x8Da5aC3A39D3B8BCaA1FC15A01506cf4F5e79830",
"ZORA_NFT_CREATOR_PROXY": "0xF74B146ce44CC162b601deC3BE331784DB111DC1",
Expand Down
2 changes: 1 addition & 1 deletion chainConfigs/1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"FACTORY_OWNER": "0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0",
"FACTORY_OWNER": "0xdb392f4391462d60b8b4413ef72018ab595af9d0",
"FACTORY_UPGRADE_GATE_OWNER": "0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0",
"MINT_FEE_AMOUNT": 777000000000000,
"MINT_FEE_RECIPIENT": "0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0",
Expand Down
2 changes: 1 addition & 1 deletion chainConfigs/420.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"FACTORY_OWNER": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb",
"FACTORY_OWNER": "0x5dee21327cd7cd6725c2578da1c3e5bb2d2d34b2",
"FACTORY_UPGRADE_GATE_OWNER": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb",
"MINT_FEE_AMOUNT": 777000000000000,
"MINT_FEE_RECIPIENT": "0x11cf5F667dC6AD4dEE58CB07e4AAc6a3fc7E1DCb",
Expand Down
14 changes: 13 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,19 @@ via_ir = true
out = 'out'
test = 'test'
src = 'src'
libs = ['lib']
libs = ['lib', 'node_modules']
gas_reports = ['*']

fs_permissions = [{ access = "read", path = "./addresses"}, { access = "read", path = "./chainConfigs"}, { access = "read", path = "./package.json" }]

[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"
1 change: 0 additions & 1 deletion lib/forge-std
Submodule forge-std deleted from a2edd3
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
"typescript": "^5.0.4"
},
"dependencies": {
"@dotenv/cli": "^2.2.2"
"@dotenv/cli": "^2.2.2",
"ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b",
"forge-std": "https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653"
}
}
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
erc721a-upgradeable=lib/ERC721A-Upgradeable/contracts/
base64/=lib/base64/
forge-std/=lib/forge-std/src/
ds-test/=node_modules/ds-test/src/
forge-std/=node_modules/forge-std/src/
3 changes: 2 additions & 1 deletion script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {DropMetadataRenderer} from "../src/metadata/DropMetadataRenderer.sol";
import {EditionMetadataRenderer} from "../src/metadata/EditionMetadataRenderer.sol";
import {IERC721Drop} from "../src//interfaces/IERC721Drop.sol";

import {ZoraDropsDeployBase, ChainConfig, DropDeployment} from "./ZoraDropsDeployBase.sol";
import {ZoraDropsDeployBase} from "./ZoraDropsDeployBase.sol";
import {ChainConfig, DropDeployment} from '../src/DeploymentConfig.sol';

contract Deploy is ZoraDropsDeployBase {
function run() public returns (string memory) {
Expand Down
3 changes: 2 additions & 1 deletion script/DeployFeeRegistry.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pragma solidity ^0.8.13;

import "forge-std/console2.sol";

import {ZoraDropsDeployBase, ChainConfig} from "./ZoraDropsDeployBase.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);
Expand Down
3 changes: 2 additions & 1 deletion script/UpgradeERC721DropFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity ^0.8.13;

import "forge-std/console2.sol";
import {ZoraDropsDeployBase, ChainConfig, DropDeployment} from "./ZoraDropsDeployBase.sol";
import {ZoraDropsDeployBase} from "./ZoraDropsDeployBase.sol";
import {ChainConfig, DropDeployment} from '../src/DeploymentConfig.sol';

import {ERC721Drop} from "../src/ERC721Drop.sol";
import {ERC721DropProxy} from "../src/ERC721DropProxy.sol";
Expand Down
100 changes: 2 additions & 98 deletions script/ZoraDropsDeployBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,109 +2,13 @@
pragma solidity ^0.8.13;

import "forge-std/Script.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 Chain configuration for constants set manually during deploy. Does not get written to after deploys.
struct ChainConfig {
/// @notice The user that owns the factory proxy. Allows ability to upgrade for new implementations deployed.
address factoryOwner;
/// @notice The user that owns the factory upgrade gate. This contract gates what existing deployed impls can upgrade to.
address factoryUpgradeGateOwner;
/// @notice Mint fee amount in WEI charged for each mint
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 Deployment addresses – set to new deployed addresses by the scripts.
struct DropDeployment {
/// @notice Metadata renderer for drop style contracts
address dropMetadata;
/// @notice Metadata renderer for edition style contracts
address editionMetadata;
/// @notice Implementation contract for the drop contract
address dropImplementation;
/// @notice Factory upgrade gate immutable registry for allowing upgrades
address factoryUpgradeGate;
/// @notice Factory proxy contract that creates zora drops style NFT contracts
address factory;
/// @notice Factory implementation contract that is the impl for the above proxy.
address factoryImpl;
}

/// @notice Deployment drops for base where
abstract contract ZoraDropsDeployBase is Script {
using stdJson for string;

/// @notice ChainID convenience getter
/// @return id chainId
function chainId() internal view returns (uint256 id) {
assembly {
id := chainid()
}
}

/// @notice File used for demo metadata on verification test mint
string constant DEMO_IPFS_METADATA_FILE = "ipfs://bafkreigu544g6wjvqcysurpzy5pcskbt45a5f33m6wgythpgb3rfqi3lzi";

///
// These are the JSON key constants to standardize writing and reading configuration
///

string constant FACTORY_OWNER = "FACTORY_OWNER";
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 DROP_METADATA_RENDERER = "DROP_METADATA_RENDERER";
string constant EDITION_METADATA_RENDERER = "EDITION_METADATA_RENDERER";
string constant ERC721DROP_IMPL = "ERC721DROP_IMPL";
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";

/// @notice Return a prefixed key for reading with a ".".
/// @param key key to prefix
/// @return prefixed key
function getKeyPrefix(string memory key) internal pure returns (string memory) {
return string.concat(".", key);
}

/// @notice Returns the chain configuration struct from the JSON configuration file
/// @return chainConfig structure
function getChainConfig() internal returns (ChainConfig memory chainConfig) {
string memory json = vm.readFile(string.concat("chainConfigs/", Strings.toString(chainId()), ".json"));
chainConfig.factoryOwner = json.readAddress(getKeyPrefix(FACTORY_OWNER));
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.subscriptionMarketFilterOwner = json.readAddress(getKeyPrefix(SUBSCRIPTION_MARKET_FILTER_OWNER));
chainConfig.zoraERC721TransferHelper = json.readAddress(getKeyPrefix(ZORA_ERC721_TRANSFER_HELPER));
}

/// @notice Get the deployment configuration struct from the JSON configuration file
/// @return dropDeployment deployment configuration structure
function getDeployment() internal returns (DropDeployment memory dropDeployment) {
string memory json = vm.readFile(string.concat("addresses/", Strings.toString(chainId()), ".json"));
dropDeployment.dropMetadata = json.readAddress(getKeyPrefix(DROP_METADATA_RENDERER));
dropDeployment.editionMetadata = json.readAddress(getKeyPrefix(EDITION_METADATA_RENDERER));
dropDeployment.dropImplementation = json.readAddress(getKeyPrefix(ERC721DROP_IMPL));
dropDeployment.factoryUpgradeGate = json.readAddress(getKeyPrefix(FACTORY_UPGRADE_GATE));
dropDeployment.factory = json.readAddress(getKeyPrefix(ZORA_NFT_CREATOR_PROXY));
dropDeployment.factoryImpl = json.readAddress(getKeyPrefix(ZORA_NFT_CREATOR_V1_IMPL));
}
abstract contract ZoraDropsDeployBase is ScriptDeploymentConfig {

/// @notice Get deployment configuration struct as JSON
/// @param deployment deploymet struct
Expand Down
119 changes: 119 additions & 0 deletions src/DeploymentConfig.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ZoraNFTCreatorV1} from "../src/ZoraNFTCreatorV1.sol";
import {IERC721Drop} from "../src/interfaces/IERC721Drop.sol";

/// @notice Chain configuration for constants set manually during deploy. Does not get written to after deploys.
struct ChainConfig {
/// @notice The user that owns the factory proxy. Allows ability to upgrade for new implementations deployed.
address factoryOwner;
/// @notice The user that owns the factory upgrade gate. This contract gates what existing deployed impls can upgrade to.
address factoryUpgradeGateOwner;
/// @notice Mint fee amount in WEI charged for each mint
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 Deployment addresses – set to new deployed addresses by the scripts.
struct DropDeployment {
/// @notice Metadata renderer for drop style contracts
address dropMetadata;
/// @notice Metadata renderer for edition style contracts
address editionMetadata;
/// @notice Implementation contract for the drop contract
address dropImplementation;
/// @notice Factory upgrade gate immutable registry for allowing upgrades
address factoryUpgradeGate;
/// @notice Factory proxy contract that creates zora drops style NFT contracts
address factory;
/// @notice Factory implementation contract that is the impl for the above proxy.
address factoryImpl;
}

/// @notice Deployment drops for base where
abstract contract DeploymentConfig is StdChains, StdCheatsSafe, StdUtils, ScriptBase {
using stdJson for string;

/// @notice ChainID convenience getter
/// @return id chainId
function chainId() internal view virtual returns (uint256 id);

/// @notice File used for demo metadata on verification test mint
string constant DEMO_IPFS_METADATA_FILE = "ipfs://bafkreigu544g6wjvqcysurpzy5pcskbt45a5f33m6wgythpgb3rfqi3lzi";

///
// These are the JSON key constants to standardize writing and reading configuration
///

string constant FACTORY_OWNER = "FACTORY_OWNER";
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 DROP_METADATA_RENDERER = "DROP_METADATA_RENDERER";
string constant EDITION_METADATA_RENDERER = "EDITION_METADATA_RENDERER";
string constant ERC721DROP_IMPL = "ERC721DROP_IMPL";
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";

/// @notice Return a prefixed key for reading with a ".".
/// @param key key to prefix
/// @return prefixed key
function getKeyPrefix(string memory key) internal pure returns (string memory) {
return string.concat(".", key);
}

/// @notice Returns the chain configuration struct from the JSON configuration file
/// @return chainConfig structure
function getChainConfig() internal view returns (ChainConfig memory chainConfig) {
string memory json = vm.readFile(string.concat("chainConfigs/", Strings.toString(chainId()), ".json"));
chainConfig.factoryOwner = json.readAddress(getKeyPrefix(FACTORY_OWNER));
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.subscriptionMarketFilterOwner = json.readAddress(getKeyPrefix(SUBSCRIPTION_MARKET_FILTER_OWNER));
chainConfig.zoraERC721TransferHelper = json.readAddress(getKeyPrefix(ZORA_ERC721_TRANSFER_HELPER));
}

/// @notice Get the deployment configuration struct from the JSON configuration file
/// @return dropDeployment deployment configuration structure
function getDeployment() internal view returns (DropDeployment memory dropDeployment) {
string memory json = vm.readFile(string.concat("addresses/", Strings.toString(chainId()), ".json"));
dropDeployment.dropMetadata = json.readAddress(getKeyPrefix(DROP_METADATA_RENDERER));
dropDeployment.editionMetadata = json.readAddress(getKeyPrefix(EDITION_METADATA_RENDERER));
dropDeployment.dropImplementation = json.readAddress(getKeyPrefix(ERC721DROP_IMPL));
dropDeployment.factoryUpgradeGate = json.readAddress(getKeyPrefix(FACTORY_UPGRADE_GATE));
dropDeployment.factory = json.readAddress(getKeyPrefix(ZORA_NFT_CREATOR_PROXY));
dropDeployment.factoryImpl = json.readAddress(getKeyPrefix(ZORA_NFT_CREATOR_V1_IMPL));
}

}

contract ForkDeploymentConfig is DeploymentConfig {
function chainId() internal view override returns (uint256 id) {
return block.chainid;
}
}

contract ScriptDeploymentConfig is DeploymentConfig {
function chainId() internal view override returns (uint256 id) {
assembly {
id := chainid()
}
}
}
4 changes: 4 additions & 0 deletions test/ZoraNFTCreatorV1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import "../src/ZoraNFTCreatorProxy.sol";
import {MockMetadataRenderer} from "./metadata/MockMetadataRenderer.sol";
import {FactoryUpgradeGate} from "../src/FactoryUpgradeGate.sol";
import {IERC721AUpgradeable} from "erc721a-upgradeable/IERC721AUpgradeable.sol";
import {ForkHelper} from "./utils/ForkHelper.sol";
import {DropDeployment , ChainConfig} from "../src/DeploymentConfig.sol";

contract ZoraNFTCreatorV1Test is Test {
address public constant DEFAULT_OWNER_ADDRESS = address(0x23499);
Expand Down Expand Up @@ -146,4 +148,6 @@ contract ZoraNFTCreatorV1Test is Test {
drop.purchase{value: fee}(1);
assertEq(drop.tokenURI(1), "DEMO");
}


}
Loading

0 comments on commit badbe63

Please sign in to comment.