Ver código fonte

Tokens: wrap safe substractions in uchecked block (#2669)

* Tokens: wrap definitely safe subs in unchecked

* Add change in changelog

Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Vladislav 4 anos atrás
pai
commit
5f7eda1f98

+ 1 - 0
CHANGELOG.md

@@ -6,6 +6,7 @@
  * Enumerables: Improve gas cost of removal in `EnumerableSet` and `EnumerableMap`.
  * Enumerables: Improve gas cost of lookup in `EnumerableSet` and `EnumerableMap`.
  * `Counter`: add a reset method. ([#2678](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2678))
+ * Tokens: Wrap definitely safe subtractions in `unchecked` blocks. 
 
 ## 4.1.0 (2021-04-29)
 

+ 12 - 4
contracts/token/ERC1155/ERC1155.sol

@@ -187,7 +187,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
 
         uint256 fromBalance = _balances[id][from];
         require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
-        _balances[id][from] = fromBalance - amount;
+        unchecked {
+            _balances[id][from] = fromBalance - amount;
+        }
         _balances[id][to] += amount;
 
         emit TransferSingle(operator, from, to, id, amount);
@@ -228,7 +230,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
 
             uint256 fromBalance = _balances[id][from];
             require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
-            _balances[id][from] = fromBalance - amount;
+            unchecked {
+                _balances[id][from] = fromBalance - amount;
+            }
             _balances[id][to] += amount;
         }
 
@@ -327,7 +331,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
 
         uint256 accountBalance = _balances[id][account];
         require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
-        _balances[id][account] = accountBalance - amount;
+        unchecked {
+            _balances[id][account] = accountBalance - amount;
+        }
 
         emit TransferSingle(operator, account, address(0), id, amount);
     }
@@ -353,7 +359,9 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
 
             uint256 accountBalance = _balances[id][account];
             require(accountBalance >= amount, "ERC1155: burn amount exceeds balance");
-            _balances[id][account] = accountBalance - amount;
+            unchecked {
+                _balances[id][account] = accountBalance - amount;
+            }
         }
 
         emit TransferBatch(operator, account, address(0), ids, amounts);

+ 13 - 5
contracts/token/ERC20/ERC20.sol

@@ -150,7 +150,9 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
 
         uint256 currentAllowance = _allowances[sender][_msgSender()];
         require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
-        _approve(sender, _msgSender(), currentAllowance - amount);
+        unchecked {
+            _approve(sender, _msgSender(), currentAllowance - amount);
+        }
 
         return true;
     }
@@ -189,7 +191,9 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
     function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
         uint256 currentAllowance = _allowances[_msgSender()][spender];
         require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
-        _approve(_msgSender(), spender, currentAllowance - subtractedValue);
+        unchecked {
+            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
+        }
 
         return true;
     }
@@ -216,7 +220,9 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
 
         uint256 senderBalance = _balances[sender];
         require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
-        _balances[sender] = senderBalance - amount;
+        unchecked {
+            _balances[sender] = senderBalance - amount;
+        }
         _balances[recipient] += amount;
 
         emit Transfer(sender, recipient, amount);
@@ -259,8 +265,10 @@ contract ERC20 is Context, IERC20, IERC20Metadata {
 
         uint256 accountBalance = _balances[account];
         require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
-        _balances[account] = accountBalance - amount;
-        _totalSupply -= amount;
+        unchecked {
+            _balances[account] = accountBalance - amount;
+            _totalSupply -= amount;
+        }
 
         emit Transfer(account, address(0), amount);
     }

+ 3 - 1
contracts/token/ERC20/extensions/ERC20Burnable.sol

@@ -34,7 +34,9 @@ abstract contract ERC20Burnable is Context, ERC20 {
     function burnFrom(address account, uint256 amount) public virtual {
         uint256 currentAllowance = allowance(account, _msgSender());
         require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
-        _approve(account, _msgSender(), currentAllowance - amount);
+        unchecked {
+            _approve(account, _msgSender(), currentAllowance - amount);
+        }
         _burn(account, amount);
     }
 }

+ 7 - 3
contracts/token/ERC777/ERC777.sol

@@ -419,8 +419,10 @@ contract ERC777 is Context, IERC777, IERC20 {
         // Update state variables
         uint256 fromBalance = _balances[from];
         require(fromBalance >= amount, "ERC777: burn amount exceeds balance");
-        _balances[from] = fromBalance - amount;
-        _totalSupply -= amount;
+        unchecked {
+            _balances[from] = fromBalance - amount;
+            _totalSupply -= amount;
+        }
 
         emit Burned(operator, from, amount, data, operatorData);
         emit Transfer(from, address(0), amount);
@@ -440,7 +442,9 @@ contract ERC777 is Context, IERC777, IERC20 {
 
         uint256 fromBalance = _balances[from];
         require(fromBalance >= amount, "ERC777: transfer amount exceeds balance");
-        _balances[from] = fromBalance - amount;
+        unchecked {
+            _balances[from] = fromBalance - amount;
+        }
         _balances[to] += amount;
 
         emit Sent(operator, from, to, amount, userData, operatorData);