0

I'm writing an NFT minting contract with openZeppelin and have 2 functions that can mint tokens. mint and reserveMint. Each function can be invoked independent of each other in various order at various time until either the totalSupply runs out. The reserveMint can be invoked until _reserve runs out.

The issue I'm having is that after all is minted the totalSupply is shown as 29 instead of 30. There are 30 tokens minted. First tokenID starts at 0 and last tokenID ends at 29. This is fine. What can I do to make sure the totalSupply in the contract is 30. I don't want to confuse users who look at the contract thinking that only 29 were minted.

Thank you!

uint256 private _reserve = 10; 
uint256 public constant totalSupply = 20;

function mint(uint256 numberOfTokens) public payable {
    uint256 supply = totalSupply();
    require( numberOfTokens <= 20, "You can mint 20 at a time." );
    require( supply + numberOfTokens < (totalSupply - _reserve), "Exceeds total supply" );
    require( msg.value >= Price * numberOfTokens,  "Ether sent is not correct" );

    for(uint256 i; i < numberOfTokens; i++){
        _safeMint( msg.sender, supply + i );
    }
}
function reserveMint(address _to, uint256 _amount) external onlyOwner() {
    require( _amount <= _reserve, "Exceeds reserved supply" );
    uint256 supply = totalSupply();
    for(uint256 i; i < _amount; i++){
        _safeMint( _to, supply + i );
    }
    _reserve -= _amount;
}
1

Let's take a look at your code for a sec:

uint256 public constant totalSupply = 20;

...

function reserveMint(address _to, uint256 _amount) external onlyOwner() {
    require( _amount <= _reserve, "Exceeds reserved supply" );
    uint256 supply = totalSupply();
    for(uint256 i; i < _amount; i++){
        _safeMint( _to, supply + i );
    }
    _reserve -= _amount;
}

You start out with a totalSupply of 20. The for loop then initializes a variable i. This will be initialized to zero (all variables in Solidity are initialized to their zero-ish representation: 0, address(0), false, etc.). As a result, on the first iteration of the for loop, when _safeMint is called, it will be called with _to and supply + 0 as the arguments, meaning that it's minting to the 20th slot, which was already counted.

You might want to initialize the for loop with:

for(uint256 i=1; i <= _amount; i++){

Instead of initializing i at zero. (There are plenty of other solutions, but that's the one we'd recommend.) Other than that, the code looks like it should work as expected. Happy coding!

3
  • Thanks for the solution but I don't think this will work. If you want to mint 2 or more nfts with either functions if the amount is > 1 then it mints the amount - 1. Which means if you declare you want to mint 2, you get 1.
    – starman
    Aug 3 at 8:32
  • sorry, let me fix that, I forgot to add <= instead of just <
    – Linum Labs
    Aug 3 at 8:49
  • Not a problem. I found the mistake as well. Thanks for your help. I had to add a <= to the max mint require statement as well.
    – starman
    Aug 3 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.