Optimize safe casting of signed numbers (#3565)

pull/3569/head
Igor Żuk 3 years ago committed by GitHub
parent d3ff81b37f
commit 580b7ab816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 186
      contracts/utils/math/SafeCast.sol
  3. 6
      scripts/generate/templates/SafeCast.js

@ -10,6 +10,7 @@
* `ERC721`: optimize transfers by making approval clearing implicit instead of emitting an event. ([#3481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3481)) * `ERC721`: optimize transfers by making approval clearing implicit instead of emitting an event. ([#3481](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3481))
* `ERC721`: optimize burn by making approval clearing implicit instead of emitting an event. ([#3538](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3538)) * `ERC721`: optimize burn by making approval clearing implicit instead of emitting an event. ([#3538](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3538))
* `ReentrancyGuard`: Reduce code size impact of the modifier by using internal functions. ([#3515](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3515)) * `ReentrancyGuard`: Reduce code size impact of the modifier by using internal functions. ([#3515](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3515))
* `SafeCast`: optimize downcasting of signed integers. ([#3565](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3565))
### Compatibility Note ### Compatibility Note

@ -573,9 +573,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt248(int256 value) internal pure returns (int248) { function toInt248(int256 value) internal pure returns (int248 downcasted) {
require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits"); downcasted = int248(value);
return int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
} }
/** /**
@ -591,9 +591,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt240(int256 value) internal pure returns (int240) { function toInt240(int256 value) internal pure returns (int240 downcasted) {
require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits"); downcasted = int240(value);
return int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
} }
/** /**
@ -609,9 +609,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt232(int256 value) internal pure returns (int232) { function toInt232(int256 value) internal pure returns (int232 downcasted) {
require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits"); downcasted = int232(value);
return int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
} }
/** /**
@ -627,9 +627,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt224(int256 value) internal pure returns (int224) { function toInt224(int256 value) internal pure returns (int224 downcasted) {
require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits"); downcasted = int224(value);
return int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
} }
/** /**
@ -645,9 +645,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt216(int256 value) internal pure returns (int216) { function toInt216(int256 value) internal pure returns (int216 downcasted) {
require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits"); downcasted = int216(value);
return int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
} }
/** /**
@ -663,9 +663,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt208(int256 value) internal pure returns (int208) { function toInt208(int256 value) internal pure returns (int208 downcasted) {
require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits"); downcasted = int208(value);
return int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
} }
/** /**
@ -681,9 +681,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt200(int256 value) internal pure returns (int200) { function toInt200(int256 value) internal pure returns (int200 downcasted) {
require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits"); downcasted = int200(value);
return int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
} }
/** /**
@ -699,9 +699,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt192(int256 value) internal pure returns (int192) { function toInt192(int256 value) internal pure returns (int192 downcasted) {
require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits"); downcasted = int192(value);
return int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
} }
/** /**
@ -717,9 +717,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt184(int256 value) internal pure returns (int184) { function toInt184(int256 value) internal pure returns (int184 downcasted) {
require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits"); downcasted = int184(value);
return int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
} }
/** /**
@ -735,9 +735,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt176(int256 value) internal pure returns (int176) { function toInt176(int256 value) internal pure returns (int176 downcasted) {
require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits"); downcasted = int176(value);
return int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
} }
/** /**
@ -753,9 +753,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt168(int256 value) internal pure returns (int168) { function toInt168(int256 value) internal pure returns (int168 downcasted) {
require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits"); downcasted = int168(value);
return int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
} }
/** /**
@ -771,9 +771,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt160(int256 value) internal pure returns (int160) { function toInt160(int256 value) internal pure returns (int160 downcasted) {
require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits"); downcasted = int160(value);
return int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
} }
/** /**
@ -789,9 +789,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt152(int256 value) internal pure returns (int152) { function toInt152(int256 value) internal pure returns (int152 downcasted) {
require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits"); downcasted = int152(value);
return int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
} }
/** /**
@ -807,9 +807,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt144(int256 value) internal pure returns (int144) { function toInt144(int256 value) internal pure returns (int144 downcasted) {
require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits"); downcasted = int144(value);
return int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
} }
/** /**
@ -825,9 +825,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt136(int256 value) internal pure returns (int136) { function toInt136(int256 value) internal pure returns (int136 downcasted) {
require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits"); downcasted = int136(value);
return int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
} }
/** /**
@ -843,9 +843,9 @@ library SafeCast {
* *
* _Available since v3.1._ * _Available since v3.1._
*/ */
function toInt128(int256 value) internal pure returns (int128) { function toInt128(int256 value) internal pure returns (int128 downcasted) {
require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); downcasted = int128(value);
return int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
} }
/** /**
@ -861,9 +861,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt120(int256 value) internal pure returns (int120) { function toInt120(int256 value) internal pure returns (int120 downcasted) {
require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits"); downcasted = int120(value);
return int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
} }
/** /**
@ -879,9 +879,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt112(int256 value) internal pure returns (int112) { function toInt112(int256 value) internal pure returns (int112 downcasted) {
require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits"); downcasted = int112(value);
return int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
} }
/** /**
@ -897,9 +897,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt104(int256 value) internal pure returns (int104) { function toInt104(int256 value) internal pure returns (int104 downcasted) {
require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits"); downcasted = int104(value);
return int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
} }
/** /**
@ -915,9 +915,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt96(int256 value) internal pure returns (int96) { function toInt96(int256 value) internal pure returns (int96 downcasted) {
require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits"); downcasted = int96(value);
return int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
} }
/** /**
@ -933,9 +933,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt88(int256 value) internal pure returns (int88) { function toInt88(int256 value) internal pure returns (int88 downcasted) {
require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits"); downcasted = int88(value);
return int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
} }
/** /**
@ -951,9 +951,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt80(int256 value) internal pure returns (int80) { function toInt80(int256 value) internal pure returns (int80 downcasted) {
require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits"); downcasted = int80(value);
return int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
} }
/** /**
@ -969,9 +969,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt72(int256 value) internal pure returns (int72) { function toInt72(int256 value) internal pure returns (int72 downcasted) {
require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits"); downcasted = int72(value);
return int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
} }
/** /**
@ -987,9 +987,9 @@ library SafeCast {
* *
* _Available since v3.1._ * _Available since v3.1._
*/ */
function toInt64(int256 value) internal pure returns (int64) { function toInt64(int256 value) internal pure returns (int64 downcasted) {
require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); downcasted = int64(value);
return int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
} }
/** /**
@ -1005,9 +1005,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt56(int256 value) internal pure returns (int56) { function toInt56(int256 value) internal pure returns (int56 downcasted) {
require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits"); downcasted = int56(value);
return int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
} }
/** /**
@ -1023,9 +1023,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt48(int256 value) internal pure returns (int48) { function toInt48(int256 value) internal pure returns (int48 downcasted) {
require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits"); downcasted = int48(value);
return int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
} }
/** /**
@ -1041,9 +1041,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt40(int256 value) internal pure returns (int40) { function toInt40(int256 value) internal pure returns (int40 downcasted) {
require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits"); downcasted = int40(value);
return int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
} }
/** /**
@ -1059,9 +1059,9 @@ library SafeCast {
* *
* _Available since v3.1._ * _Available since v3.1._
*/ */
function toInt32(int256 value) internal pure returns (int32) { function toInt32(int256 value) internal pure returns (int32 downcasted) {
require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); downcasted = int32(value);
return int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
} }
/** /**
@ -1077,9 +1077,9 @@ library SafeCast {
* *
* _Available since v4.7._ * _Available since v4.7._
*/ */
function toInt24(int256 value) internal pure returns (int24) { function toInt24(int256 value) internal pure returns (int24 downcasted) {
require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits"); downcasted = int24(value);
return int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
} }
/** /**
@ -1095,9 +1095,9 @@ library SafeCast {
* *
* _Available since v3.1._ * _Available since v3.1._
*/ */
function toInt16(int256 value) internal pure returns (int16) { function toInt16(int256 value) internal pure returns (int16 downcasted) {
require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); downcasted = int16(value);
return int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
} }
/** /**
@ -1113,9 +1113,9 @@ library SafeCast {
* *
* _Available since v3.1._ * _Available since v3.1._
*/ */
function toInt8(int256 value) internal pure returns (int8) { function toInt8(int256 value) internal pure returns (int8 downcasted) {
require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); downcasted = int8(value);
return int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
} }
/** /**

@ -114,9 +114,9 @@ const toIntDownCast = length => `\
* *
* _Available since v${version('toInt(int)', length)}._ * _Available since v${version('toInt(int)', length)}._
*/ */
function toInt${length}(int256 value) internal pure returns (int${length}) { function toInt${length}(int256 value) internal pure returns (int${length} downcasted) {
require(value >= type(int${length}).min && value <= type(int${length}).max, "SafeCast: value doesn't fit in ${length} bits"); downcasted = int${length}(value);
return int${length}(value); require(downcasted == value, "SafeCast: value doesn't fit in ${length} bits");
} }
`; `;
/* eslint-enable max-len */ /* eslint-enable max-len */

Loading…
Cancel
Save