Skip to content

Commit

Permalink
Support increasing max mintable supply with method to disable (#58)
Browse files Browse the repository at this point in the history
* Add ERC721MIncreasableSupply

* add back deleted comment

* update deploy script
  • Loading branch information
mi-yu authored Nov 10, 2022
1 parent 2eeeb23 commit 6fcd65f
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 10 deletions.
3 changes: 2 additions & 1 deletion contracts/ERC721M.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard {
address private _crossmintAddress;

// The total mintable supply.
uint256 private _maxMintableSupply;
uint256 internal _maxMintableSupply;

// Global wallet limit, across all stages.
uint256 private _globalWalletLimit;
Expand Down Expand Up @@ -257,6 +257,7 @@ contract ERC721M is IERC721M, ERC721AQueryable, Ownable, ReentrancyGuard {
*/
function setMaxMintableSupply(uint256 maxMintableSupply)
external
virtual
onlyOwner
{
if (maxMintableSupply > _maxMintableSupply) {
Expand Down
69 changes: 69 additions & 0 deletions contracts/ERC721MIncreasableSupply.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "./ERC721M.sol";

contract ERC721MIncreasableSupply is ERC721M {
// Whether mintable supply can increase. Once set to false, _maxMintableSupply can never increase.
bool private _canIncreaseMaxMintableSupply;

event DisableIncreaseMaxMintableSupply();

constructor(
string memory collectionName,
string memory collectionSymbol,
string memory tokenURISuffix,
uint256 maxMintableSupply,
uint256 globalWalletLimit,
address cosigner,
uint64 timestampExpirySeconds
)
ERC721M(
collectionName,
collectionSymbol,
tokenURISuffix,
maxMintableSupply,
globalWalletLimit,
cosigner,
timestampExpirySeconds
)
{
_canIncreaseMaxMintableSupply = true;
}

/**
* @dev Return true if max mintable supply can be increased.
*/
function getCanIncreaseMaxMintableSupply() external view returns (bool) {
return _canIncreaseMaxMintableSupply;
}

/**
* @dev Makes _canIncreaseMaxMintableSupply false permanently.
*/
function disableIncreaseMaxMintableSupply() external onlyOwner {
_canIncreaseMaxMintableSupply = false;
emit DisableIncreaseMaxMintableSupply();
}

/**
* @dev Sets maximum mintable supply.
*
* New supply cannot be larger than the old, unless _canIncreaseMaxMintableSupply is true.
*/
function setMaxMintableSupply(uint256 maxMintableSupply)
external
override
onlyOwner
{
if (
!_canIncreaseMaxMintableSupply &&
maxMintableSupply > _maxMintableSupply
) {
revert CannotIncreaseMaxMintableSupply();
}
_maxMintableSupply = maxMintableSupply;
emit SetMaxMintableSupply(maxMintableSupply);
}
}
4 changes: 4 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ task('deploy', 'Deploy ERC721M')
'cosigner address (0x00...000 if not using cosign)',
'0x0000000000000000000000000000000000000000',
)
.addFlag(
'increasesupply',
'whether or not to enable increasing supply behavior',
)
.setAction(deploy);

task('setBaseURI', 'Set the base uri')
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion scripts/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
export const ContractDetails = {
ERC721M: { name: 'ERC721M' }, // The contract of direct sales
BucketAuction: { name: 'BucketAuction' }, // The contract of bucket auctions
};
ERC721MIncreasableSupply: { name: 'ERC721MIncreasableSupply' }, // ERC721M with increasable supply
} as const;
16 changes: 10 additions & 6 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ export interface IDeployParams {
globalwalletlimit: string;
cosigner?: string;
timestampexpiryseconds?: number;
increasesupply?: boolean;
}

export const deploy = async (
args: IDeployParams,
hre: HardhatRuntimeEnvironment,
) => {
// Compile again in case we have a coverage build (binary too large to deploy)
await hre.run('compile');

const contractName = args.increasesupply
? ContractDetails.ERC721MIncreasableSupply.name
: ContractDetails.ERC721M.name;
console.log(
`Going to deploy ${ContractDetails.ERC721M.name} with params`,
`Going to deploy ${contractName} with params`,
JSON.stringify(args, null, 2),
);

const ERC721M = await hre.ethers.getContractFactory(
ContractDetails.ERC721M.name,
);
const ERC721M = await hre.ethers.getContractFactory(contractName);

const erc721M = await ERC721M.deploy(
args.name,
Expand All @@ -41,5 +45,5 @@ export const deploy = async (

await erc721M.deployed();

console.log(`${ContractDetails.ERC721M.name} deployed to:`, erc721M.address);
console.log(`${contractName} deployed to:`, erc721M.address);
};
40 changes: 40 additions & 0 deletions test/ERC721MIncreasableSupply.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ERC721MIncreasableSupply } from '../typechain-types';
import { ethers } from 'hardhat';
import { expect } from 'chai';

describe('ERC721MIncreasableSupply', () => {
let contract: ERC721MIncreasableSupply;

beforeEach(async () => {
const factory = await ethers.getContractFactory('ERC721MIncreasableSupply');
contract = await factory.deploy(
'test',
'TEST',
'.json',
1000,
0,
ethers.constants.AddressZero,
300,
);
const [owner] = await ethers.getSigners();
contract = contract.connect(owner);
await contract.deployed();
});

it('can increase max mintable supply until disableIncreaseMaxMintableSupply called', async () => {
const currentSupply = await contract.getMaxMintableSupply();
expect(await contract.getCanIncreaseMaxMintableSupply()).to.eq(true);
await expect(contract.setMaxMintableSupply(currentSupply.add(1000)))
.to.emit(contract, 'SetMaxMintableSupply')
.withArgs(currentSupply.toNumber() + 1000);

await expect(contract.disableIncreaseMaxMintableSupply()).to.emit(
contract,
'DisableIncreaseMaxMintableSupply',
);
expect(await contract.getCanIncreaseMaxMintableSupply()).to.eq(false);
await expect(
contract.setMaxMintableSupply(currentSupply.add(2000)),
).to.be.revertedWith('CannotIncreaseMaxMintableSupply');
});
});

0 comments on commit 6fcd65f

Please sign in to comment.