This repository was archived by the owner on Jan 25, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMathUtils.sol
More file actions
90 lines (77 loc) · 3.56 KB
/
Copy pathMathUtils.sol
File metadata and controls
90 lines (77 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import { WadRayMath } from "./WadRayMath.sol";
/// @title MathUtils library
/// @author Aave
/// @notice Provides functions to perform linear and compounded interest calculations
library MathUtils {
using WadRayMath for uint256;
/// @dev Ignoring leap years
uint256 internal constant SECONDS_PER_YEAR = 365 days;
/// @dev Function to calculate the interest accumulated using a linear interest rate formula
/// @param rate The interest rate, in ray
/// @param lastUpdateTimestamp The timestamp of the last update of the interest
/// @return interestRate The interest rate linearly accumulated during the timeDelta, in ray
function calculateLinearInterest(uint256 rate, uint256 lastUpdateTimestamp)
internal
view
returns (uint256 interestRate)
{
//solium-disable-next-line
uint256 result = rate * (block.timestamp - lastUpdateTimestamp);
unchecked {
result = result / SECONDS_PER_YEAR;
}
interestRate = WadRayMath.RAY + result;
}
/// @dev Function to calculate the interest using a compounded interest rate formula
/// To avoid expensive exponentiation, the calculation is performed using a binomial approximation:
/// (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3...
/// The approximation slightly underpays liquidity providers and undercharges borrowers, with the advantage of great
/// gas cost reductions. The whitepaper contains reference to the approximation and a table showing the margin of
/// error per different time periods
/// @param rate The interest rate, in ray
/// @param lastUpdateTimestamp The timestamp of the last update of the interest
/// @return interestRate The interest rate compounded during the timeDelta, in ray
function calculateCompoundedInterest(uint256 rate, uint256 lastUpdateTimestamp, uint256 currentTimestamp)
internal
pure
returns (uint256 interestRate)
{
//solium-disable-next-line
uint256 exp = currentTimestamp - lastUpdateTimestamp;
if (exp == 0) {
return WadRayMath.RAY;
}
uint256 expMinusOne;
uint256 expMinusTwo;
uint256 basePowerTwo;
uint256 basePowerThree;
unchecked {
expMinusOne = exp - 1;
expMinusTwo = exp > 2 ? exp - 2 : 0;
basePowerTwo = rate.rayMul(rate) / (SECONDS_PER_YEAR * SECONDS_PER_YEAR);
basePowerThree = basePowerTwo.rayMul(rate) / SECONDS_PER_YEAR;
}
uint256 secondTerm = exp * expMinusOne * basePowerTwo;
unchecked {
secondTerm /= 2;
}
uint256 thirdTerm = exp * expMinusOne * expMinusTwo * basePowerThree;
unchecked {
thirdTerm /= 6;
}
interestRate = WadRayMath.RAY + (rate * exp) / SECONDS_PER_YEAR + secondTerm + thirdTerm;
}
/// @dev Calculates the compounded interest between the timestamp of the last update and the current block timestamp
/// @param rate The interest rate (in ray)
/// @param lastUpdateTimestamp The timestamp from which the interest accumulation needs to be calculated
/// @return interestRate The interest rate compounded between lastUpdateTimestamp and current block timestamp, in ray
function calculateCompoundedInterest(uint256 rate, uint256 lastUpdateTimestamp)
internal
view
returns (uint256 interestRate)
{
interestRate = calculateCompoundedInterest(rate, lastUpdateTimestamp, block.timestamp);
}
}