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

ERC20 simplification with allowing _transfer() to perform _mint() and _burn() functionalities

Open k06a opened this issue 3 years ago • 8 comments

Let's discuss this opportunity to minimize ERC20 source code.

PR Checklist

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

k06a avatar Jan 14 '22 17:01 k06a

Hello @k06a

I'm really not confortable with this change. In particular, it would allow a dev to call _transfer() internally, and do "mint" or "burn" operation that do not update the totalSupply.

Can you give more details about your usecase ?

I was not here when the decision was taken, but having the mint & burn be separate function from transfer is helping with multiple things:

  • its easy to override mint and burn, and that doesn't add any check in transfer, making sure no additional cost is introduced into the simple transfers (that are the most commonly used operations)
  • it forces the dev to clearly distinguish between these operations and avoid the risk of minting or burning "by mistake"

Amxx avatar Jan 14 '22 20:01 Amxx

@Amxx I see, but this issue could be solved by moving totalSupply modification into the _transfer method. Your points makes sense for me, but what about extracting such a private __transfer method? This would reduce the code size (+compiled size).

k06a avatar Jan 15 '22 08:01 k06a

Having an additional __transfer function would just make everything more confusing. Also, I think we should avoid __ préfixes.

What about leaving everything as now, and adding a _arbitraryTransfer that would redirect to mint, burn or transfer depending on the parameters it receives?

Amxx avatar Jan 15 '22 08:01 Amxx

@Amxx this would work and can be introduced as an extension. But I was thinking about reducing code size of the existing solution.

k06a avatar Jan 15 '22 08:01 k06a

I'm more concerned by the gas cost of executing transactions then by the cost of deployment.

Maybe we should produce number to check the impact of such a change on both

Amxx avatar Jan 15 '22 09:01 Amxx

I agree that both gas impacts are important.

k06a avatar Jan 15 '22 09:01 k06a

I'd like to see the numbers but I believe the bytecode size impact could be significant, and the runtime cost impact may be negligible. The additional cost contains no storage reads or writes as far as I can tell, it's just stack operations and jumps.

I think we have to consider this improvement, and a similar strategy could be valuable in other contracts.

_arbitraryTransfer could be a private function if we prefer to keep the current internal API, which is simpler as it has a single way to do each operation.

frangio avatar Feb 01 '22 20:02 frangio

We are probably going to move forward with this in 5.0 along with the removal of before and after hooks (replaced with "simple" overriding of _transfer). A PR with these changes for ERC721 in #3635.

frangio avatar Sep 19 '22 03:09 frangio

This has been implemented in next-v5.0 in #3838 and #3921.

frangio avatar Jan 23 '23 15:01 frangio