openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

Use unchecked to improve gas usage of ERC721

Open Amxx opened this issue 3 years ago • 4 comments

Following the logic in described in https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3512#issuecomment-1172614573.

  • _balances are private
  • _balances are only increased/decreased when tokens are minted, burned, or transferred

A balance cannot decrease below 0 because that would require transferring/burning more tokens out of a wallet than were transferred/minted to this wallet in the first place.

The balance cannot overflow, because that would require minting all the tokenIds, and putting them all in the same wallet (there are 2**256 tokenIds, so that would overflow by one). While this is mathematically possible, it is impossible in practice (with token being transferred/minted one at a time)

PR Checklist

  • [ ] Tests
  • [ ] Documentation
  • [ ] Changelog entry

Amxx avatar Jul 01 '22 20:07 Amxx

Given that we want to explore batch minting in ERC721 it seems we should not merge this, as the assumption that minting happens one at a time will be invalidated. Also please include benchmarks, what kind of improvement do you see with this PR?

Use of unchecked should be accompanied by comments explaining why it's safe.

frangio avatar Jul 05 '22 01:07 frangio

Benchmark of the changes (running the transactions in test/token/ERC721/ERC721.test.js) Capture d’écran du 2022-07-06 10-03-21

Amxx avatar Jul 06 '22 08:07 Amxx

I understand that we want to experiment new minting mechanism. However, I believe that these minting mechanisms should remain ERC721 compliant, which means emitting a Transfer event for all the tokens ids. This means that, in practice, it's impossible to mint all the tokens, and the balance increment overflow is not an issue.

Amxx avatar Jul 06 '22 08:07 Amxx

For reference: https://twitter.com/optimizoor/status/1544626818996613120?t=8tV84gD3blTSsxk14EotiQ

TLDR: batch minting should be limited to "not to big batches" ... which means that the limit should never be reached, even minting 10**18 token each time

Amxx avatar Jul 06 '22 10:07 Amxx

I believe once #3611 is merged, the requested changes will no longer be needed.

Amxx avatar Aug 11 '22 15:08 Amxx