100 lines
3.9 KiB
Solidity
100 lines
3.9 KiB
Solidity
// 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;
|
|
}
|
|
} |