github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/test/contracts/uniswap/v2/FullMath.sol (about)

     1  // SPDX-License-Identifier: CC-BY-4.0
     2  pragma solidity >=0.4.0;
     3  
     4  // taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
     5  // license is CC-BY-4.0
     6  library FullMath {
     7      function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) {
     8          uint256 mm = mulmod(x, y, uint256(-1));
     9          l = x * y;
    10          h = mm - l;
    11          if (mm < l) h -= 1;
    12      }
    13  
    14      function fullDiv(
    15          uint256 l,
    16          uint256 h,
    17          uint256 d
    18      ) private pure returns (uint256) {
    19          uint256 pow2 = d & -d;
    20          d /= pow2;
    21          l /= pow2;
    22          l += h * ((-pow2) / pow2 + 1);
    23          uint256 r = 1;
    24          r *= 2 - d * r;
    25          r *= 2 - d * r;
    26          r *= 2 - d * r;
    27          r *= 2 - d * r;
    28          r *= 2 - d * r;
    29          r *= 2 - d * r;
    30          r *= 2 - d * r;
    31          r *= 2 - d * r;
    32          return l * r;
    33      }
    34  
    35      function mulDiv(
    36          uint256 x,
    37          uint256 y,
    38          uint256 d
    39      ) internal pure returns (uint256) {
    40          (uint256 l, uint256 h) = fullMul(x, y);
    41  
    42          uint256 mm = mulmod(x, y, d);
    43          if (mm > l) h -= 1;
    44          l -= mm;
    45  
    46          if (h == 0) return l / d;
    47  
    48          require(h < d, 'FullMath: FULLDIV_OVERFLOW');
    49          return fullDiv(l, h, d);
    50      }
    51  }