import { expect } from 'chai' import hre from "hardhat"; import { getBytes, solidityPackedKeccak256, } from 'ethers' import { loadFixture, } from "@nomicfoundation/hardhat-toolbox/network-helpers"; describe('NFTClaimStage2WL', function() { async function deployOneContract() { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await hre.ethers.getSigners(); const verifier = owner.address; const OperatorAllowlist = await hre.ethers.getContractFactory("OperatorAllowlist"); const operatorAllowlist = await OperatorAllowlist.deploy(owner.address); const CFFT = await hre.ethers.getContractFactory("ImmutableERC20MinterBurnerPermit"); const ft = await CFFT.deploy(owner.address, owner.address, owner.address, "test usdc", "usdc", '100000000000000000000000000'); await ft.grantMinterRole(owner.address); await ft.mint(otherAccount.address, '1000'); const CFNFTGame = await hre.ethers.getContractFactory("CFNFTGame"); const nft = await CFNFTGame.deploy(owner.address, 'name', 'symbol', 'baseURI', 'contractURI', operatorAllowlist.target, owner.address, 5); const nftAddress = nft.target; const NFTClaimStage2 = await hre.ethers.getContractFactory("NFTClaimStage2WL"); const mintConfig = [ 2000, ft.target, 100, owner.address ] const nftClaimer = await NFTClaimStage2.deploy( nftAddress, '6240603010000001', mintConfig); await nft.grantMinterRole(nftClaimer.target) await nftClaimer.addParse1WL([otherAccount.address], [3]) const chainId = hre.network.config.chainId return { nftClaimer, owner, otherAccount, verifier, nftAddress, ft, nft, chainId }; } describe("Deployment", function () { it('should deploy NFTClaimStage2', async function() { const { nftClaimer, otherAccount } = await loadFixture(deployOneContract); expect((await nftClaimer.mintConfig()).mintPrice).to.equal(100); // @ts-ignore expect((await nftClaimer.connect(otherAccount).whiteCount())).to.equal(3); }); it('should deploy NFTClaimStage2 with the correct NFT address', async function() { const { nftClaimer, nftAddress } = await loadFixture(deployOneContract); expect(await nftClaimer.nftAddress()).to.equal(nftAddress); }); }) describe("update settings", function () { it('should update mintConfig', async function() { const { nftClaimer } = await loadFixture(deployOneContract); const mintConfig = [ 2000, '0xaa34B79A0Ab433eaC900fB3CB9f191F5Cd27501D', 200, '0x5Ab03Aa79Ab91B7420b5CFF134a4188388888888' ] await nftClaimer.updateMintConfig(mintConfig); expect((await nftClaimer.mintConfig()).mintPrice).to.equal(200); }); it('should update parse', async function() { const { nftClaimer } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); expect(await nftClaimer.mintParse()).to.equal(1); }); }); describe("claim", function () { it('should claim NFT', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); //use ft.connect() to send a transaction from another account // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, 200) expect(await nftClaimer.nftAddress()).equal(nft.target); // @ts-ignore await nftClaimer.connect(otherAccount).claim(2); expect(await nft.balanceOf(otherAccount.address)).to.equal(2); expect(await nftClaimer.totalCount()).to.equal(2); // @ts-ignore expect((await nftClaimer.connect(otherAccount).whiteCount())).to.equal(1); }); it('should claim NFTS in parse2', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(2); const count = 4 const price = 100 await nftClaimer.addParse2WL([otherAccount.address]) // @ts-ignore expect((await nftClaimer.connect(otherAccount).whiteCount())).to.equal(count); const tokenAmount = price * count // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, tokenAmount) // @ts-ignore await nftClaimer.connect(otherAccount).claim(count); expect(await nft.balanceOf(otherAccount.address)).to.equal(count); expect(await ft.balanceOf(owner.address)).to.equal(tokenAmount) }); it('should revert claim NFT not in whitelist or exceed limit', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); //use ft.connect() to send a transaction from another account // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, 400) expect(await nftClaimer.nftAddress()).equal(nft.target); // @ts-ignore await expect(nftClaimer.connect(otherAccount).claim(4)).to.be.revertedWith( "NFTClaimer: not in whitelist or exceed limit" ); }); it('should revert claim NFT if the balance not enough', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); const price = 1001 const mintConfig = [ 2000, ft.target, price, owner.address ] await nftClaimer.updateMintConfig(mintConfig); // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, price) // @ts-ignore await expect(nftClaimer.connect(otherAccount).claim(1)).to.be.revertedWith( "ERC20: transfer amount exceeds balance" ); }); it('should revert claim NFT if allowance not enough', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); const price = 100 // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, price - 1) // @ts-ignore await expect(nftClaimer.connect(otherAccount).claim(1)).to.be.revertedWith( "ERC20: insufficient allowance" ); }); it('should revert claim NFT if the activity not open', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(0); const price = 100 // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, price) // @ts-ignore await expect(nftClaimer.connect(otherAccount).claim(1)).to.be.revertedWith( "NFTClaimer: not begin or ended" ); }); it('should revert claim NFT if the exceed max num', async function() { const { nftClaimer, owner, otherAccount, ft, nft, chainId } = await loadFixture(deployOneContract); await nftClaimer.updateMintParse(1); const price = 100 const mintConfig = [ 1, ft.target, price, owner.address ] await nftClaimer.updateMintConfig(mintConfig); // @ts-ignore await ft.connect(otherAccount).approve(nftClaimer.target, price * 2) const nonce = (Math.random() * 1000) | 0; // @ts-ignore await expect(nftClaimer.connect(otherAccount).claim(2)).to.be.revertedWith( "NFTClaimer: exceed max supply" ); }); }); })