From 942b6f8ecc9e2a22409065e8ad2fe417b40b053c Mon Sep 17 00:00:00 2001 From: "Michael D. Norman" Date: Sun, 8 May 2022 21:22:45 -0500 Subject: [PATCH] chore: [#1] Removed temporary mint function --- contracts/ParcelNFT.sol | 5 - .../allowListClaim/allowListClaim.spec.ts | 17 +-- test/contracts/erc721/erc721.ts | 102 ++++++++++-------- test/contracts/erc721/tokenURI.spec.ts | 68 ++++++++---- .../helpers/contracts/AllowListClaimHelper.ts | 11 ++ 5 files changed, 121 insertions(+), 82 deletions(-) create mode 100644 test/helpers/contracts/AllowListClaimHelper.ts diff --git a/contracts/ParcelNFT.sol b/contracts/ParcelNFT.sol index 0971e4f..60658e6 100644 --- a/contracts/ParcelNFT.sol +++ b/contracts/ParcelNFT.sol @@ -91,11 +91,6 @@ contract ParcelNFT is _setupRole(Roles.SUPER_ADMIN, initParams.superAdmin); } - // todo: temporary until minting is supported - function mint(uint256 tokenId) external onlyRole(Roles.PARCEL_MANAGER) { - _safeMint(_msgSender(), tokenId); - } - /** * @notice Attempts to mint the given amount of tokens to the given account. */ diff --git a/test/contracts/allowListClaim/allowListClaim.spec.ts b/test/contracts/allowListClaim/allowListClaim.spec.ts index 40bd0bd..dd6344a 100644 --- a/test/contracts/allowListClaim/allowListClaim.spec.ts +++ b/test/contracts/allowListClaim/allowListClaim.spec.ts @@ -1,16 +1,11 @@ import { expect } from 'chai'; import { BigNumber } from 'ethers'; -import { DateTime } from 'luxon'; import { ZERO_ADDRESS } from '../../../src/constants/accounts'; import { PARCEL_MANAGER_ROLE } from '../../../src/constants/roles'; -import { - buildMerkleTreeForAllowList, - convertToClaimPeriodTimestamp, - getMerkleProof, -} from '../../../src/contracts/AllowListClaim'; +import { buildMerkleTreeForAllowList, getMerkleProof } from '../../../src/contracts/AllowListClaim'; import { toByte32String } from '../../../src/utils/fixedBytes'; -import { ParcelNFT } from '../../../types/contracts'; import { INITIALIZER, USER1, USER2, USER3 } from '../../helpers/Accounts'; +import { setValidClaimPeriod } from '../../helpers/contracts/AllowListClaimHelper'; import { createParcelNFT } from '../../helpers/contracts/ParcelNFTHelper'; describe('setMerkleRoot', () => { @@ -361,11 +356,3 @@ describe('allowListMint', () => { ).to.be.lt(400000); }); }); - -const setValidClaimPeriod = async (parcelNFT: ParcelNFT) => { - const now = DateTime.now(); - await parcelNFT.setClaimPeriod( - convertToClaimPeriodTimestamp(now), - convertToClaimPeriodTimestamp(now.plus({ hour: 1 })), - ); -}; diff --git a/test/contracts/erc721/erc721.ts b/test/contracts/erc721/erc721.ts index 2226aa1..87259d1 100644 --- a/test/contracts/erc721/erc721.ts +++ b/test/contracts/erc721/erc721.ts @@ -5,7 +5,9 @@ import { ERC721_METADATA_INTERFACE_ID, } from '../../../src/constants/interfaces'; import { PARCEL_MANAGER_ROLE } from '../../../src/constants/roles'; -import { USER1, USER2 } from '../../helpers/Accounts'; +import { buildMerkleTreeForAllowList, getMerkleProof } from '../../../src/contracts/AllowListClaim'; +import { INITIALIZER, USER1, USER2 } from '../../helpers/Accounts'; +import { setValidClaimPeriod } from '../../helpers/contracts/AllowListClaimHelper'; import { createParcelNFT } from '../../helpers/contracts/ParcelNFTHelper'; import { shouldSupportInterface } from '../../helpers/ERC165Helper'; @@ -21,17 +23,20 @@ describe('ERC721Enumerable', () => { describe('totalSupply', () => { it('should return the totalSupply', async () => { const parcelNFT = await createParcelNFT(); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER2.address); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); + + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); expect(await parcelNFT.totalSupply()).to.eq(0); - await parcelNFT.connect(USER1).mint(100); + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); expect(await parcelNFT.totalSupply()).to.eq(1); - await parcelNFT.connect(USER1).mint(101); - await parcelNFT.connect(USER2).mint(102); - await parcelNFT.connect(USER1).mint(103); + await parcelNFT.connect(USER1).allowListMint(2, 10, getMerkleProof(USER1.address, 10, merkleTree)); + await parcelNFT.connect(USER2).allowListMint(1, 10, getMerkleProof(USER2.address, 10, merkleTree)); expect(await parcelNFT.totalSupply()).to.eq(4); }); }); @@ -39,44 +44,50 @@ describe('ERC721Enumerable', () => { describe('tokenOfOwnerByIndex', () => { it('should return the token at the given index for the given user', async () => { const parcelNFT = await createParcelNFT(); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER2.address); - - await parcelNFT.connect(USER1).mint(100); - expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(100); - - await parcelNFT.connect(USER2).mint(101); - expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(100); - expect(await parcelNFT.tokenOfOwnerByIndex(USER2.address, 0)).to.eq(101); - - await parcelNFT.connect(USER1).mint(102); - await parcelNFT.connect(USER1).mint(103); - expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(100); - expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 1)).to.eq(102); - expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 2)).to.eq(103); - expect(await parcelNFT.tokenOfOwnerByIndex(USER2.address, 0)).to.eq(101); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); + + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); + + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); + expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(1); + + await parcelNFT.connect(USER2).allowListMint(1, 10, getMerkleProof(USER2.address, 10, merkleTree)); + expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(1); + expect(await parcelNFT.tokenOfOwnerByIndex(USER2.address, 0)).to.eq(2); + + await parcelNFT.connect(USER1).allowListMint(2, 10, getMerkleProof(USER1.address, 10, merkleTree)); + expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 0)).to.eq(1); + expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 1)).to.eq(3); + expect(await parcelNFT.tokenOfOwnerByIndex(USER1.address, 2)).to.eq(4); + expect(await parcelNFT.tokenOfOwnerByIndex(USER2.address, 0)).to.eq(2); }); }); describe('tokenByIndex', () => { it('should return the token at the given index', async () => { const parcelNFT = await createParcelNFT(); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER2.address); - - await parcelNFT.connect(USER1).mint(100); - expect(await parcelNFT.tokenByIndex(0)).to.eq(100); - - await parcelNFT.connect(USER2).mint(101); - expect(await parcelNFT.tokenByIndex(0)).to.eq(100); - expect(await parcelNFT.tokenByIndex(1)).to.eq(101); - - await parcelNFT.connect(USER1).mint(102); - await parcelNFT.connect(USER1).mint(103); - expect(await parcelNFT.tokenByIndex(0)).to.eq(100); - expect(await parcelNFT.tokenByIndex(1)).to.eq(101); - expect(await parcelNFT.tokenByIndex(2)).to.eq(102); - expect(await parcelNFT.tokenByIndex(3)).to.eq(103); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); + + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); + + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); + expect(await parcelNFT.tokenByIndex(0)).to.eq(1); + + await parcelNFT.connect(USER2).allowListMint(1, 10, getMerkleProof(USER2.address, 10, merkleTree)); + expect(await parcelNFT.tokenByIndex(0)).to.eq(1); + expect(await parcelNFT.tokenByIndex(1)).to.eq(2); + + await parcelNFT.connect(USER1).allowListMint(2, 10, getMerkleProof(USER1.address, 10, merkleTree)); + expect(await parcelNFT.tokenByIndex(0)).to.eq(1); + expect(await parcelNFT.tokenByIndex(1)).to.eq(2); + expect(await parcelNFT.tokenByIndex(2)).to.eq(3); + expect(await parcelNFT.tokenByIndex(3)).to.eq(4); }); }); }); @@ -99,12 +110,17 @@ describe('ERC721Metadata', () => { describe('tokenURI', () => { it('should return the token URI', async () => { const parcelNFT = await createParcelNFT(); - await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); + + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); - await parcelNFT.connect(USER1).mint(100); + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); - await parcelNFT.connect(USER1).setBaseURI('https://the.base.uri/'); - expect(await parcelNFT.tokenURI(100)).to.eq('https://the.base.uri/100'); + await parcelNFT.setBaseURI('https://the.base.uri/'); + expect(await parcelNFT.tokenURI(1)).to.eq('https://the.base.uri/1'); }); }); }); diff --git a/test/contracts/erc721/tokenURI.spec.ts b/test/contracts/erc721/tokenURI.spec.ts index 16a0495..0c4ac61 100644 --- a/test/contracts/erc721/tokenURI.spec.ts +++ b/test/contracts/erc721/tokenURI.spec.ts @@ -1,58 +1,82 @@ import { expect } from 'chai'; import { PARCEL_MANAGER_ROLE } from '../../../src/constants/roles'; -import { INITIALIZER, USER1 } from '../../helpers/Accounts'; +import { buildMerkleTreeForAllowList, getMerkleProof } from '../../../src/contracts/AllowListClaim'; +import { INITIALIZER, USER1, USER2 } from '../../helpers/Accounts'; +import { setValidClaimPeriod } from '../../helpers/contracts/AllowListClaimHelper'; import { createParcelNFT } from '../../helpers/contracts/ParcelNFTHelper'; describe('setBaseURI', () => { it('should set baseURI', async () => { const parcelNFT = await createParcelNFT(); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.connect(USER1).mint(100); + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); - expect(await parcelNFT.tokenURI(100)).to.eq(''); + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); + + expect(await parcelNFT.tokenURI(1)).to.eq(''); await parcelNFT.connect(USER1).setBaseURI('the-base/'); expect(await parcelNFT.baseURI()).to.eq('the-base/'); - expect(await parcelNFT.tokenURI(100)).to.eq('the-base/100'); + expect(await parcelNFT.tokenURI(1)).to.eq('the-base/1'); }); it('should fail if not called with parcel manager', async () => { const parcelNFT = await createParcelNFT(); await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); - await parcelNFT.mint(100); + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); + + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); expect(parcelNFT.connect(USER1).setBaseURI('the-base/')).to.be.revertedWith('missing role'); - expect(await parcelNFT.tokenURI(100)).to.eq(''); + expect(await parcelNFT.tokenURI(1)).to.eq(''); }); }); describe('setTokenURI', () => { it('should set the individual token uri', async () => { const parcelNFT = await createParcelNFT(); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.connect(USER1).mint(100); + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); - expect(await parcelNFT.tokenURI(100)).to.eq(''); + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); - await parcelNFT.connect(USER1).setTokenURI(100, 'the-best-token'); + expect(await parcelNFT.tokenURI(1)).to.eq(''); - expect(await parcelNFT.tokenURI(100)).to.eq('the-best-token'); + await parcelNFT.connect(USER1).setTokenURI(1, 'the-best-token'); + + expect(await parcelNFT.tokenURI(1)).to.eq('the-best-token'); }); it('should fail if not called with parcel manager', async () => { const parcelNFT = await createParcelNFT(); await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); - await parcelNFT.mint(100); + await setValidClaimPeriod(parcelNFT); - expect(parcelNFT.connect(USER1).setTokenURI(100, 'the-best-token')).to.be.revertedWith('missing role'); + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); + + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); + + expect(parcelNFT.connect(USER1).setTokenURI(1, 'the-best-token')).to.be.revertedWith('missing role'); - expect(await parcelNFT.tokenURI(100)).to.eq(''); + expect(await parcelNFT.tokenURI(1)).to.eq(''); }); it('should fail if called with an invalid tokenId', async () => { @@ -66,17 +90,23 @@ describe('setTokenURI', () => { describe('tokenURI', () => { it('should return the concatenated uri when both are set', async () => { const parcelNFT = await createParcelNFT(); + await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, INITIALIZER.address); await parcelNFT.grantRole(PARCEL_MANAGER_ROLE, USER1.address); - await parcelNFT.connect(USER1).mint(100); - await parcelNFT.connect(USER1).mint(101); + await setValidClaimPeriod(parcelNFT); + + const merkleTree = buildMerkleTreeForAllowList({ [USER1.address]: 10, [USER2.address]: 10 }); + await parcelNFT.setMerkleRoot(merkleTree.getHexRoot()); + + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); + await parcelNFT.connect(USER1).allowListMint(1, 10, getMerkleProof(USER1.address, 10, merkleTree)); - expect(await parcelNFT.tokenURI(100)).to.eq(''); + expect(await parcelNFT.tokenURI(1)).to.eq(''); await parcelNFT.connect(USER1).setBaseURI('the-base/'); - await parcelNFT.connect(USER1).setTokenURI(100, 'the-best-token'); + await parcelNFT.connect(USER1).setTokenURI(1, 'the-best-token'); - expect(await parcelNFT.tokenURI(100)).to.eq('the-base/the-best-token'); - expect(await parcelNFT.tokenURI(101)).to.eq('the-base/101'); + expect(await parcelNFT.tokenURI(1)).to.eq('the-base/the-best-token'); + expect(await parcelNFT.tokenURI(2)).to.eq('the-base/2'); }); }); diff --git a/test/helpers/contracts/AllowListClaimHelper.ts b/test/helpers/contracts/AllowListClaimHelper.ts new file mode 100644 index 0000000..80b27cf --- /dev/null +++ b/test/helpers/contracts/AllowListClaimHelper.ts @@ -0,0 +1,11 @@ +import { DateTime } from 'luxon'; +import { convertToClaimPeriodTimestamp } from '../../../src/contracts/AllowListClaim'; +import { ParcelNFT } from '../../../types/contracts'; + +export const setValidClaimPeriod = async (parcelNFT: ParcelNFT) => { + const now = DateTime.now(); + await parcelNFT.setClaimPeriod( + convertToClaimPeriodTimestamp(now), + convertToClaimPeriodTimestamp(now.plus({ hour: 1 })), + ); +};