-
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
Add ERC1155.totalSupply that returns overall supply count #3962
Add ERC1155.totalSupply that returns overall supply count #3962
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is something terribly wrong here:
totalAmount
starts at 0- you increase is for every new token
- you add that sum to the
_totalSupplyAll
- you then increase it again (without resetting it) with every token being burned
- you decrease that from the
_totalSupplyAll
So if someone transfers from 0 to 0 (which would happen with the new _update transition), you would mess up the _totalSupplyAll :/
Also, on a completely different point, this change will restrict a total of 2**256-1
tokens minted accross ALL ids. This is a significant change, which needs to be documented.
should be
|
Thanks for pointing this out, |
We should be using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change on 2 fronts:
- this change restrict the ability to mint token, imposing a new limit that was not there before
- upgrading from the previous version to this is ok from a storage layout point of view... but it would lead to inconsistent values (and even mint reverting)
For the mint reverting:
- you already have 100 token
- you upgrade, the totalSupply() is 0
- you burn 1 token ... decrease is unchecked so is overflows
- totalSupply() is now 2**256-1
- you try to mint 1 token ... increase is checked and reverts because of the overflow
Yeah I share the concerns. Let's move this to 5.0. @JulissaDantes Please rebase or rewrite this on top of next-v5.0. |
5f5bc99
to
a27ba26
Compare
Ready. |
for (uint256 i = 0; i < ids.length; ++i) { | ||
uint256 id = ids[i]; | ||
uint256 amount = amounts[i]; | ||
uint256 supply = _totalSupply[id]; | ||
require(supply >= amount, "ERC1155: burn amount exceeds totalSupply"); | ||
unchecked { | ||
_totalSupply[id] = supply - amount; | ||
totalBurnAmount += amount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't obvious to me why this variable won't overflow. We need to add the explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It comes from two inequalities:
amounts[i] <= totalSupply(i)
(from the require on line 67)sum(totalSupply(i)) <= totalSupplyAll
(contract invariant)
so totalBurnAmount = sum(amounts[i]) <= sum(totalSupply(i)) <= totalSupplyAll <= 2*256-1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically we could even get rid of the check on line 67 if we were to check balance >= amount
before. (the check if done after, because this is the "pre" hook)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Amxx I think we didn't do that because we were concerned what would happen if ERC1155Supply was added in an upgrade... I wish we had a more consistent way of dealing with that kind of concern.
🦋 Changeset detectedLatest commit: 2ddaded The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
}); | ||
expect(await this.token.methods['totalSupply()']()).to.be.bignumber.equal('0'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason not to check totalSupply(firstTokenId)
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Is checked multiple times before this test I did not think we needed it, but do you think we should include it for a no-op test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, totalSupply(uint256)
is not checked for no-op transfers from zero to zero. I added the test.
Co-authored-by: Francisco <frangio.1@gmail.com>
Fixes #3301
This PR adds a tracking storage variable inside the
ERC1155Supply
contract, to keep track of the amount of all the circulating tokens, without having to check each tokenId's total supply.PR Checklist