question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Why not wrap the ` _balances[to] += amount` instruction in an `unchecked` block?

See original GitHub issue

This issue is related to https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2875, but my question comes from a different angle:

Why not wrap all calculations in the _transfer function in an unchecked block? I’m specifically referring to line 241 in the _transfer function:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/e734b42fc2245b520372bca0099870f40f1e6f38/contracts/token/ERC20/ERC20.sol#L241

It seems to me that the balance of the to account can never overflow (it’s an invariant), due to the fact that the _mint function uses checked arithmetic (and rightly so).

I looked at the tests for the transfer function and couldn’t find a test that checks for an overflow on line 241:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/e734b42fc2245b520372bca0099870f40f1e6f38/test/token/ERC20/ERC20.behavior.js

The only argument that I can think of in favor of keeping the current behavior is the precautionary principle: many people inherit ERC20 and modify it according to their project idea, which in some cases might involve changing the _balances mapping outside of _mint.

Thoughts?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
frangiocommented, Jul 1, 2022

So for the record I want to explain why we did not have this optimization before and why we’re going to merge it now.

The reasoning until now was that we use unchecked when lack of overflow can be proven through local reasoning. For example:

require(amount <= balances[to]);
unchecked {
    balances[to] -= amount;
}

We know b - a will not overflow because a <= b is asserted immediately before.

The property that balances[to] + amount does not overflow is not a local one in this sense. It can’t be shown by reasoning about the function. It can only be proven by reasoning about the entire contract, and observing that: 1) the values in the balances mapping are only increased in _mint, 2) any increase in one account’s balance is reflected in an equivalent increase in the _totalSupply and this is capped by 2**256 thanks to overflow checks, 3) all updates to the balances mapping preserve this invariant (the cap).

What is happening now is we’re relaxing the requirements to use unchecked to allow it when lack of overflow can be proven through reasoning about one file/contract. Note that this is still “local” in another sense, just “less” local than before.

This makes the case for private variables versus internal ones even stronger. We need to be able to guarantee that the balances mapping is not updated outside of this file.

For future reference, this optimization of ~130 gas, in my opinion, only barely meets the threshold to be worth the extra complexity (complexity to prove the correctness of the contract!).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Solidity Documentation - Read the Docs
By default, all arithmetic is checked for under- or overflow, but this can be disabled using the unchecked block, resulting in wrapping ...
Read more >
An Automatic Repair Framework for On-Chain Smart Contracts
Given a vulnerable smart contract, Aroc first automatically generates a patch contract containing secure rules based on the repair template, and ...
Read more >
Zeus: Analyzing Safety of Smart Contracts - Calgary
If the balance in the wallet is less than the amount to be sent, then the owner gets the solution to his puzzle...
Read more >
Banner Finance 9.3.12 User Guide - Hampton University
“Aggregated Data” means any data obtained or generated by Ellucian, including data pertaining to the software, Ellucian's systems and software, and the use...
Read more >
Budget Guidelines and EDC Manual 2022-23.pdf - NJ.gov
Section II provides instructions for accessing the budget software. ... Users should make sure that internet settings do not block pop-ups ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found