Math.sol 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
  3. // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.3.0/contracts/utils/math/Math.sol
  4. // note: We only copy the subset of the library methods that we need.
  5. pragma solidity ^0.8.0;
  6. library Math {
  7. /// @dev division or modulo by zero
  8. uint256 internal constant DIVISION_BY_ZERO = 0x12;
  9. /// @dev arithmetic underflow or overflow
  10. uint256 internal constant UNDER_OVERFLOW = 0x11;
  11. /**
  12. * @dev Return the 512-bit multiplication of two uint256.
  13. *
  14. * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
  15. */
  16. function mul512(
  17. uint256 a,
  18. uint256 b
  19. ) internal pure returns (uint256 high, uint256 low) {
  20. // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
  21. // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
  22. // variables such that product = high * 2²⁵⁶ + low.
  23. /// @solidity memory-safe-assembly
  24. assembly {
  25. let mm := mulmod(a, b, not(0))
  26. low := mul(a, b)
  27. high := sub(sub(mm, low), lt(mm, low))
  28. }
  29. }
  30. /**
  31. * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
  32. *
  33. * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
  34. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
  35. * one branch when needed, making this function more expensive.
  36. */
  37. function ternary(
  38. bool condition,
  39. uint256 a,
  40. uint256 b
  41. ) internal pure returns (uint256) {
  42. unchecked {
  43. // branchless ternary works because:
  44. // b ^ (a ^ b) == a
  45. // b ^ 0 == b
  46. return b ^ ((a ^ b) * toUint(condition));
  47. }
  48. }
  49. /**
  50. * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
  51. */
  52. function toUint(bool b) internal pure returns (uint256 u) {
  53. /// @solidity memory-safe-assembly
  54. assembly {
  55. u := iszero(iszero(b))
  56. }
  57. }
  58. /// @dev Reverts with a panic code. Recommended to use with
  59. /// the internal constants with predefined codes.
  60. function panic(uint256 code) internal pure {
  61. /// @solidity memory-safe-assembly
  62. assembly {
  63. mstore(0x00, 0x4e487b71)
  64. mstore(0x20, code)
  65. revert(0x1c, 0x24)
  66. }
  67. }
  68. /**
  69. * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
  70. * denominator == 0.
  71. *
  72. * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
  73. * Uniswap Labs also under MIT license.
  74. */
  75. function mulDiv(
  76. uint256 x,
  77. uint256 y,
  78. uint256 denominator
  79. ) internal pure returns (uint256 result) {
  80. unchecked {
  81. (uint256 high, uint256 low) = mul512(x, y);
  82. // Handle non-overflow cases, 256 by 256 division.
  83. if (high == 0) {
  84. // Solidity will revert if denominator == 0, unlike the div opcode on its own.
  85. // The surrounding unchecked block does not change this fact.
  86. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
  87. return low / denominator;
  88. }
  89. // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
  90. if (denominator <= high) {
  91. panic(
  92. ternary(denominator == 0, DIVISION_BY_ZERO, UNDER_OVERFLOW)
  93. );
  94. }
  95. ///////////////////////////////////////////////
  96. // 512 by 256 division.
  97. ///////////////////////////////////////////////
  98. // Make division exact by subtracting the remainder from [high low].
  99. uint256 remainder;
  100. /// @solidity memory-safe-assembly
  101. assembly {
  102. // Compute remainder using mulmod.
  103. remainder := mulmod(x, y, denominator)
  104. // Subtract 256 bit number from 512 bit number.
  105. high := sub(high, gt(remainder, low))
  106. low := sub(low, remainder)
  107. }
  108. // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
  109. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
  110. uint256 twos = denominator & (0 - denominator);
  111. /// @solidity memory-safe-assembly
  112. assembly {
  113. // Divide denominator by twos.
  114. denominator := div(denominator, twos)
  115. // Divide [high low] by twos.
  116. low := div(low, twos)
  117. // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
  118. twos := add(div(sub(0, twos), twos), 1)
  119. }
  120. // Shift in bits from high into low.
  121. low |= high * twos;
  122. // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
  123. // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
  124. // four bits. That is, denominator * inv ≡ 1 mod 2⁴.
  125. uint256 inverse = (3 * denominator) ^ 2;
  126. // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
  127. // works in modular arithmetic, doubling the correct bits in each step.
  128. inverse *= 2 - denominator * inverse; // inverse mod 2⁸
  129. inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
  130. inverse *= 2 - denominator * inverse; // inverse mod 2³²
  131. inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
  132. inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
  133. inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
  134. // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
  135. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is
  136. // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
  137. // is no longer required.
  138. result = low * inverse;
  139. return result;
  140. }
  141. }
  142. // /**
  143. // * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.
  144. // */
  145. // function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
  146. // return mulDiv(x, y, denominator) + toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
  147. // }
  148. /**
  149. * @dev Returns the absolute unsigned value of a signed value.
  150. */
  151. function abs(int256 n) internal pure returns (uint256) {
  152. unchecked {
  153. // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson.
  154. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift,
  155. // taking advantage of the most significant (or "sign" bit) in two's complement representation.
  156. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result,
  157. // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative).
  158. int256 mask = n >> 255;
  159. // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it.
  160. return uint256((n + mask) ^ mask);
  161. }
  162. }
  163. /**
  164. * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
  165. */
  166. function tryMul(
  167. uint256 a,
  168. uint256 b
  169. ) internal pure returns (bool success, uint256 result) {
  170. unchecked {
  171. uint256 c = a * b;
  172. /// @solidity memory-safe-assembly
  173. assembly {
  174. // Only true when the multiplication doesn't overflow
  175. // (c / a == b) || (a == 0)
  176. success := or(eq(div(c, a), b), iszero(a))
  177. }
  178. // equivalent to: success ? c : 0
  179. result = c * toUint(success);
  180. }
  181. }
  182. /**
  183. * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
  184. */
  185. function tryDiv(
  186. uint256 a,
  187. uint256 b
  188. ) internal pure returns (bool success, uint256 result) {
  189. unchecked {
  190. success = b > 0;
  191. /// @solidity memory-safe-assembly
  192. assembly {
  193. // The `DIV` opcode returns zero when the denominator is 0.
  194. result := div(a, b)
  195. }
  196. }
  197. }
  198. }