// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library LendingMath { uint256 internal constant FACTOR_SCALE = 1e18; uint256 internal constant SECONDS_PER_YEAR = 365 * 24 * 60 * 60; function principalToBalance(int104 principal, uint256 index) internal pure returns (int256) { return int256(principal) * int256(index) / int256(FACTOR_SCALE); } function balanceToPrincipal(int256 balance, uint256 index) internal pure returns (int104) { return int104((balance * int256(FACTOR_SCALE)) / int256(index)); } function repayAndSupplyAmount(int104 oldPrincipal, int104 newPrincipal) internal pure returns (uint104, uint104) { if (newPrincipal < oldPrincipal) return (0, 0); if (newPrincipal <= 0) { return (uint104(newPrincipal - oldPrincipal), 0); } else if (oldPrincipal >= 0) { return (0, uint104(newPrincipal - oldPrincipal)); } else { return (uint104(-oldPrincipal), uint104(newPrincipal)); } } function withdrawAndBorrowAmount(int104 oldPrincipal, int104 newPrincipal) internal pure returns (uint104, uint104) { if (newPrincipal > oldPrincipal) return (0, 0); if (newPrincipal >= 0) { return (uint104(oldPrincipal - newPrincipal), 0); } else if (oldPrincipal <= 0) { return (0, uint104(oldPrincipal - newPrincipal)); } else { return (uint104(oldPrincipal), uint104(-newPrincipal)); } } function getUtilization(uint256 totalSupply, uint256 totalBorrow) internal pure returns (uint64) { if (totalSupply == 0) return 0; return uint64((totalBorrow * FACTOR_SCALE) / totalSupply); } function getSupplyRate( uint256 utilization, uint64 supplyKink, uint64 supplyPerSecondInterestRateSlopeLow, uint64 supplyPerSecondInterestRateSlopeHigh, uint64 supplyPerSecondInterestRateBase ) internal pure returns (uint64) { if (utilization <= supplyKink) { return supplyPerSecondInterestRateBase + uint64((utilization * supplyPerSecondInterestRateSlopeLow) / FACTOR_SCALE); } else { uint256 excessUtil = utilization - supplyKink; return supplyPerSecondInterestRateBase + supplyPerSecondInterestRateSlopeLow + uint64((excessUtil * supplyPerSecondInterestRateSlopeHigh) / FACTOR_SCALE); } } function getBorrowRate( uint256 utilization, uint64 borrowKink, uint64 borrowPerSecondInterestRateSlopeLow, uint64 borrowPerSecondInterestRateSlopeHigh, uint64 borrowPerSecondInterestRateBase ) internal pure returns (uint64) { if (utilization <= borrowKink) { return borrowPerSecondInterestRateBase + uint64((utilization * borrowPerSecondInterestRateSlopeLow) / FACTOR_SCALE); } else { uint256 excessUtil = utilization - borrowKink; return borrowPerSecondInterestRateBase + borrowPerSecondInterestRateSlopeLow + uint64((excessUtil * borrowPerSecondInterestRateSlopeHigh) / FACTOR_SCALE); } } function accrueInterest( uint256 index, uint64 interestRatePerSecond, uint256 timeElapsed ) internal pure returns (uint256) { uint256 interestAccrued = (index * interestRatePerSecond * timeElapsed) / FACTOR_SCALE; return index + interestAccrued; } function getCollateralValue( uint256 collateralAmount, uint256 collateralPrice, uint8 collateralDecimals ) internal pure returns (uint256) { return (collateralAmount * collateralPrice) / (10 ** collateralDecimals); } function getBorrowCapacity( uint256 collateralValue, uint64 borrowCollateralFactor ) internal pure returns (uint256) { return (collateralValue * borrowCollateralFactor) / FACTOR_SCALE; } }