// SPDX-License-Identifier: agpl-3.0 pragma solidity 0.6.12; import {Errors} from '../Errors.sol'; /** * @title PercentageMath library * @author Aave * @notice Provides functions to perform calculations of portions * @dev Percentages are defined in basis points. The precision is indicated by ONE * @dev Operations are rounded half up **/ library PercentageMath { uint16 constant BP = 1; // basis point uint16 constant PCT = 100 * BP; // basis points per percentage point uint16 constant ONE = 100 * PCT; // basis points per 1 (100%) uint16 constant HALF_ONE = ONE / 2; // deprecated uint256 constant PERCENTAGE_FACTOR = ONE; //percentage plus two decimals /** * @dev Executes a percentage multiplication * @param value The value of which the percentage needs to be calculated * @param factor Basis points of the value to be calculated * @return The percentage of value **/ function percentMul(uint256 value, uint256 factor) internal pure returns (uint256) { if (value == 0 || factor == 0) { return 0; } require(value <= (type(uint256).max - HALF_ONE) / factor, Errors.MATH_MULTIPLICATION_OVERFLOW); return (value * factor + HALF_ONE) / ONE; } /** * @dev Executes a percentage division * @param value The value of which the percentage needs to be calculated * @param factor Basis points of the value to be calculated * @return The value divided the percentage **/ function percentDiv(uint256 value, uint256 factor) internal pure returns (uint256) { require(factor != 0, Errors.MATH_DIVISION_BY_ZERO); uint256 halfFactor = factor >> 1; require(value <= (type(uint256).max - halfFactor) / ONE, Errors.MATH_MULTIPLICATION_OVERFLOW); return (value * ONE + halfFactor) / factor; } function percentOf(uint256 value, uint256 base) internal pure returns (uint256) { require(base != 0, Errors.MATH_DIVISION_BY_ZERO); if (value == 0) { return 0; } require(value <= (type(uint256).max - HALF_ONE) / ONE, Errors.MATH_MULTIPLICATION_OVERFLOW); return (value * ONE + (base >> 1)) / base; } }