diff --git a/.storage-layout b/.storage-layout index b35d8519c..6859a1da5 100644 --- a/.storage-layout +++ b/.storage-layout @@ -33,6 +33,7 @@ | permissions | mapping(uint256 => mapping(address => uint256)) | 510 | 0 | 32 | src/nft/ZoraCreator1155Impl.sol:ZoraCreator1155Impl | | __gap | uint256[50] | 511 | 0 | 1600 | src/nft/ZoraCreator1155Impl.sol:ZoraCreator1155Impl | | createReferrals | mapping(uint256 => address) | 561 | 0 | 32 | src/nft/ZoraCreator1155Impl.sol:ZoraCreator1155Impl | +| delegatedTokenId | mapping(uint32 => uint256) | 562 | 0 | 32 | src/nft/ZoraCreator1155Impl.sol:ZoraCreator1155Impl | ======================= ➡ ZoraCreator1155FactoryImpl diff --git a/package.json b/package.json index a2b31da78..b56769811 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@zoralabs/openzeppelin-contracts-upgradeable": "4.8.4", "@zoralabs/protocol-rewards": "1.1.2", "ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b", - "forge-std": "https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653", + "forge-std": "https://github.com/foundry-rs/forge-std#705263c95892a906d7af65f0f73ce8a4a0c80b80", "solmate": "^6.1.0" }, "devDependencies": { diff --git a/src/deployment/DeploymentConfig.sol b/src/deployment/DeploymentConfig.sol index c43a12077..e71baeae9 100644 --- a/src/deployment/DeploymentConfig.sol +++ b/src/deployment/DeploymentConfig.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.17; import "forge-std/Test.sol"; +import {CommonBase} from "forge-std/Base.sol"; import {MintFeeManager} from "../../src/fee/MintFeeManager.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; @@ -76,17 +77,27 @@ abstract contract DeploymentConfig is CommonBase { chainConfig.protocolRewards = json.readAddress(getKeyPrefix(PROTOCOL_REWARDS)); } + function readAddressOrDefaultToZero(string memory json, string memory key) internal view returns (address addr) { + string memory keyPrefix = getKeyPrefix(key); + + if (vm.keyExists(json, keyPrefix)) { + addr = json.readAddress(keyPrefix); + } else { + addr = address(0); + } + } + /// @notice Get the deployment configuration struct from the JSON configuration file /// @return deployment deployment configuration structure function getDeployment() internal view returns (Deployment memory deployment) { string memory json = vm.readFile(string.concat("addresses/", Strings.toString(chainId()), ".json")); - deployment.fixedPriceSaleStrategy = json.readAddress(getKeyPrefix(FIXED_PRICE_SALE_STRATEGY)); - deployment.merkleMintSaleStrategy = json.readAddress(getKeyPrefix(MERKLE_MINT_SALE_STRATEGY)); - deployment.redeemMinterFactory = json.readAddress(getKeyPrefix(REDEEM_MINTER_FACTORY)); - deployment.contract1155Impl = json.readAddress(getKeyPrefix(CONTRACT_1155_IMPL)); - deployment.factoryImpl = json.readAddress(getKeyPrefix(FACTORY_IMPL)); - deployment.factoryProxy = json.readAddress(getKeyPrefix(FACTORY_PROXY)); - deployment.preminter = json.readAddress(getKeyPrefix(PREMINTER)); + deployment.fixedPriceSaleStrategy = readAddressOrDefaultToZero(json, FIXED_PRICE_SALE_STRATEGY); + deployment.merkleMintSaleStrategy = readAddressOrDefaultToZero(json, MERKLE_MINT_SALE_STRATEGY); + deployment.redeemMinterFactory = readAddressOrDefaultToZero(json, REDEEM_MINTER_FACTORY); + deployment.contract1155Impl = readAddressOrDefaultToZero(json, CONTRACT_1155_IMPL); + deployment.factoryImpl = readAddressOrDefaultToZero(json, FACTORY_IMPL); + deployment.factoryProxy = readAddressOrDefaultToZero(json, FACTORY_PROXY); + deployment.preminter = readAddressOrDefaultToZero(json, PREMINTER); } } diff --git a/src/interfaces/ICreatorPermissionControl.sol b/src/interfaces/ICreatorPermissionControl.sol index 73be76c31..72a8a36cf 100644 --- a/src/interfaces/ICreatorPermissionControl.sol +++ b/src/interfaces/ICreatorPermissionControl.sol @@ -5,8 +5,4 @@ pragma solidity 0.8.17; interface ICreatorPermissionControl { /// @notice Emitted when permissions are updated event UpdatedPermissions(uint256 indexed tokenId, address indexed user, uint256 indexed permissions); - - /// @notice Public interface to get permissions given a token id and a user address - /// @return Returns raw permission bits - function getPermissions(uint256 tokenId, address user) external view returns (uint256); } diff --git a/src/permissions/CreatorPermissionControl.sol b/src/permissions/CreatorPermissionControl.sol index 55cc10da0..2d4353b87 100644 --- a/src/permissions/CreatorPermissionControl.sol +++ b/src/permissions/CreatorPermissionControl.sol @@ -7,14 +7,6 @@ import {ICreatorPermissionControl} from "../interfaces/ICreatorPermissionControl /// Imagine. Mint. Enjoy. /// @author @iainnash / @tbtstl contract CreatorPermissionControl is CreatorPermissionStorageV1, ICreatorPermissionControl { - /// @notice Check if the user has the given permissions - /// @dev if multiple permissions are passed in this checks for all the permissions requested - /// @return true or false if all of the passed in permissions apply - function _hasPermissions(uint256 tokenId, address user, uint256 permissionBits) internal view returns (bool) { - // Does a bitwise and and checks if any of those permissions match - return permissions[tokenId][user] & permissionBits == permissionBits; - } - /// @notice Check if the user has any of the given permissions /// @dev if multiple permissions are passed in this checks for any one of those permissions /// @return true or false if any of the passed in permissions apply @@ -23,11 +15,6 @@ contract CreatorPermissionControl is CreatorPermissionStorageV1, ICreatorPermiss return permissions[tokenId][user] & permissionBits > 0; } - /// @return raw permission bits for the given user - function getPermissions(uint256 tokenId, address user) external view returns (uint256) { - return permissions[tokenId][user]; - } - /// @notice addPermission – internal function to add a set of permission bits to a user /// @param tokenId token id to add the permission to (0 indicates contract-wide add) /// @param user user to update permissions for diff --git a/test/factory/ZoraCreator1155Factory.t.sol b/test/factory/ZoraCreator1155Factory.t.sol index 99564ce7b..8e79b0584 100644 --- a/test/factory/ZoraCreator1155Factory.t.sol +++ b/test/factory/ZoraCreator1155Factory.t.sol @@ -103,7 +103,7 @@ contract ZoraCreator1155FactoryTest is Test { assertEq(config.royaltyMintSchedule, royaltyMintSchedule); assertEq(config.royaltyBPS, royaltyBPS); assertEq(config.royaltyRecipient, royaltyRecipient); - assertEq(target.getPermissions(0, admin), target.PERMISSION_BIT_ADMIN()); + assertEq(target.permissions(0, admin), target.PERMISSION_BIT_ADMIN()); assertEq(target.uri(1), "ipfs://asdfadsf"); } diff --git a/test/mock/MockPermissionControl.sol b/test/mock/MockPermissionControl.sol index 4974a8e65..9353e68d5 100644 --- a/test/mock/MockPermissionControl.sol +++ b/test/mock/MockPermissionControl.sol @@ -4,14 +4,6 @@ pragma solidity 0.8.17; import {CreatorPermissionControl} from "../../src/permissions/CreatorPermissionControl.sol"; contract MockPermissionControl is CreatorPermissionControl { - function hasPermissions(uint256 tokenId, address user, uint256 permissionBits) external view returns (bool) { - return _hasPermissions(tokenId, user, permissionBits); - } - - function hasAnyPermission(uint256 tokenId, address user, uint256 permissionBits) external view returns (bool) { - return _hasAnyPermission(tokenId, user, permissionBits); - } - function addPermission(uint256 tokenId, address user, uint256 permissionBits) external { _addPermission(tokenId, user, permissionBits); } diff --git a/test/nft/ZoraCreator1155.t.sol b/test/nft/ZoraCreator1155.t.sol index b865f4a3b..26f2538d6 100644 --- a/test/nft/ZoraCreator1155.t.sol +++ b/test/nft/ZoraCreator1155.t.sol @@ -274,7 +274,7 @@ contract ZoraCreator1155Test is Test { vm.prank(admin); target.addPermission(tokenId, user, permission); - assertEq(target.getPermissions(tokenId, user), permission); + assertEq(target.permissions(tokenId, user), permission); } function test_addPermission_revertOnlyAdminOrRole(uint256 tokenId) external { @@ -299,7 +299,7 @@ contract ZoraCreator1155Test is Test { vm.prank(admin); target.removePermission(tokenId, user, permission); - assertEq(target.getPermissions(tokenId, user), 0); + assertEq(target.permissions(tokenId, user), 0); } function test_removePermissionRevokeOwnership() external { diff --git a/test/permissions/CreatorPermissionControl.t.sol b/test/permissions/CreatorPermissionControl.t.sol index 5db41bbd8..d83548f5f 100644 --- a/test/permissions/CreatorPermissionControl.t.sol +++ b/test/permissions/CreatorPermissionControl.t.sol @@ -12,38 +12,40 @@ contract CreatorPermissionControlTest is Test { } function test_showsNoPermission(uint256 tokenId, address user, uint256 permissionBits) public { - assertFalse(creatorPermissions.hasAnyPermission(tokenId, user, permissionBits)); + bool hasAnyPermission = creatorPermissions.permissions(tokenId, user) & permissionBits > 0; + assertFalse(hasAnyPermission); } function test_addPermissions(uint256 tokenId, address user) public { creatorPermissions.addPermission(tokenId, user, 0x1); creatorPermissions.addPermission(tokenId, user, 0x2); - assertEq(creatorPermissions.getPermissions(tokenId, user), 0x3); + assertEq(creatorPermissions.permissions(tokenId, user), 0x3); } function test_addPermissionOtherExists(uint256 tokenId, address user, uint256 id) public { vm.assume(id != 0x1); vm.assume(id != 0x0); creatorPermissions.addPermission(tokenId, user, 0x1); - assertFalse(creatorPermissions.hasPermissions(tokenId, user, id)); + bool hasPermission = creatorPermissions.permissions(tokenId, user) & id == id; + assertFalse(hasPermission); } function test_hasAllPermissions(uint256 tokenId, address user) public { creatorPermissions.addPermission(tokenId, user, type(uint256).max); - assertEq(creatorPermissions.getPermissions(tokenId, user), type(uint256).max); + assertEq(creatorPermissions.permissions(tokenId, user), type(uint256).max); } function test_clearPermissions(uint256 tokenId, address user) public { creatorPermissions.addPermission(tokenId, user, type(uint256).max); - assertEq(creatorPermissions.getPermissions(tokenId, user), type(uint256).max); + assertEq(creatorPermissions.permissions(tokenId, user), type(uint256).max); creatorPermissions.clearPermissions(tokenId, user); - assertEq(creatorPermissions.getPermissions(tokenId, user), 0); + assertEq(creatorPermissions.permissions(tokenId, user), 0); } function test_removePermission(uint256 tokenId, address user) public { creatorPermissions.addPermission(tokenId, user, type(uint256).max); - assertEq(creatorPermissions.getPermissions(tokenId, user), type(uint256).max); + assertEq(creatorPermissions.permissions(tokenId, user), type(uint256).max); creatorPermissions.clearPermissions(tokenId, user); - assertEq(creatorPermissions.getPermissions(tokenId, user), 0); + assertEq(creatorPermissions.permissions(tokenId, user), 0); } } diff --git a/test/premint/ZoraCreator1155Preminter.t.sol b/test/premint/ZoraCreator1155Preminter.t.sol index f23d941aa..e194e3ee8 100644 --- a/test/premint/ZoraCreator1155Preminter.t.sol +++ b/test/premint/ZoraCreator1155Preminter.t.sol @@ -168,10 +168,6 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { } function testTheForkPremint(string memory chainName) private { - if (keccak256(abi.encodePacked(chainName)) != keccak256(abi.encodePacked("zora_goerli"))) { - return; - } - console.log("testing on fork: ", chainName); // create and select the fork, which will be used for all subsequent calls @@ -180,7 +176,15 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { // get contract hash, which is unique per contract creation config, and can be used // retreive the address created for a contract - preminter = ZoraCreator1155PremintExecutor(getDeployment().preminter); + address preminterAddress = getDeployment().preminter; + + if (preminterAddress == address(0)) { + console.log("preminter not configured for chain...skipping"); + return; + } + + preminter = ZoraCreator1155PremintExecutor(preminterAddress); + factoryImpl = ZoraCreator1155FactoryImpl(getDeployment().factoryImpl); console.log("building defaults"); @@ -198,8 +202,6 @@ contract ZoraCreator1155PreminterTest is ForkDeploymentConfig, Test { address contractAddress = preminter.getContractAddress(contractConfig); - console.log(contractAddress); - // 2. Call smart contract to get digest to sign for creation params. bytes32 digest = ZoraCreator1155Attribution.premintHashedTypeDataV4(premintConfig, contractAddress, chainId); diff --git a/yarn.lock b/yarn.lock index 27ebce858..814d325d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1823,9 +1823,9 @@ foreground-child@^3.1.0: cross-spawn "^7.0.0" signal-exit "^4.0.1" -"forge-std@https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653": - version "1.1.1" - resolved "https://github.com/foundry-rs/forge-std#cd7d533f9a0ee0ec02ad81e0a8f262bc4203c653" +"forge-std@https://github.com/foundry-rs/forge-std#705263c95892a906d7af65f0f73ce8a4a0c80b80": + version "1.6.0" + resolved "https://github.com/foundry-rs/forge-std#705263c95892a906d7af65f0f73ce8a4a0c80b80" formdata-polyfill@^4.0.10: version "4.0.10"