-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ERC1155Supply: Add totalSupply() function that returns overall supply count #3301
Comments
Hello @philipSKYBIT If someone wanted to track the overall token supply, the best way would indeed be to have a The reason why we don't have it is:
|
To be fair, this variable would only get read/written on mints and burns, so I wouldn't entirely rule out adding Before agreeing, I would like to understand the motivation a little more. What page on Etherscan tries to access this function? |
On the Etherscan token page e.g.: It's the same on Polygonscan. We want to be able to show total supply minted so far on a minting dapp page. |
@philipSKYBIT Can you confirm on a testnet Etherscan that if there is a |
https://goerli.etherscan.io/token/0xfA7644E6204B2eeA4C46762Bf82a9570a2054eE8 I minted 2 tokens, and etherscan correctly shows 2 as total supply. I had created and imported // SPDX-License-Identifier: MIT
// Modified version of OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/ERC1155Supply.sol) - added totalSupply overall
pragma solidity ^0.8.0;
// import "../ERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
/**
* @dev Extension of ERC1155 that adds tracking of total supply per id.
*
* Useful for scenarios where Fungible and Non-fungible tokens have to be
* clearly identified. Note: While a totalSupply of 1 might mean the
* corresponding is an NFT, there is no guarantees that no other token with the
* same id are not going to be minted.
*/
abstract contract ERC1155SupplyWithAll is ERC1155 {
mapping(uint256 => uint256) private _totalSupply;
uint256 private _totalSupplyAll;
/**
* @dev Total amount of tokens in with a given id.
*/
function totalSupply(uint256 id) public view virtual returns (uint256) {
return _totalSupply[id];
}
function totalSupply() public view virtual returns (uint256) {
return _totalSupplyAll;
}
/**
* @dev Indicates whether any token exist with a given id, or not.
*/
function exists(uint256 id) public view virtual returns (bool) {
return totalSupply(id) > 0;
}
/**
* @dev See {ERC1155-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual override {
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
if (from == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] += amounts[i];
_totalSupplyAll += amounts[i];
}
}
if (to == address(0)) {
for (uint256 i = 0; i < ids.length; ++i) {
_totalSupply[ids[i]] -= amounts[i];
_totalSupplyAll -= amounts[i];
}
}
}
} |
Feel free to submit a pull request with this change to ERC1155Supply. Note that the code submitted by @philipSKYBIT above is suboptimal because the global supply is updated once for each token in the batch transfer, we should optimize this by accumulating in one variable and writing to storage just once. |
Since I just recently implemented the |
Yes @pcaversaccio, this is something we have identified. See this comment on the PR. Do you feel like this constraint would be cause real issues, or will it remain mostly theoretical. Said differently, do you know any ERC1155 contract where the supply as large enough for this value to overflow ? |
awesome - thx for the link. So am personally not aware of any |
In any case this will never be included by default so users can make an informed decision if they decide to use this functionality with what it entails. I had also proposed to make the total supply number saturate at the max and cause the getter to revert from then on. This would be acceptable if the function is only used off chain but can't be sure about that. |
I wish this was true - how many times will people simply go to OpenZeppelin Wizard, and enable "Supply Tracking" because they read "Keeps track of total supply of tokens." which sounds like a good feature to have and that's it... Reverting with a nice message or custom error would be indeed informative but who knows how people will interact in the future. |
We're with you, making a library without footguns is definitely part of our design philosophy, but at some point we need to treat users like adults too. 😅 In this particular case, the reasoning for me is that this is unlikely to be a problem. If it was likely, say it capped the supply to a low number, then I would not be okay with it. |
Fair enough 😎 - but just for the sake of history, I hereby make a bet that at some time in the future there will be a case where an overflow will happen and it will pose a problem (think of |
Fixed by #3962 in |
🧐 Motivation
ERC1155Supply only counts by token ID. In some cases we may want a general overall count of all tokens that have been minted under the contract. e.g. etherscan and polygonscan tries to call
totalSupply()
when showing information about an NFT, and shows an error on the page if it failed.📝 Details
Having only a count for each token ID in
ERC1155Supply
means to get an overall total count, options are:totalSupply(id)
ERC1155Supply
and within the ERC1155 contract:-- use Counters. But
Counters
cannot increment by more than 1, which we'd want after a batch mint. Here is an issue about this: Allow Counter increment by more than just 1 #3296-- or just use
uint256
instead of bothERC1155Supply
andCounters
I still want to use
ERC1155Supply
as its purpose is supply tracking. I propose to add overloaded functiontotalSupply()
that returns the overall count.Some code that could be added are:
uint256 private _totalSupplyAll;
In
_beforeTokenTransfer
:The text was updated successfully, but these errors were encountered: