Repository: OpenZeppelin/openzeppelin-contracts

Issue #4404: contracts/utils/math: replace "if (A && B)" to save gas fees
Created: 2023-06-29T23:29:39Z
The solidity compiler generates more code for “if (A && B) {}” than for “if (A) {if (B) {} }”.
Our experiment shows that switching from “if (A && B) {}” to “if (A) {if (B) {} }” can save gas fee.
💻 Environment

master branch
📝 Details


  
    
      openzeppelin-contracts/contracts/utils/math/Math.sol
    
    
        Lines 217 to 223
      in
      874c2d3
    
  
  
    

        
          
           function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { 
        

        
          
               uint256 result = mulDiv(x, y, denominator); 
        

        
          
               if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { 
        

        
          
                   result += 1; 
        

        
          
               } 
        

        
          
               return result; 
        

        
          
           } 
        
    
  


Replacing the following code snippet
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }

with
       if (rounding == Rounding.Up) {
            if (mulmod(x, y, denominator) > 0) {
                result += 1;
            }
       }

can save gas fees and does not hurt code readability.
🔢 Code to reproduce bug

Duplicate issue #4408: openzeppelin-contracts-upgradable: replace "if (A && B)" to save gas fees
Created: 2023-07-01T02:24:01Z
The solidity compiler generates more code for “if (A && B) {}” than for “if (A) {if (B) {} }”.
Our experiment shows that switching from “if (A && B) {}” to “if (A) {if (B) {} }” can save gas fee.
💻 Environment

master branch
📝 Details

Similar to issue 4404, there are nine such cases in openzeppelin-contracts-upgradable
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/utils/ArraysUpgradeable.sol#L45
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/token/ERC20/extensions/ERC4626Upgradeable.sol#L97
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol#L69
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/governance/utils/VotesUpgradeable.sol#L203
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/governance/GovernorUpgradeable.sol#L200
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/access/AccessControlDefaultAdminRulesUpgradeable.sol#L121
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/token/ERC20/utils/SafeERC20Upgradeable.sol#L119
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/access/AccessControlDefaultAdminRulesUpgradeable.sol#L154
https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/03b0aeb8e6b0badadbab83003c0456912fa06f89/contracts/utils/math/MathUpgradeable.sol#L218
🔢 Code to reproduce bug

Closing comment (2023-07-01T03:24:19Z): Duplicate of #4404.