// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.6.12; // Imports import "./BalancerConstants.sol"; /** * @author Balancer Labs * @title SafeMath - wrap Solidity operators to prevent underflow/overflow * @dev badd and bsub are basically identical to OpenZeppelin SafeMath; mul/div have extra checks */ library BalancerSafeMath { /** * @notice Safe addition * @param a - first operand * @param b - second operand * @dev if we are adding b to a, the resulting sum must be greater than a * @return - sum of operands; throws if overflow */ function badd(uint a, uint b) internal pure returns (uint) { uint c = a + b; require(c >= a, "ERR_ADD_OVERFLOW"); return c; } /** * @notice Safe unsigned subtraction * @param a - first operand * @param b - second operand * @dev Do a signed subtraction, and check that it produces a positive value * (i.e., a - b is valid if b <= a) * @return - a - b; throws if underflow */ function bsub(uint a, uint b) internal pure returns (uint) { (uint c, bool negativeResult) = bsubSign(a, b); require(!negativeResult, "ERR_SUB_UNDERFLOW"); return c; } /** * @notice Safe signed subtraction * @param a - first operand * @param b - second operand * @dev Do a signed subtraction * @return - difference between a and b, and a flag indicating a negative result * (i.e., a - b if a is greater than or equal to b; otherwise b - a) */ function bsubSign(uint a, uint b) internal pure returns (uint, bool) { if (b <= a) { return (a - b, false); } else { return (b - a, true); } } /** * @notice Safe multiplication * @param a - first operand * @param b - second operand * @dev Multiply safely (and efficiently), rounding down * @return - product of operands; throws if overflow or rounding error */ function bmul(uint a, uint b) internal pure returns (uint) { // Gas optimization (see github.com/OpenZeppelin/openzeppelin-contracts/pull/522) if (a == 0) { return 0; } // Standard overflow check: a/a*b=b uint c0 = a * b; require(c0 / a == b, "ERR_MUL_OVERFLOW"); // Round to 0 if x*y < BONE/2? uint c1 = c0 + (BalancerConstants.BONE / 2); require(c1 >= c0, "ERR_MUL_OVERFLOW"); uint c2 = c1 / BalancerConstants.BONE; return c2; } /** * @notice Safe division * @param dividend - first operand * @param divisor - second operand * @dev Divide safely (and efficiently), rounding down * @return - quotient; throws if overflow or rounding error */ function bdiv(uint dividend, uint divisor) internal pure returns (uint) { require(divisor != 0, "ERR_DIV_ZERO"); // Gas optimization if (dividend == 0){ return 0; } uint c0 = dividend * BalancerConstants.BONE; require(c0 / dividend == BalancerConstants.BONE, "ERR_DIV_INTERNAL"); // bmul overflow uint c1 = c0 + (divisor / 2); require(c1 >= c0, "ERR_DIV_INTERNAL"); // badd require uint c2 = c1 / divisor; return c2; } /** * @notice Safe unsigned integer modulo * @dev Returns the remainder of dividing two unsigned integers. * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * @param dividend - first operand * @param divisor - second operand -- cannot be zero * @return - quotient; throws if overflow or rounding error */ function bmod(uint dividend, uint divisor) internal pure returns (uint) { require(divisor != 0, "ERR_MODULO_BY_ZERO"); return dividend % divisor; } /** * @notice Safe unsigned integer max * @dev Returns the greater of the two input values * * @param a - first operand * @param b - second operand * @return - the maximum of a and b */ function bmax(uint a, uint b) internal pure returns (uint) { return a >= b ? a : b; } /** * @notice Safe unsigned integer min * @dev returns b, if b < a; otherwise returns a * * @param a - first operand * @param b - second operand * @return - the lesser of the two input values */ function bmin(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } /** * @notice Safe unsigned integer average * @dev Guard against (a+b) overflow by dividing each operand separately * * @param a - first operand * @param b - second operand * @return - the average of the two values */ function baverage(uint a, uint b) internal pure returns (uint) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } /** * @notice Babylonian square root implementation * @dev (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) * @param y - operand * @return z - the square root result */ function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }