โœ”๏ธGas Saving Technique 1: Unchecked Arithmetic

Introduction

With the introduction of Solidity version 0.8 and above, automatic checks for arithmetic overflow and underflow have been incorporated. While these checks enhance security by preventing unexpected behavior, they also consume additional gas for each operation. In scenarios where overflow or underflow is impossible due to the logic of the contract, these automatic checks become unnecessary gas expenditures. The unchecked directive in Solidity allows developers to bypass these checks, conserving gas.

Vulnerability Details & Impact

Automatically embedded overflow and underflow checks for arithmetic operations in Solidity v0.8+ incur extra gas costs for each transaction. By carefully deploying the unchecked directive in operations where overflow or underflow is improbable, developers can optimize contracts for gas efficiency without sacrificing security.

How to Implement unchecked Directive for Gas Savings

Understanding the unchecked Block

Solidityโ€™s unchecked block is utilized to circumvent automatic overflow and underflow checks on arithmetic operations. Within the unchecked block, arithmetic calculations do not trigger these automatic checks, which results in saved gas.

Hereโ€™s a syntactical demonstration:

solidityCopy code// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract GasSaver {
    uint256 public count;
    
    function increment(uint256 amount) public {
        unchecked {
            // Inside this block, overflow checks are disabled
            count += amount;
        }
    }
}

Practical Example: Loop Increment Optimization

Consider a for loop where you're certain that the loop variable wonโ€™t cause an overflow. By employing the unchecked directive, you can increment the loop variable without incurring the gas costs of overflow checks.

Below is a code snippet demonstrating this:

solidityCopy code// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract LoopGasSaver {
    function saveGasInLoop(uint256 iterations) public pure returns (uint256) {
        uint256 sum = 0;
        unchecked {
            for (uint256 i = 0; i < iterations; i++) {
                // Overflow check is skipped for i++, saving gas per iteration
                sum += i;
            }
        }
        return sum;
    }
}
  1. Identify Safe Operations: Recognize arithmetic operations where overflow/underflow cannot occur.

  2. Implement unchecked: Surround these safe operations with the unchecked block.

  3. Test Thoroughly: Conduct rigorous testing to ensure that the identified operations are truly safe from overflow and underflow.

Conclusion

While the unchecked directive offers a mechanism for gas optimization, it must be used with caution. Misuse of unchecked can expose contracts to security vulnerabilities. Thorough testing and careful consideration are imperative when deploying this directive to ensure that security is not compromised for the sake of gas efficiency.

References and examples:

https://docs.soliditylang.org/en/v0.8.10/control-structures.html#checked-or-unchecked-arithmetic

[G-01] Adding unchecked directive can save gas - Unchecked

Last updated