Skip to content

Commit

Permalink
feat: add timestamp based functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Debugger022 committed Nov 28, 2023
1 parent d89619d commit f44e34c
Show file tree
Hide file tree
Showing 37 changed files with 26,685 additions and 17,250 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ MNEMONIC=
ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1
FORK_MAINNET=false
QUICK_NODE_KEY=ABC123ABC123ABC123ABC123ABC123ABC1
RUN_TIMESTAMP_BASED_INTEGRATION_TESTS=true
88 changes: 59 additions & 29 deletions contracts/BaseJumpRateModelV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@
pragma solidity 0.8.13;

import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol";

import { TimeManager } from "./TimeManager.sol";
import { InterestRateModel } from "./InterestRateModel.sol";
import { BLOCKS_PER_YEAR, EXP_SCALE, MANTISSA_ONE } from "./lib/constants.sol";
import { EXP_SCALE, MANTISSA_ONE } from "./lib/constants.sol";

/**
* @title Logic for Compound's JumpRateModel Contract V2.
* @title BaseJumpRateModelV2
* @author Compound (modified by Dharma Labs, Arr00 and Venus)
* @notice An interest rate model with a steep increase after a certain utilization threshold called **kink** is reached.
* The parameters of this interest rate model can be adjusted by the owner. Version 2 modifies Version 1 by enabling updateable parameters.
* The parameters of this interest rate model can be adjusted by the owner. Version 2 modifies Version 1 by enabling updateable parameters
*/
abstract contract BaseJumpRateModelV2 is InterestRateModel {
abstract contract BaseJumpRateModelV2 is TimeManager, InterestRateModel {
/**
* @notice The address of the AccessControlManager contract
*/
IAccessControlManagerV8 public accessControlManager;

/**
* @notice The multiplier of utilization rate that gives the slope of the interest rate
* @notice The multiplier of utilization rate per block or second that gives the slope of the interest rate
*/
uint256 public multiplierPerBlock;

/**
* @notice The base interest rate which is the y-intercept when utilization rate is 0
* @notice The base interest rate per block or second which is the y-intercept when utilization rate is 0
*/
uint256 public baseRatePerBlock;

/**
* @notice The multiplier per block after hitting a specified utilization point
* @notice The multiplier per block or second after hitting a specified utilization point
*/
uint256 public jumpMultiplierPerBlock;

Expand All @@ -39,9 +39,9 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {
uint256 public kink;

event NewInterestParams(
uint256 baseRatePerBlock,
uint256 multiplierPerBlock,
uint256 jumpMultiplierPerBlock,
uint256 baseRatePerBlockOrTimestamp,
uint256 multiplierPerBlockOrTimestamp,
uint256 jumpMultiplierPerBlockOrTimestamp,
uint256 kink
);

Expand All @@ -52,31 +52,35 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {

/**
* @notice Construct an interest rate model
* @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)
* @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)
* @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point
* @param baseRatePerYear_ The approximate target base APR, as a mantissa (scaled by EXP_SCALE)
* @param multiplierPerYear_ The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)
* @param jumpMultiplierPerYear_ The multiplierPerBlockOrTimestamp after hitting a specified utilization point
* @param kink_ The utilization point at which the jump multiplier is applied
* @param accessControlManager_ The address of the AccessControlManager contract
* @param timeBased_ A boolean indicating whether the contract is based on time or block.
* @param blocksPerYear_ The number of blocks per year
*/
constructor(
uint256 baseRatePerYear,
uint256 multiplierPerYear,
uint256 jumpMultiplierPerYear,
uint256 baseRatePerYear_,
uint256 multiplierPerYear_,
uint256 jumpMultiplierPerYear_,
uint256 kink_,
IAccessControlManagerV8 accessControlManager_
) {
IAccessControlManagerV8 accessControlManager_,
bool timeBased_,
uint256 blocksPerYear_
) TimeManager(timeBased_, blocksPerYear_) {
require(address(accessControlManager_) != address(0), "invalid ACM address");

accessControlManager = accessControlManager_;

_updateJumpRateModel(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_);
_updateJumpRateModel(baseRatePerYear_, multiplierPerYear_, jumpMultiplierPerYear_, kink_);
}

/**
* @notice Update the parameters of the interest rate model
* @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)
* @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)
* @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point
* @param jumpMultiplierPerYear The multiplierPerBlockOrTimestamp after hitting a specified utilization point
* @param kink_ The utilization point at which the jump multiplier is applied
* @custom:error Unauthorized if the sender is not allowed to call this function
* @custom:access Controlled by AccessControlManager
Expand All @@ -98,13 +102,30 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {
}

/**
* @notice Calculates the current supply rate per block
* @notice Calculates the current borrow rate per slot(block/second)
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @param badDebt The amount of badDebt in the market
* @return The borrow rate percentage per slot(block/second) as a mantissa (scaled by 1e18)
*/
function getBorrowRate(
uint256 cash,
uint256 borrows,
uint256 reserves,
uint256 badDebt
) external view override returns (uint256) {
return _getBorrowRate(cash, borrows, reserves, badDebt);
}

/**
* @notice Calculates the current supply rate per slot(block/second)
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @param reserveFactorMantissa The current reserve factor for the market
* @param badDebt The amount of badDebt in the market
* @return The supply rate percentage per block as a mantissa (scaled by EXP_SCALE)
* @return The supply rate percentage per slot(block/second) as a mantissa (scaled by EXP_SCALE)
*/
function getSupplyRate(
uint256 cash,
Expand All @@ -121,6 +142,14 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {
return incomeToDistribute / supply;
}

/**
* @notice Get the number of seconds/blocks in a year
* @return Number of blocks or seconds in a year
*/
function getSlotsInOneYear() public view returns (uint256) {
return _getSlotsInOneYear();
}

/**
* @notice Calculates the utilization rate of the market: `(borrows + badDebt) / (cash + borrows + badDebt - reserves)`
* @param cash The amount of cash in the market
Expand Down Expand Up @@ -153,7 +182,7 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {
* @notice Internal function to update the parameters of the interest rate model
* @param baseRatePerYear The approximate target base APR, as a mantissa (scaled by EXP_SCALE)
* @param multiplierPerYear The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)
* @param jumpMultiplierPerYear The multiplierPerBlock after hitting a specified utilization point
* @param jumpMultiplierPerYear The multiplierPerBlockOrTimestamp after hitting a specified utilization point
* @param kink_ The utilization point at which the jump multiplier is applied
*/
function _updateJumpRateModel(
Expand All @@ -162,21 +191,22 @@ abstract contract BaseJumpRateModelV2 is InterestRateModel {
uint256 jumpMultiplierPerYear,
uint256 kink_
) internal {
baseRatePerBlock = baseRatePerYear / BLOCKS_PER_YEAR;
multiplierPerBlock = multiplierPerYear / BLOCKS_PER_YEAR;
jumpMultiplierPerBlock = jumpMultiplierPerYear / BLOCKS_PER_YEAR;
uint256 slotsInOneYear = getSlotsInOneYear();
baseRatePerBlock = baseRatePerYear / slotsInOneYear;
multiplierPerBlock = multiplierPerYear / slotsInOneYear;
jumpMultiplierPerBlock = jumpMultiplierPerYear / slotsInOneYear;
kink = kink_;

emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);
}

/**
* @notice Calculates the current borrow rate per block, with the error code expected by the market
* @notice Calculates the current borrow rate per slot(block/second), with the error code expected by the market
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @param badDebt The amount of badDebt in the market
* @return The borrow rate percentage per block as a mantissa (scaled by EXP_SCALE)
* @return The borrow rate percentage per slot(block/second) as a mantissa (scaled by EXP_SCALE)
*/
function _getBorrowRate(
uint256 cash,
Expand Down
48 changes: 25 additions & 23 deletions contracts/JumpRateModelV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.13;

import { IAccessControlManagerV8 } from "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol";

import { BaseJumpRateModelV2 } from "./BaseJumpRateModelV2.sol";

/**
Expand All @@ -11,33 +10,36 @@ import { BaseJumpRateModelV2 } from "./BaseJumpRateModelV2.sol";
* @notice Supports only for V2 vTokens
*/
contract JumpRateModelV2 is BaseJumpRateModelV2 {
/**
* @notice Construct an interest rate model
* @param baseRatePerYear_ The approximate target base APR, as a mantissa (scaled by EXP_SCALE)
* @param multiplierPerYear_ The rate of increase in interest rate wrt utilization (scaled by EXP_SCALE)
* @param jumpMultiplierPerYear_ The multiplierPerBlockOrTimestamp after hitting a specified utilization point
* @param kink_ The utilization point at which the jump multiplier is applied
* @param accessControlManager_ The address of the AccessControlManager contract
* @param timeBased_ A boolean indicating whether the contract is based on time or block.
* @param blocksPerYear_ The number of blocks per year
*/
constructor(
uint256 baseRatePerYear,
uint256 multiplierPerYear,
uint256 jumpMultiplierPerYear,
uint256 baseRatePerYear_,
uint256 multiplierPerYear_,
uint256 jumpMultiplierPerYear_,
uint256 kink_,
IAccessControlManagerV8 accessControlManager_
IAccessControlManagerV8 accessControlManager_,
bool timeBased_,
uint256 blocksPerYear_
)
BaseJumpRateModelV2(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_, accessControlManager_)
BaseJumpRateModelV2(
baseRatePerYear_,
multiplierPerYear_,
jumpMultiplierPerYear_,
kink_,
accessControlManager_,
timeBased_,
blocksPerYear_
)
/* solhint-disable-next-line no-empty-blocks */
{

}

/**
* @notice Calculates the current borrow rate per block
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @param badDebt The amount of badDebt in the market
* @return The borrow rate percentage per block as a mantissa (scaled by 1e18)
*/
function getBorrowRate(
uint256 cash,
uint256 borrows,
uint256 reserves,
uint256 badDebt
) external view override returns (uint256) {
return _getBorrowRate(cash, borrows, reserves, badDebt);
}
}
Loading

0 comments on commit f44e34c

Please sign in to comment.