Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What is the benefit of using uncheked?

In OpenZeppelin ERC20 implementation, there is a _transfer method:

function _transfer(
    address sender,
    address recipient,
    uint256 amount
) internal virtual {
    require(sender != address(0), "ERC20: transfer from the zero address");
    require(recipient != address(0), "ERC20: transfer to the zero address");

    _beforeTokenTransfer(sender, recipient, amount);

    uint256 senderBalance = _balances[sender];
    require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
    unchecked {
        _balances[sender] = senderBalance - amount;
    }
    _balances[recipient] += amount;

    emit Transfer(sender, recipient, amount);

    _afterTokenTransfer(sender, recipient, amount);
}

Why do they use uncheked arithmetic for decreasing the balance? I know that in case of unchecked, 2-3 will return 2**256-1 and not case an exception. But why do we need this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

unchecked produces smaller bytecode compared to regular arthimetic operations, as it doesn’t contain the underflow/overflow validation.

So if you want to have a custom error message in case overflow would occur, this code costs less gas to run

uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {

    // no validation here as it's already validated in the `require()` condition
    _balances[sender] = senderBalance - amount;
}

compared to this one

uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");

// redundant validation here
_balances[sender] = senderBalance - amount;

Without the custom message, this would be the cheapest, but still safe, option:

// contains the check and fails without custom message in case of underflow
_balances[sender] -= amount;

And this would be even cheaper compared to the previous one. But it’s unsafe as it doesn’t check for undeflow:

unchecked {
    // UNSAFE, DO NOT USE
    _balances[sender] -= amount;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading