diff --git a/contracts/BucketAuction.sol b/contracts/BucketAuction.sol index 1b1d7f80..8a8de01b 100644 --- a/contracts/BucketAuction.sol +++ b/contracts/BucketAuction.sol @@ -32,7 +32,8 @@ contract BucketAuction is IBucketAuction, ERC721M { address cosigner, uint256 minimumContributionInWei, uint64 startTimeUnixSeconds, - uint64 endTimeUnixSeconds + uint64 endTimeUnixSeconds, + uint64 timestampExpirySeconds ) ERC721M( collectionName, @@ -41,10 +42,9 @@ contract BucketAuction is IBucketAuction, ERC721M { maxMintableSupply, globalWalletLimit, cosigner, - /* timestampExpirySeconds= */ - 300, - /* mintCurrency= */ - address(0) + timestampExpirySeconds, + address(0), // mintCurrency + address(0) // crossMintAddress ) { _claimable = false; diff --git a/contracts/BucketAuctionOperatorFilterer.sol b/contracts/BucketAuctionOperatorFilterer.sol index fa3df3a8..f97a042b 100644 --- a/contracts/BucketAuctionOperatorFilterer.sol +++ b/contracts/BucketAuctionOperatorFilterer.sol @@ -19,7 +19,8 @@ contract BucketAuctionOperatorFilterer is address cosigner, uint256 minimumContributionInWei, uint64 startTimeUnixSeconds, - uint64 endTimeUnixSeconds + uint64 endTimeUnixSeconds, + uint64 timestampExpirySeconds ) UpdatableOperatorFilterer( CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, @@ -35,7 +36,8 @@ contract BucketAuctionOperatorFilterer is cosigner, minimumContributionInWei, startTimeUnixSeconds, - endTimeUnixSeconds + endTimeUnixSeconds, + timestampExpirySeconds ) {} diff --git a/contracts/DutchAuction.sol b/contracts/DutchAuction.sol index 24dd3719..5ed8cbb2 100644 --- a/contracts/DutchAuction.sol +++ b/contracts/DutchAuction.sol @@ -37,6 +37,7 @@ contract DutchAuction is IDutchAuction, ERC721M { /* timestampExpirySeconds= */ 300, /* mintCurrency= */ + address(0), address(0) ) { diff --git a/contracts/ERC721M.sol b/contracts/ERC721M.sol index 9468e628..261a96ba 100644 --- a/contracts/ERC721M.sol +++ b/contracts/ERC721M.sol @@ -73,7 +73,8 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossMintAddress ) ERC721A(collectionName, collectionSymbol) { if (globalWalletLimit > maxMintableSupply) revert GlobalWalletLimitOverflow(); @@ -84,6 +85,7 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { _cosigner = cosigner; // ethers.constants.AddressZero for no cosigning _timestampExpirySeconds = timestampExpirySeconds; _mintCurrency = mintCurrency; + _crossmintAddress = crossMintAddress; } /** @@ -109,30 +111,6 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { return _numberMinted(minter); } - /** - * @dev Sets cosigner. - */ - function setCosigner(address cosigner) external onlyOwner { - _cosigner = cosigner; - emit SetCosigner(cosigner); - } - - /** - * @dev Sets expiry in seconds. This timestamp specifies how long a signature from cosigner is valid for. - */ - function setTimestampExpirySeconds(uint64 expiry) external onlyOwner { - _timestampExpirySeconds = expiry; - emit SetTimestampExpirySeconds(expiry); - } - - /** - * @dev Sets crossmint address if using crossmint. This allows the specified address to call `crossmint`. - */ - function setCrossmintAddress(address crossmintAddress) external onlyOwner { - _crossmintAddress = crossmintAddress; - emit SetCrossmintAddress(crossmintAddress); - } - /** * @dev Sets stages in the format of an array of `MintStageInfo`. * @@ -251,19 +229,6 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { return _globalWalletLimit; } - /** - * @dev Sets global wallet limit. - */ - function setGlobalWalletLimit(uint256 globalWalletLimit) - external - onlyOwner - { - if (globalWalletLimit > _maxMintableSupply) - revert GlobalWalletLimitOverflow(); - _globalWalletLimit = globalWalletLimit; - emit SetGlobalWalletLimit(globalWalletLimit); - } - /** * @dev Returns number of minted token for a given address. */ @@ -293,52 +258,10 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { if (index >= _mintStages.length) { revert("InvalidStage"); } - uint32 walletMinted = _stageMintedCountsPerWallet[index][msg.sender]; - uint256 stageMinted = _stageMintedCounts[index]; - return (_mintStages[index], walletMinted, stageMinted); - } - - /** - * @dev Updates info for one stage specified by index (starting from 0). - */ - function updateStage( - uint256 index, - uint80 price, - uint32 walletLimit, - bytes32 merkleRoot, - uint24 maxStageSupply, - uint64 startTimeUnixSeconds, - uint64 endTimeUnixSeconds - ) external onlyOwner { - if (index >= _mintStages.length) revert InvalidStage(); - if (index >= 1) { - if ( - startTimeUnixSeconds < - _mintStages[index - 1].endTimeUnixSeconds + - _timestampExpirySeconds - ) { - revert InsufficientStageTimeGap(); - } - } - _assertValidStartAndEndTimestamp( - startTimeUnixSeconds, - endTimeUnixSeconds - ); - _mintStages[index].price = price; - _mintStages[index].walletLimit = walletLimit; - _mintStages[index].merkleRoot = merkleRoot; - _mintStages[index].maxStageSupply = maxStageSupply; - _mintStages[index].startTimeUnixSeconds = startTimeUnixSeconds; - _mintStages[index].endTimeUnixSeconds = endTimeUnixSeconds; - - emit UpdateStage( - index, - price, - walletLimit, - merkleRoot, - maxStageSupply, - startTimeUnixSeconds, - endTimeUnixSeconds + return ( + _mintStages[index], + _stageMintedCountsPerWallet[index][msg.sender], + _stageMintedCounts[index] ); } @@ -474,9 +397,6 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { _safeMint(to, qty); } - /** - * @dev Withdraws funds by owner. - */ function withdraw() external onlyOwner { uint256 value = address(this).balance; (bool success, ) = msg.sender.call{value: value}(""); @@ -503,14 +423,6 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard { emit SetBaseURI(baseURI); } - /** - * @dev Sets token base URI permanent. Cannot revert. - */ - function setBaseURIPermanent() external onlyOwner { - _baseURIPermanent = true; - emit PermanentBaseURI(_currentBaseURI); - } - /** * @dev Sets token URI suffix. e.g. ".json". */ diff --git a/contracts/ERC721MAutoApprover.sol b/contracts/ERC721MAutoApprover.sol index 40081273..84401309 100644 --- a/contracts/ERC721MAutoApprover.sol +++ b/contracts/ERC721MAutoApprover.sol @@ -18,7 +18,8 @@ contract ERC721MAutoApprover is ERC721M { address cosigner, uint64 timestampExpirySeconds, address mintCurrency, - address autoApproveAddress + address autoApproveAddress, + address crossmintAddress ) ERC721M( collectionName, @@ -28,7 +29,8 @@ contract ERC721MAutoApprover is ERC721M { globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossmintAddress ) { _autoApproveAddress = autoApproveAddress; diff --git a/contracts/ERC721MIncreasableOperatorFilterer.sol b/contracts/ERC721MIncreasableOperatorFilterer.sol index 6f29f89e..38d4b227 100644 --- a/contracts/ERC721MIncreasableOperatorFilterer.sol +++ b/contracts/ERC721MIncreasableOperatorFilterer.sol @@ -19,7 +19,8 @@ contract ERC721MIncreasableOperatorFilterer is uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossmintAddress ) UpdatableOperatorFilterer( CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, @@ -34,7 +35,8 @@ contract ERC721MIncreasableOperatorFilterer is globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossmintAddress ) {} diff --git a/contracts/ERC721MIncreasableSupply.sol b/contracts/ERC721MIncreasableSupply.sol index 00b60b99..4558d486 100644 --- a/contracts/ERC721MIncreasableSupply.sol +++ b/contracts/ERC721MIncreasableSupply.sol @@ -18,7 +18,8 @@ contract ERC721MIncreasableSupply is ERC721M { uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossMintAddress ) ERC721M( collectionName, @@ -28,7 +29,8 @@ contract ERC721MIncreasableSupply is ERC721M { globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossMintAddress ) { _canIncreaseMaxMintableSupply = true; diff --git a/contracts/ERC721MOperatorFilterer.sol b/contracts/ERC721MOperatorFilterer.sol index a72d0b93..720dd679 100644 --- a/contracts/ERC721MOperatorFilterer.sol +++ b/contracts/ERC721MOperatorFilterer.sol @@ -15,7 +15,8 @@ contract ERC721MOperatorFilterer is ERC721M, UpdatableOperatorFilterer { uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossmintAddress ) UpdatableOperatorFilterer( CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, @@ -30,7 +31,8 @@ contract ERC721MOperatorFilterer is ERC721M, UpdatableOperatorFilterer { globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossmintAddress ) {} diff --git a/contracts/ERC721MOperatorFiltererAutoApprover.sol b/contracts/ERC721MOperatorFiltererAutoApprover.sol index abef74a4..b2fbc08f 100644 --- a/contracts/ERC721MOperatorFiltererAutoApprover.sol +++ b/contracts/ERC721MOperatorFiltererAutoApprover.sol @@ -18,7 +18,8 @@ contract ERC721MOperatorFiltererAutoApprover is ERC721MOperatorFilterer { address cosigner, uint64 timestampExpirySeconds, address mintCurrency, - address autoApproveAddress + address autoApproveAddress, + address crossMintAddress ) ERC721MOperatorFilterer( collectionName, @@ -28,7 +29,8 @@ contract ERC721MOperatorFiltererAutoApprover is ERC721MOperatorFilterer { globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossMintAddress ) { _autoApproveAddress = autoApproveAddress; diff --git a/contracts/ERC721MPausable.sol b/contracts/ERC721MPausable.sol index 6321c300..8632c2a9 100644 --- a/contracts/ERC721MPausable.sol +++ b/contracts/ERC721MPausable.sol @@ -14,7 +14,8 @@ contract ERC721MPausable is ERC721M, Pausable { uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossmintAddress ) ERC721M( collectionName, @@ -24,7 +25,8 @@ contract ERC721MPausable is ERC721M, Pausable { globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossmintAddress ) {} diff --git a/contracts/ERC721MPausableOperatorFilterer.sol b/contracts/ERC721MPausableOperatorFilterer.sol index f865ecff..271433c2 100644 --- a/contracts/ERC721MPausableOperatorFilterer.sol +++ b/contracts/ERC721MPausableOperatorFilterer.sol @@ -18,7 +18,8 @@ contract ERC721MPausableOperatorFilterer is uint256 globalWalletLimit, address cosigner, uint64 timestampExpirySeconds, - address mintCurrency + address mintCurrency, + address crossMintAddress ) UpdatableOperatorFilterer( CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, @@ -33,7 +34,8 @@ contract ERC721MPausableOperatorFilterer is globalWalletLimit, cosigner, timestampExpirySeconds, - mintCurrency + mintCurrency, + crossMintAddress ) {} diff --git a/hardhat.config.ts b/hardhat.config.ts index 6f375342..1f2f7b2a 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -11,32 +11,30 @@ import 'solidity-coverage'; import { deploy } from './scripts/deploy'; import { deployBA } from './scripts/deployBA'; +import { deployOnft } from './scripts/deployOnft'; +import { deployOwnedRegistrant } from './scripts/deployOwnedRegistrant'; +import { getEndTimeBA } from './scripts/dev/getEndTimeBA'; +import { getMinContributionInWei } from './scripts/dev/getMinContributionInWei'; +import { getPrice } from './scripts/dev/getPrice'; +import { getStartTimeBA } from './scripts/dev/getStartTimeBA'; import { mint } from './scripts/mint'; import { ownerMint } from './scripts/ownerMint'; -import { setBaseURI } from './scripts/setBaseURI'; -import { setCrossmintAddress } from './scripts/setCrossmintAddress'; -import { setGlobalWalletLimit } from './scripts/setGlobalWalletLimit'; -import { setMaxMintableSupply } from './scripts/setMaxMintableSupply'; -import { setMintable } from './scripts/setMintable'; -import { setStages } from './scripts/setStages'; -import { setTimestampExpirySeconds } from './scripts/setTimestampExpirySeconds'; -import { transferOwnership } from './scripts/transferOwnership'; -import { setStartAndEndTimeUnixSeconds } from './scripts/setStartAndEndTimeUnixSeconds'; -import { setMinContributionInWei } from './scripts/setMinContributionInWei'; +import { sendOnft } from './scripts/sendOnft'; import { sendRefund } from './scripts/sendRefund'; import { sendRefundBatch } from './scripts/sendRefundBatch'; import { sendTokensAndRefund } from './scripts/sendTokensAndRefund'; import { sendTokensAndRefundBatch } from './scripts/sendTokensAndRefundBatch'; -import { setPrice } from './scripts/setPrice'; -import { getPrice } from './scripts/dev/getPrice'; -import { getStartTimeBA } from './scripts/dev/getStartTimeBA'; -import { getEndTimeBA } from './scripts/dev/getEndTimeBA'; -import { getMinContributionInWei } from './scripts/dev/getMinContributionInWei'; -import { deployOnft } from './scripts/deployOnft'; +import { setBaseURI } from './scripts/setBaseURI'; +import { setMaxMintableSupply } from './scripts/setMaxMintableSupply'; +import { setMinContributionInWei } from './scripts/setMinContributionInWei'; +import { setMintable } from './scripts/setMintable'; import { setOnftMinDstGas } from './scripts/setOnftMinDstGas'; +import { setPrice } from './scripts/setPrice'; +import { setStages } from './scripts/setStages'; +import { setStartAndEndTimeUnixSeconds } from './scripts/setStartAndEndTimeUnixSeconds'; +import { setTimestampExpirySeconds } from './scripts/setTimestampExpirySeconds'; import { setTrustedRemote } from './scripts/setTrustedRemote'; -import { sendOnft } from './scripts/sendOnft'; -import { deployOwnedRegistrant } from './scripts/deployOwnedRegistrant'; +import { transferOwnership } from './scripts/transferOwnership'; const config: HardhatUserConfig = { solidity: { @@ -96,7 +94,7 @@ const config: HardhatUserConfig = { url: process.env.SEPOLIA_URL || 'https://rpc.sepolia.org', accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], - } + }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, @@ -125,6 +123,11 @@ task('deploy', 'Deploy ERC721M') .addParam('tokenurisuffix', 'token uri suffix', '.json') .addParam('globalwalletlimit', 'global wallet limit', '0') .addParam('timestampexpiryseconds', 'timestamp expiry in seconds', '300') + .addOptionalParam( + 'crossMintAddress', + 'cross mint address', + '0x0000000000000000000000000000000000000000', + ) .addOptionalParam( 'cosigner', 'cosigner address (0x00...000 if not using cosign)', @@ -154,11 +157,6 @@ task('setBaseURI', 'Set the base uri') .addOptionalParam('gaspricegwei', 'Set gas price in Gwei') .setAction(setBaseURI); -task('setCrossmintAddress', 'Set crossmint address') - .addParam('contract', 'contract address') - .addParam('crossmintaddress', 'new crossmint address') - .setAction(setCrossmintAddress); - task('mint', 'Mint token(s)') .addParam('contract', 'contract address') .addParam('qty', 'quantity to mint', '1') @@ -171,11 +169,6 @@ task('ownerMint', 'Mint token(s) as owner') .addOptionalParam('to', 'recipient address') .setAction(ownerMint); -task('setGlobalWalletLimit', 'Set the global wallet limit') - .addParam('contract', 'contract address') - .addParam('limit', 'global wallet limit (0 for no global limit)') - .setAction(setGlobalWalletLimit); - task('setMaxMintableSupply', 'set max mintable supply') .addParam('contract', 'contract address') .addParam('supply', 'new supply') @@ -192,6 +185,11 @@ task('deployBA', 'Deploy BucketAuction') 'cosigner address (0x00...000 if not using cosign)', '0x0000000000000000000000000000000000000000', ) + .addOptionalParam( + 'timestampExpirySeconds', + 'timestamp expiry in seconds', + '300', + ) .addParam( 'mincontributioninwei', 'The minimum contribution in wei required only for the AuctionBucket', @@ -330,7 +328,11 @@ task('sendOnft', 'Send tokens to target network') .setAction(sendOnft); task('deployOwnedRegistrant', 'Deploy OwnedRegistrant') - .addParam('newowner', 'new owner address', '0x0000000000000000000000000000000000000000') + .addParam( + 'newowner', + 'new owner address', + '0x0000000000000000000000000000000000000000', + ) .setAction(deployOwnedRegistrant); export default config; diff --git a/scripts/deploy.ts b/scripts/deploy.ts index d474b63d..32a3233a 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -22,6 +22,7 @@ export interface IDeployParams { autoapproveaddress?: string; pausable?: boolean; mintcurrency?: string; + crossMintAddress?: string; } export const deploy = async ( @@ -74,6 +75,7 @@ export const deploy = async ( args.timestampexpiryseconds ?? 300, args.mintcurrency ?? hre.ethers.constants.AddressZero, args.autoapproveaddress ?? {}, + args.crossMintAddress ?? hre.ethers.constants.AddressZero, ] as const; console.log( diff --git a/scripts/deployBA.ts b/scripts/deployBA.ts index 17417b12..2f903355 100644 --- a/scripts/deployBA.ts +++ b/scripts/deployBA.ts @@ -5,8 +5,8 @@ // Runtime Environment's members available in the global scope. import { confirm } from '@inquirer/prompts'; -import { ContractDetails } from './common/constants'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { ContractDetails } from './common/constants'; export interface IDeployParams { name: string; @@ -19,6 +19,8 @@ export interface IDeployParams { auctionstarttime: string; auctionendtime: string; useoperatorfilterer?: boolean; + crossMintAddress?: string; + timestampExpirySeconds?: number; } export const deployBA = async ( @@ -56,6 +58,8 @@ export const deployBA = async ( hre.ethers.BigNumber.from(args.mincontributioninwei), Math.floor(new Date(args.auctionstarttime).getTime() / 1000), Math.floor(new Date(args.auctionendtime).getTime() / 1000), + args.crossMintAddress ?? hre.ethers.constants.AddressZero, + args.timestampExpirySeconds ?? 300, ] as const; console.log( @@ -70,7 +74,7 @@ export const deployBA = async ( ), ); - if (!await confirm({ message: 'Continue to deploy?' })) return; + if (!(await confirm({ message: 'Continue to deploy?' }))) return; const contract = await contractFactory.deploy(...params); await contract.deployed(); diff --git a/scripts/deployOnft.ts b/scripts/deployOnft.ts index d09d0be9..e1c4f691 100644 --- a/scripts/deployOnft.ts +++ b/scripts/deployOnft.ts @@ -24,7 +24,6 @@ export const deployOnft = async ( args: IDeployParams, hre: HardhatRuntimeEnvironment, ) => { - let contractName; let deployParams; @@ -68,7 +67,7 @@ export const deployOnft = async ( ), ); - if (!await confirm({ message: 'Continue to deploy?' })) return; + if (!(await confirm({ message: 'Continue to deploy?' }))) return; const contract = await hre.ethers.getContractFactory(contractName); const erc721MOnft = await contract.deploy(...deployParams); diff --git a/test/BucketAuction.test.ts b/test/BucketAuction.test.ts index 65cc1656..f4615782 100644 --- a/test/BucketAuction.test.ts +++ b/test/BucketAuction.test.ts @@ -29,12 +29,12 @@ describe('BucketAuction', function () { /* minimumContributionInWei= */ 100, 0, // Placeholder; startTimeUnixSeconds will be overwritten later 1, // Placeholder; endTimeUnixSeconds will be overwritten later + 60, // timestamp expiry seconds ); await ba.deployed(); [owner, readonly] = await ethers.getSigners(); ownerConn = ba.connect(owner); - await ownerConn.setTimestampExpirySeconds(60); await ownerConn.setStages([ { price: ethers.utils.parseEther('0.1'), diff --git a/test/DutchAuction.test.ts b/test/DutchAuction.test.ts index 09dad650..3605792b 100644 --- a/test/DutchAuction.test.ts +++ b/test/DutchAuction.test.ts @@ -1,5 +1,5 @@ -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { time } from '@nomicfoundation/hardhat-network-helpers'; +import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import chai, { expect } from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { ethers } from 'hardhat'; diff --git a/test/ERC721MAutoApprover.test.ts b/test/ERC721MAutoApprover.test.ts index 5f65731d..bc86d086 100644 --- a/test/ERC721MAutoApprover.test.ts +++ b/test/ERC721MAutoApprover.test.ts @@ -1,6 +1,6 @@ -import { ERC721MAutoApprover } from '../typechain-types'; -import { ethers } from 'hardhat'; import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ERC721MAutoApprover } from '../typechain-types'; const test_approve_address = '0x7897018b1cE161e58943C579AC3df50d89c3D4F4'; @@ -19,6 +19,7 @@ describe('ERC721MAutoApprover', () => { 300, ethers.constants.AddressZero, test_approve_address, + ethers.constants.AddressZero, ); const [owner] = await ethers.getSigners(); contract = contract.connect(owner); diff --git a/test/ERC721MIncreasableSupply.test.ts b/test/ERC721MIncreasableSupply.test.ts index 2973fe6c..531c56fa 100644 --- a/test/ERC721MIncreasableSupply.test.ts +++ b/test/ERC721MIncreasableSupply.test.ts @@ -1,6 +1,6 @@ -import { ERC721MIncreasableSupply } from '../typechain-types'; -import { ethers } from 'hardhat'; import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ERC721MIncreasableSupply } from '../typechain-types'; describe('ERC721MIncreasableSupply', () => { let contract: ERC721MIncreasableSupply; @@ -16,6 +16,7 @@ describe('ERC721MIncreasableSupply', () => { ethers.constants.AddressZero, 300, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); const [owner] = await ethers.getSigners(); contract = contract.connect(owner); diff --git a/test/ERC721MOperatorFiltererAutoApprover.test.ts b/test/ERC721MOperatorFiltererAutoApprover.test.ts index 1c01fa2a..5ad9c436 100644 --- a/test/ERC721MOperatorFiltererAutoApprover.test.ts +++ b/test/ERC721MOperatorFiltererAutoApprover.test.ts @@ -1,6 +1,6 @@ -import { ERC721MOperatorFiltererAutoApprover } from '../typechain-types'; -import { ethers } from 'hardhat'; import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { ERC721MOperatorFiltererAutoApprover } from '../typechain-types'; const test_approve_address = '0x7897018b1cE161e58943C579AC3df50d89c3D4F4'; @@ -21,6 +21,7 @@ describe('ERC721MOperatorFiltererAutoApprover', () => { 300, ethers.constants.AddressZero, test_approve_address, + ethers.constants.AddressZero, ); const [owner] = await ethers.getSigners(); contract = contract.connect(owner); diff --git a/test/ERC721MPausable.test.ts b/test/ERC721MPausable.test.ts index 1fe1a55d..872f48da 100644 --- a/test/ERC721MPausable.test.ts +++ b/test/ERC721MPausable.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { ethers } from 'hardhat'; import { Contract } from 'ethers'; +import { ethers } from 'hardhat'; describe('ERC721MPausable', function () { let erc721MPausable: Contract; @@ -22,6 +22,7 @@ describe('ERC721MPausable', function () { ethers.constants.AddressZero, 300, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); erc721MPausable = erc721MPausable.connect(owner); await erc721MPausable.deployed(); diff --git a/test/ERC721MPausableOperatorFilterer.test.ts b/test/ERC721MPausableOperatorFilterer.test.ts index 6e9deee5..4761ba31 100644 --- a/test/ERC721MPausableOperatorFilterer.test.ts +++ b/test/ERC721MPausableOperatorFilterer.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { ethers } from 'hardhat'; import { Contract } from 'ethers'; +import { ethers } from 'hardhat'; describe('ERC721MPausableOperatorFilterer', function () { let erc721MPausableOperatorFilterer: Contract; @@ -22,6 +22,7 @@ describe('ERC721MPausableOperatorFilterer', function () { ethers.constants.AddressZero, 300, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); erc721MPausableOperatorFilterer = erc721MPausableOperatorFilterer.connect(owner); diff --git a/test/erc721m.test.ts b/test/erc721m.test.ts index 6aa568d0..810e1944 100644 --- a/test/erc721m.test.ts +++ b/test/erc721m.test.ts @@ -49,6 +49,7 @@ describe('ERC721M', function () { beforeEach(async () => { const ERC721M = await ethers.getContractFactory('ERC721M'); + [owner, readonly] = await ethers.getSigners(); const erc721M = await ERC721M.deploy( 'Test', 'TEST', @@ -58,10 +59,10 @@ describe('ERC721M', function () { ethers.constants.AddressZero, 60, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); await erc721M.deployed(); - [owner, readonly] = await ethers.getSigners(); contract = erc721M.connect(owner); readonlyContract = erc721M.connect(readonly); chainId = await ethers.provider.getNetwork().then((n) => n.chainId); @@ -285,202 +286,6 @@ describe('ERC721M', function () { expect(walletMintedCount).to.equal(0); }); - it('can update stage', async () => { - await contract.setStages([ - { - price: ethers.utils.parseEther('0.5'), - walletLimit: 3, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 5, - startTimeUnixSeconds: 0, - endTimeUnixSeconds: 1, - }, - { - price: ethers.utils.parseEther('0.6'), - walletLimit: 4, - merkleRoot: ethers.utils.hexZeroPad('0x2', 32), - maxStageSupply: 10, - startTimeUnixSeconds: 61, - endTimeUnixSeconds: 62, - }, - ]); - - expect(await contract.getNumberStages()).to.equal(2); - - let [stageInfo, walletMintedCount] = await contract.getStageInfo(0); - expect(stageInfo.price).to.equal(ethers.utils.parseEther('0.5')); - expect(stageInfo.walletLimit).to.equal(3); - expect(stageInfo.maxStageSupply).to.equal(5); - expect(stageInfo.merkleRoot).to.equal(ethers.utils.hexZeroPad('0x1', 32)); - expect(walletMintedCount).to.equal(0); - - [stageInfo, walletMintedCount] = await contract.getStageInfo(1); - expect(stageInfo.price).to.equal(ethers.utils.parseEther('0.6')); - expect(stageInfo.walletLimit).to.equal(4); - expect(stageInfo.maxStageSupply).to.equal(10); - expect(stageInfo.merkleRoot).to.equal(ethers.utils.hexZeroPad('0x2', 32)); - expect(walletMintedCount).to.equal(0); - - // Update first stage - await expect( - contract.updateStage( - /* _index= */ 0, - /* price= */ ethers.utils.parseEther('0.1'), - /* walletLimit= */ 13, - /* merkleRoot= */ ethers.utils.hexZeroPad('0x9', 32), - /* maxStageSupply= */ 15, - /* startTimeUnixSeconds= */ 0, - /* endTimeUnixSeconds= */ 1, - ), - ) - .to.emit(contract, 'UpdateStage') - .withArgs( - 0, - ethers.utils.parseEther('0.1'), - 13, - ethers.utils.hexZeroPad('0x9', 32), - 15, - 0, - 1, - ); - - expect(await contract.getNumberStages()).to.equal(2); - - [stageInfo, walletMintedCount] = await contract.getStageInfo(0); - expect(stageInfo.price).to.equal(ethers.utils.parseEther('0.1')); - expect(stageInfo.walletLimit).to.equal(13); - expect(stageInfo.maxStageSupply).to.equal(15); - expect(stageInfo.merkleRoot).to.equal(ethers.utils.hexZeroPad('0x9', 32)); - expect(walletMintedCount).to.equal(0); - - // Stage 2 is unchanged. - [stageInfo, walletMintedCount] = await contract.getStageInfo(1); - expect(stageInfo.price).to.equal(ethers.utils.parseEther('0.6')); - expect(stageInfo.walletLimit).to.equal(4); - expect(stageInfo.maxStageSupply).to.equal(10); - expect(stageInfo.merkleRoot).to.equal(ethers.utils.hexZeroPad('0x2', 32)); - expect(walletMintedCount).to.equal(0); - }); - - it('updates stage reverts for non-existent stage', async () => { - await contract.setStages([ - { - price: ethers.utils.parseEther('0.5'), - walletLimit: 3, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 5, - startTimeUnixSeconds: 0, - endTimeUnixSeconds: 1, - }, - { - price: ethers.utils.parseEther('0.6'), - walletLimit: 4, - merkleRoot: ethers.utils.hexZeroPad('0x2', 32), - maxStageSupply: 10, - startTimeUnixSeconds: 61, - endTimeUnixSeconds: 62, - }, - ]); - - // Update a stage which doesn't exist. - const updateStage = contract.updateStage( - /* _index= */ 2, - /* price= */ ethers.utils.parseEther('0.1'), - /* walletLimit= */ 13, - /* merkleRoot= */ ethers.utils.hexZeroPad('0x9', 32), - /* maxStageSupply= */ 15, - /* startTimeUnixSeconds= */ 0, - /* endTimeUnixSeconds= */ 0, - ); - - await expect(updateStage).to.be.revertedWith('InvalidStage'); - }); - - it('cannot update stage to insufficient stage gap', async () => { - await contract.setStages([ - { - price: ethers.utils.parseEther('0.5'), - walletLimit: 3, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 5, - startTimeUnixSeconds: 0, - endTimeUnixSeconds: 1, - }, - { - price: ethers.utils.parseEther('0.6'), - walletLimit: 4, - merkleRoot: ethers.utils.hexZeroPad('0x2', 32), - maxStageSupply: 10, - startTimeUnixSeconds: 61, - endTimeUnixSeconds: 62, - }, - ]); - - // Set stage 1 to only be 59 seconds from stage 2 - const updateStage = contract.updateStage( - /* _index= */ 1, - /* price= */ ethers.utils.parseEther('0.1'), - /* walletLimit= */ 13, - /* merkleRoot= */ ethers.utils.hexZeroPad('0x9', 32), - /* maxStageSupply= */ 15, - /* startTimeUnixSeconds= */ 0, - /* endTimeUnixSeconds= */ 2, - ); - - await expect(updateStage).to.be.revertedWith('InsufficientStageTimeGap'); - }); - - it('cannot update stage due to the startTimeUnixSeconds is not smaller than the endTimeUnixSeconds', async () => { - await contract.setStages([ - { - price: ethers.utils.parseEther('0.5'), - walletLimit: 3, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 5, - startTimeUnixSeconds: 0, - endTimeUnixSeconds: 1, - }, - { - price: ethers.utils.parseEther('0.6'), - walletLimit: 4, - merkleRoot: ethers.utils.hexZeroPad('0x2', 32), - maxStageSupply: 10, - startTimeUnixSeconds: 61, - endTimeUnixSeconds: 62, - }, - ]); - - // Update stage 1 and set startTimeUnixSeconds and endTimeUnixSeconds to identical values - const updateStageWithIdenticalStartAndEndTime = contract.updateStage( - /* _index= */ 1, - /* price= */ ethers.utils.parseEther('0.1'), - /* walletLimit= */ 13, - /* merkleRoot= */ ethers.utils.hexZeroPad('0x9', 32), - /* maxStageSupply= */ 15, - /* startTimeUnixSeconds= */ 61, - /* endTimeUnixSeconds= */ 61, - ); - - await expect(updateStageWithIdenticalStartAndEndTime).to.be.revertedWith( - 'InvalidStartAndEndTimestamp', - ); - - // Update stage 1 and set startTimeUnixSeconds to a value which is not smaller than the endTimeUnixSeconds - const updateStageWithStartTimeAfterEndTime = contract.updateStage( - /* _index= */ 1, - /* price= */ ethers.utils.parseEther('0.1'), - /* walletLimit= */ 13, - /* merkleRoot= */ ethers.utils.hexZeroPad('0x9', 32), - /* maxStageSupply= */ 15, - /* startTimeUnixSeconds= */ 61, - /* endTimeUnixSeconds= */ 60, - ); - - await expect(updateStageWithStartTimeAfterEndTime).to.be.revertedWith( - 'InvalidStartAndEndTimestamp', - ); - }); - it('gets stage info', async () => { await contract.setStages([ { @@ -674,31 +479,23 @@ describe('ERC721M', function () { ).to.be.revertedWith('ReentrancyGuard: reentrant call'); }); - it('can set max mintable supply', async () => { - await contract.setMaxMintableSupply(99); - expect(await contract.getMaxMintableSupply()).to.equal(99); - - // can set the mintable supply again with the same value - await contract.setMaxMintableSupply(99); - expect(await contract.getMaxMintableSupply()).to.equal(99); - - // can set the mintable supply again with the lower value - await contract.setMaxMintableSupply(98); - expect(await contract.getMaxMintableSupply()).to.equal(98); - - // can not set the mintable supply with higher value - await expect(contract.setMaxMintableSupply(100)).to.be.rejectedWith( - 'CannotIncreaseMaxMintableSupply', + it('enforces max mintable supply', async () => { + const ERC721M = await ethers.getContractFactory('ERC721M'); + const erc721M = await ERC721M.deploy( + 'Test', + 'TEST', + '', + 99, + 0, + ethers.constants.AddressZero, + 60, + ethers.constants.AddressZero, + ethers.constants.AddressZero, ); + await erc721M.deployed(); - // readonlyContract should not be able to set max mintable supply - await expect( - readonlyContract.setMaxMintableSupply(99), - ).to.be.revertedWith('Ownable'); - }); - - it('enforces max mintable supply', async () => { - await contract.setMaxMintableSupply(99); + [owner, readonly] = await ethers.getSigners(); + contract = erc721M.connect(owner); await contract.setStages([ { price: ethers.utils.parseEther('0.5'), @@ -749,7 +546,6 @@ describe('ERC721M', function () { endTimeUnixSeconds: stageStart + 2, }, ]); - await contract.setMaxMintableSupply(999); await contract.setMintable(true); // Setup the test context: block.timestamp should comply to the stage being active @@ -790,7 +586,6 @@ describe('ERC721M', function () { endTimeUnixSeconds: stageStart + 2, }, ]); - await contract.setMaxMintableSupply(999); await contract.setMintable(true); // Setup the test context: Update block.timestamp to comply to the stage being active @@ -866,7 +661,6 @@ describe('ERC721M', function () { }, ]); await contract.setMintable(true); - await contract.setCosigner(cosigner.address); const timestamp = stageStart + 500; const sig = getCosignSignature( @@ -892,202 +686,227 @@ describe('ERC721M', function () { expect(stagedMintedCount.toNumber()).to.equal(1); }); - it('mint with cosign - invalid sigs', async () => { - const [_owner, minter, cosigner] = await ethers.getSigners(); - await contract.setStages([ - { - price: ethers.utils.parseEther('0'), - walletLimit: 0, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 100, - startTimeUnixSeconds: 0, - endTimeUnixSeconds: 1, - }, - ]); - await contract.setMintable(true); - await contract.setCosigner(cosigner.address); - - const timestamp = Math.floor(new Date().getTime() / 1000); - const sig = await getCosignSignature( - contract, - cosigner, - minter.address, - timestamp, - 1, - ); - - // invalid because of unexpected timestamp - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], - timestamp + 1, - sig, - { - value: ethers.utils.parseEther('0'), - }, - ), - ).to.be.revertedWith('InvalidCosignSignature'); + describe('mint with cosign - invalid cases', () => { + beforeEach(async () => { + const [_owner, _minter, cosigner] = await ethers.getSigners(); + const ERC721M = await ethers.getContractFactory('ERC721M'); + const erc721M = await ERC721M.deploy( + 'Test', + 'TEST', + '', + 1000, + 0, + cosigner.address, + 60, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + ); + await erc721M.deployed(); - // invalid because of unexptected sig - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], - timestamp, - sig + '00', - { - value: ethers.utils.parseEther('0'), - }, - ), - ).to.be.revertedWith('InvalidCosignSignature'); - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], - timestamp, - '0x00', + [owner, readonly] = await ethers.getSigners(); + contract = erc721M.connect(owner); + readonlyContract = erc721M.connect(readonly); + chainId = await ethers.provider.getNetwork().then((n) => n.chainId); + }); + it('mint with cosign - invalid sigs', async () => { + const [_owner, minter, cosigner] = await ethers.getSigners(); + await contract.setStages([ { - value: ethers.utils.parseEther('0'), + price: ethers.utils.parseEther('0'), + walletLimit: 0, + merkleRoot: ethers.utils.hexZeroPad('0x1', 32), + maxStageSupply: 100, + startTimeUnixSeconds: 0, + endTimeUnixSeconds: 1, }, - ), - ).to.be.revertedWith('InvalidCosignSignature'); - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], + ]); + await contract.setMintable(true); + const timestamp = Math.floor(new Date().getTime() / 1000); + const sig = await getCosignSignature( + contract, + cosigner, + minter.address, timestamp, - '0', - { - value: ethers.utils.parseEther('0'), - }, - ), - ).to.be.rejectedWith('invalid arrayify'); - await expect( - readonlyContract.mint( 1, - [ethers.utils.hexZeroPad('0x', 32)], - timestamp, - '', - { - value: ethers.utils.parseEther('0'), - }, - ), - ).to.be.rejectedWith('invalid arrayify'); - - // invalid because of unawait expected minter - await expect( - contract.mint(1, [ethers.utils.hexZeroPad('0x', 32)], timestamp, sig, { - value: ethers.utils.parseEther('0'), - }), - ).to.be.revertedWith('InvalidCosignSignature'); - }); - - it('mint with cosign - timestamp out of stage', async () => { - const [_owner, minter, cosigner] = await ethers.getSigners(); - const block = await ethers.provider.getBlock( - await ethers.provider.getBlockNumber(), - ); - const stageStart = block.timestamp; - await contract.setStages([ - { - price: ethers.utils.parseEther('0'), - walletLimit: 0, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 100, - startTimeUnixSeconds: stageStart, - endTimeUnixSeconds: stageStart + 1000, - }, - ]); - await contract.setMintable(true); - await contract.setCosigner(cosigner.address); + ); - const earlyTimestamp = stageStart - 1; - let sig = getCosignSignature( - readonlyContract, - cosigner, - minter.address, - earlyTimestamp, - 1, - ); + // invalid because of unexpected timestamp + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp + 1, + sig, + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidCosignSignature'); + + // invalid because of unexptected sig + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + sig + '00', + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidCosignSignature'); + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + '0x00', + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidCosignSignature'); + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + '0', + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.rejectedWith('invalid arrayify'); + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + '', + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.rejectedWith('invalid arrayify'); + + // invalid because of unawait expected minter + await expect( + contract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + sig, + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidCosignSignature'); + }); - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], - earlyTimestamp, - sig, + it('mint with cosign - timestamp out of stage', async () => { + const [_owner, minter, cosigner] = await ethers.getSigners(); + const block = await ethers.provider.getBlock( + await ethers.provider.getBlockNumber(), + ); + const stageStart = block.timestamp; + await contract.setStages([ { - value: ethers.utils.parseEther('0'), + price: ethers.utils.parseEther('0'), + walletLimit: 0, + merkleRoot: ethers.utils.hexZeroPad('0x1', 32), + maxStageSupply: 100, + startTimeUnixSeconds: stageStart, + endTimeUnixSeconds: stageStart + 1000, }, - ), - ).to.be.revertedWith('InvalidStage'); - - const lateTimestamp = stageStart + 1001; - sig = getCosignSignature( - readonlyContract, - cosigner, - minter.address, - lateTimestamp, - 1, - ); - - await expect( - readonlyContract.mint( + ]); + await contract.setMintable(true); + + const earlyTimestamp = stageStart - 1; + let sig = getCosignSignature( + readonlyContract, + cosigner, + minter.address, + earlyTimestamp, 1, - [ethers.utils.hexZeroPad('0x', 32)], - lateTimestamp, - sig, - { - value: ethers.utils.parseEther('0'), - }, - ), - ).to.be.revertedWith('InvalidStage'); - }); - - it('mint with cosign - expired signature', async () => { - const [_owner, minter, cosigner] = await ethers.getSigners(); - const block = await ethers.provider.getBlock( - await ethers.provider.getBlockNumber(), - ); - const stageStart = block.timestamp; - await contract.setStages([ - { - price: ethers.utils.parseEther('0'), - walletLimit: 0, - merkleRoot: ethers.utils.hexZeroPad('0x1', 32), - maxStageSupply: 100, - startTimeUnixSeconds: stageStart, - endTimeUnixSeconds: stageStart + 1000, - }, - ]); - await contract.setMintable(true); - await contract.setCosigner(cosigner.address); + ); - const timestamp = stageStart; - const sig = getCosignSignature( - readonlyContract, - cosigner, - minter.address, - timestamp, - 1, - ); + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + earlyTimestamp, + sig, + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidStage'); + + const lateTimestamp = stageStart + 1001; + sig = getCosignSignature( + readonlyContract, + cosigner, + minter.address, + lateTimestamp, + 1, + ); - // fast forward 2 minutes - await ethers.provider.send('evm_increaseTime', [120]); - await ethers.provider.send('evm_mine', []); + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + lateTimestamp, + sig, + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('InvalidStage'); + }); - await expect( - readonlyContract.mint( - 1, - [ethers.utils.hexZeroPad('0x', 32)], - timestamp, - sig, + it('mint with cosign - expired signature', async () => { + const [_owner, minter, cosigner] = await ethers.getSigners(); + const block = await ethers.provider.getBlock( + await ethers.provider.getBlockNumber(), + ); + const stageStart = block.timestamp; + await contract.setStages([ { - value: ethers.utils.parseEther('0'), + price: ethers.utils.parseEther('0'), + walletLimit: 0, + merkleRoot: ethers.utils.hexZeroPad('0x1', 32), + maxStageSupply: 100, + startTimeUnixSeconds: stageStart, + endTimeUnixSeconds: stageStart + 1000, }, - ), - ).to.be.revertedWith('TimestampExpired'); + ]); + await contract.setMintable(true); + + const timestamp = stageStart; + const sig = getCosignSignature( + readonlyContract, + cosigner, + minter.address, + timestamp, + 1, + ); + + // fast forward 2 minutes + await ethers.provider.send('evm_increaseTime', [120]); + await ethers.provider.send('evm_mine', []); + + await expect( + readonlyContract.mint( + 1, + [ethers.utils.hexZeroPad('0x', 32)], + timestamp, + sig, + { + value: ethers.utils.parseEther('0'), + }, + ), + ).to.be.revertedWith('TimestampExpired'); + }); }); it('enforces stage supply', async () => { @@ -1282,6 +1101,7 @@ describe('ERC721M', function () { ethers.constants.AddressZero, 60, ethers.constants.AddressZero, + crossmintAddressStr, ); await erc721M.deployed(); @@ -1304,7 +1124,6 @@ describe('ERC721M', function () { }, ]); await ownerConn.setMintable(true); - await ownerConn.setCrossmintAddress(crossmintAddressStr); // Impersonate Crossmint wallet const crossmintSigner = await ethers.getImpersonatedSigner( @@ -1353,6 +1172,7 @@ describe('ERC721M', function () { owner.address, 300, ethers.constants.AddressZero, + crossmintAddressStr, ); await erc721M.deployed(); @@ -1371,7 +1191,6 @@ describe('ERC721M', function () { }, ]); await ownerConn.setMintable(true); - await ownerConn.setCrossmintAddress(crossmintAddressStr); // Impersonate Crossmint wallet const crossmintSigner = await ethers.getImpersonatedSigner( @@ -1456,6 +1275,22 @@ describe('ERC721M', function () { }); it('crossmint reverts on non-Crossmint sender', async () => { + const crossmintAddressStr = '0xdAb1a1854214684acE522439684a145E62505233'; + [owner, readonly] = await ethers.getSigners(); + const ERC721M = await ethers.getContractFactory('ERC721M'); + const erc721M = await ERC721M.deploy( + 'Test', + 'TEST', + '', + 1000, + 0, + owner.address, + 300, + ethers.constants.AddressZero, + crossmintAddressStr, + ); + await erc721M.deployed(); + contract = erc721M.connect(owner); const accounts = (await ethers.getSigners()).map((signer) => getAddress(signer.address), ); @@ -1479,9 +1314,6 @@ describe('ERC721M', function () { }, ]); await contract.setMintable(true); - await contract.setCrossmintAddress( - '0xdAb1a1854214684acE522439684a145E62505233', - ); const crossmint = contract.crossmint( 7, @@ -1641,64 +1473,27 @@ describe('ERC721M', function () { 'URIQueryForNonexistentToken', ); }); + }); - it('Returns should not be able to set baseURI once frozen', async () => { - const block = await ethers.provider.getBlock( - await ethers.provider.getBlockNumber(), + describe('Global wallet limit', function () { + beforeEach(async () => { + const ERC721M = await ethers.getContractFactory('ERC721M'); + const erc721M = await ERC721M.deploy( + 'Test', + 'TEST', + '', + 1000, + 2, + ethers.constants.AddressZero, + 60, + ethers.constants.AddressZero, + ethers.constants.AddressZero, ); - // +10 is a number bigger than the count of transactions up to mint - const stageStart = block.timestamp + 10; - // Set stages - await contract.setStages([ - { - price: ethers.utils.parseEther('0.5'), - walletLimit: 10, - merkleRoot: ethers.utils.hexZeroPad('0x0', 32), - maxStageSupply: 5, - startTimeUnixSeconds: stageStart, - endTimeUnixSeconds: stageStart + 1, - }, - { - price: ethers.utils.parseEther('0.6'), - walletLimit: 10, - merkleRoot: ethers.utils.hexZeroPad('0x0', 32), - maxStageSupply: 10, - startTimeUnixSeconds: stageStart + 61, - endTimeUnixSeconds: stageStart + 62, - }, - ]); - - await contract.setBaseURI('base_uri_'); - await contract.setMintable(true); - - // Setup the test context: Update block.timestamp to comply to the stage being active - await ethers.provider.send('evm_mine', [stageStart - 1]); - await contract.mint(2, [ethers.utils.hexZeroPad('0x', 32)], 0, '0x00', { - value: ethers.utils.parseEther('2.5'), - }); - - expect(await contract.tokenURI(0)).to.equal('base_uri_0'); - expect(await contract.tokenURI(1)).to.equal('base_uri_1'); - - await contract.setBaseURI('base_uri_again_'); - expect(await contract.tokenURI(0)).to.equal('base_uri_again_0'); - - // readonlyContract should not be able to set baseURI - await expect( - readonlyContract.setBaseURI('something_else_'), - ).to.be.revertedWith('Ownable'); + await erc721M.deployed(); - await expect(contract.setBaseURIPermanent()).to.emit( - contract, - 'PermanentBaseURI', - ); - await expect( - contract.setBaseURI('base_uri_again_again_'), - ).to.be.revertedWith('CannotUpdatePermanentBaseURI'); + [owner, readonly] = await ethers.getSigners(); + contract = erc721M.connect(owner); }); - }); - - describe('Global wallet limit', function () { it('validates global wallet limit in constructor', async () => { const ERC721M = await ethers.getContractFactory('ERC721M'); await expect( @@ -1711,21 +1506,16 @@ describe('ERC721M', function () { ethers.constants.AddressZero, 60, ethers.constants.AddressZero, + ethers.constants.AddressZero, ), ).to.be.revertedWith('GlobalWalletLimitOverflow'); }); it('sets global wallet limit', async () => { - await contract.setGlobalWalletLimit(2); expect((await contract.getGlobalWalletLimit()).toNumber()).to.equal(2); - - await expect(contract.setGlobalWalletLimit(1001)).to.be.revertedWith( - 'GlobalWalletLimitOverflow', - ); }); it('enforces global wallet limit', async () => { - await contract.setGlobalWalletLimit(2); expect((await contract.getGlobalWalletLimit()).toNumber()).to.equal(2); const block = await ethers.provider.getBlock( @@ -1811,20 +1601,13 @@ describe('ERC721M', function () { ethers.constants.AddressZero, 60, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); await erc721M.deployed(); const ownerConn = erc721M.connect(owner); await expect( ownerConn.getCosignDigest(owner.address, 1, 0), ).to.be.revertedWith('CosignerNotSet'); - - // we can set the cosigner - await ownerConn.setCosigner(cosigner.address); - - // readonly contract can't set cosigner - await expect( - readonlyContract.setCosigner(cosigner.address), - ).to.be.revertedWith('Ownable'); }); it('can deploy with cosign', async () => { @@ -1839,6 +1622,7 @@ describe('ERC721M', function () { cosigner.address, 60, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); await erc721M.deployed(); diff --git a/test/mintCurrency.test.ts b/test/mintCurrency.test.ts index 48390b56..df4270ca 100644 --- a/test/mintCurrency.test.ts +++ b/test/mintCurrency.test.ts @@ -1,7 +1,7 @@ -import { ERC721M } from '../typechain-types'; +import { expect } from 'chai'; import { Contract, Signer } from 'ethers'; import { ethers } from 'hardhat'; -import { expect } from 'chai'; +import { ERC721M } from '../typechain-types'; describe('Mint Currency', () => { let erc721M: ERC721M, @@ -31,6 +31,7 @@ describe('Mint Currency', () => { ethers.constants.AddressZero, 60, erc20.address, + ethers.constants.AddressZero, ); await erc721M.deployed(); @@ -165,6 +166,7 @@ describe('Mint Currency', () => { ethers.constants.AddressZero, 60, ethers.constants.AddressZero, + ethers.constants.AddressZero, ); await erc721M.deployed();