📈 Compound Rate Keeper
Introduction
The Compound Rate Keeper module is designed to be employed in lending protocols to compute interest and borrow rates, as well as in staking contracts to determine users' rewards accrual with a fixed Annual Percentage Yield (APY).
Implementation
The ACompoundRateKeeper contract primary objective is to calculate compound interest rates based on two parameters: capitalizationRate and capitalizationPeriod. The compound interest formula is as follows:
where:
- compoundRate - the newly calculated compound rate
- currentRate - rate at the current point (initially set to 1)
- capitalizationRate - compound percentage rate
- secondsPassed - seconds passed since the last update
- capitalizationPeriod - period in seconds the capitalizationRate has to be applied to calculate the interest
Note, that the compoundRate is calculated with the precision of 10**25. The maximum possible compoundRate is type(uint128).max * 10**25.
The ACompoundRateKeeper contract defines the calculation of the compound rate and can serve as a base for implementing diverse lending or staking calculations. This contract includes the following public functions:
| Function | Description |
|---|---|
emergencyUpdateCompoundRate | Updates the compound rate. If overflows, sets isMaxRateReached to true |
getCompoundRate | Returns current compound rate |
getFutureCompoundRate | Returns future compound rate |
getCapitalizationRate | Returns current capitalization rate |
getCapitalizationPeriod | Returns current capitalization period |
getLastUpdate | Returns timestamp of the last update |
getIsMaxRateReached | Returns whether the max rate is reached |
getCurrentRate | Returns current rate |
Additionally, there are a couple of internal functions to update the capitalization rate or capitalization period:
| Function | Description |
|---|---|
_setCapitalizationRate | Sets the capitalization rate |
_setCapitalizationPeriod | Sets the capitalization period |
The core function containing the rate calculation logic is getFutureCompoundRate, which eventually returns the new rate.
Example
To implement and interact with the compound rate keeper, create a contract that inherits from the ACompoundRateKeeper contract and initializes all necessary values.
import "@solarity/solidity-lib/compound-rate-keeper/ACompoundRateKeeper.sol";
contract CompoundRateKeeper is ACompoundRateKeeper {
constructor(uint256 capitalizationRate_, uint64 capitalizationPeriod_) {
__CompoundRateKeeper_init(capitalizationRate_, capitalizationPeriod_);
}
}
So now we can create an instance of our implementation and use in different contexts.
uint256 public constant PRECISION = 10 ** 25;
uint64 public constant YEAR_IN_SECONDS = 365 * 24 * 60 * 60;
CompoundRateKeeper public crk;
crk = new CompoundRateKeeper(
112 * PRECISION / 100, // 1.12 * precision - capitalization rate
YEAR_IN_SECONDS // 1 year in seconds - capitalization period
);
crk.getCapitalizationRate(); // 11200000000000000000000000
crk.getCapitalizationPeriod(); // 31536000
crk.getCompoundRate(); // current compound rate - 10000000000000000000000000
crk.getFutureCompoundRate(block.timestamp + YEAR_IN_SECONDS);
// rate after one year - 11200000000000000000000000