Dynamic Interest Rate Model
Last updated
Last updated
The Dynamic Interest Rate Model (DIRM) is a sophisticated interest rate mechanism designed to efficiently balance supply and demand within Curvance lending markets. It builds upon traditional "jump rate" models while introducing dynamic elements that automatically respond to changing market conditions.
The model uses two primary interest rate components:
Base Interest Rate: Applied linearly as utilization increases from 0% to the vertex point, which increases linearly until a certain utilization threshold (vertexStartingPoint
) is reached.
Vertex Interest Rate: Applied when utilization exceeds the vertex point, multiplied by the Vertex Multiplier, which adjusts more steeply based on liquidity utilization.
Vertex Starting Point: The utilization threshold where the model switches from base to vertex rate.
The heart of the model is the Vertex Multiplier - a dynamic coefficient that adjusts based on market conditions:
Default Value: Starts at 1.0 (WAD).
Maximum Value: Capped at vertexMultiplierMax.
Storage Format: Packed with timestamp data in a single storage slot to minimize gas costs.
Market Utilization → Calculated from borrows / (underlyingHeld + borrows - reserves).
Utilization → Drives interest rate calculations through base and vertex formulas.
Interest Rates → Applied to borrowers and distributed to lenders (minus protocol fees).
Vertex Multiplier → Adjusted based on sustained market utilization patterns.
Decay Mechanism → Continuously reduces elevated multiplier values over time.
The Vertex Multiplier operates as a state machine with the following transitions:
Initialization State
Starting point: vertexMultiplier = WAD (1.0).
Next update timestamp set.
Adjustment States
Based on utilization relative to thresholds:
Below decreaseThresholdMax: Maximum negative adjustment + decay.
Below vertex but above decreaseThresholdMax: Scaled negative adjustment + decay.
Above vertex but below increaseThreshold: Only decay applied.
Above increaseThreshold: Positive adjustment + decay.
Transition Conditions
Transitions only occur when current block.timestamp ≥ updateTimestamp
.
Rate update only possible when properly linked to an eToken.
The decay feature introduces a downward sloping characteristic:
When the multiplier is elevated, a constant negative velocity is applied.
This occurs regardless of positive/negative acceleration from utilization.
If the multiplier is elevated due to high utilization, it naturally decays over time to prevent interest rates from remaining too high indefinitely.
Similarly, if utilization is low and the multiplier has been reduced, it decays back upward over time to prevent excessively low rates.
Creates natural incentives for borrowers while protecting against liquidity crunches.
The model is governed by several parameters that define its behavior:
Base Parameters:
baseInterestRate: The slope of the linear portion.
vertexInterestRate: The slope of the exponential portion.
vertexStartingPoint: The utilization point where vertex takes effect.
Adjustment Controls:
adjustmentRate: Time between multiplier updates (seconds).
adjustmentVelocity: Maximum rate of multiplier change per update.
vertexMultiplierMax: Maximum allowed value for multiplier.
Threshold Parameters:
increaseThreshold: Point above vertex where multiplier increases.
increaseThresholdMax: Point where multiplier increase reaches maximum.
decreaseThreshold: Point below vertex where multiplier decreases.
decreaseThresholdMax: Point where multiplier decrease reaches maximum.
decayRate: Rate at which elevated multipliers naturally decrease.
Responsive to Market Conditions:
High utilization leads to increased rates, attracting lenders.
Sustained high rates encourage borrowers to repay.
Self-Balancing:
Creates a feedback loop that stabilizes market liquidity.
Prevents liquidity crunches through predictive rate adjustments.
Growth Incentives:
Decay mechanism helps maintain competitive rates during normal operations.
Creates naturally decreasing interest rates in stable markets.
Gas Optimization:
Uses bit-packed storage for multiplier and timestamp.
Efficient math calculations for model computation.
If a market experiences sustained high utilization:
Interest rates will gradually increase as the Vertex Multiplier rises.
This attracts new lenders while encouraging borrowers to repay.
As utilization decreases, rates begin to fall (but not immediately due to the multiplier).
The decay mechanism ensures rates will eventually normalize even without full utilization correction.
This creates a more stable, responsive system compared to fixed-rate models while protecting the protocol from potential liquidity crises.
Utilization Rate Calculation
Base Interest Rate Calculation
Vertex Interest Rate Calculation
Final Borrow Interest Rate Calculation
Vertex Multiplier Adjustment (Above Vertex)
Where:
Vertex Multiplier Adjustment (Below Vertex)
Contract: DynamicInterestRateModel
Description: Calculates the current borrow rate per year, with updated vertex multiplier applied.
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
Return data:
uint256
The borrow rate percentage per year, in WAD
Contract: DynamicInterestRateModel
Description: Calculates the current supply rate per year. This function converts the per-compound supply rate to an annual rate.
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
uint256
interestFee
The current interest rate reserve factor for the market.
Return data:
uint256
The supply rate percentage per year, in WAD.
Contract: DynamicInterestRateModel
Description: Returns the unpacked values from _currentRates storage variable, providing the current vertex multiplier and next update timestamp.
Function signature:
Return data:
uint256
The current Vertex Multiplier, in WAD.
uint256
The timestamp for the next vertex multiplier update, in unix time.
Contract: DynamicInterestRateModel
Description: Calculates the utilization rate of the market using the formula: borrows / (underlyingHeld + borrows - reserves).
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
Return data:
uint256
The utilization rate between [0, WAD].
Contract: DynamicInterestRateModel
Description: Calculates the current borrow rate per compound, with updated vertex multiplier applied. This provides a prediction of what the borrow rate will be after the next vertex multiplier update.
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
Return data:
uint256
The borrow rate percentage per compound, in WAD.
Contract: DynamicInterestRateModel
Description: Calculates the current borrow rate, per compound, based on the current market conditions.
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
Return data:
uint256
The borrow rate percentage, per compound, in WAD.
Contract: DynamicInterestRateModel
Description: Calculates the current supply rate, per compound, based on the borrow rate and interest fee.
Function signature:
uint256
underlyingHeld
The amount of underlying assets held in the market.
uint256
borrows
The amount of borrows in the market.
uint256
reserves
The amount of reserves in the market.
uint256
interestFee
The current interest rate reserve factor for the market.
Return data:
uint256
The supply rate percentage, per compound, in WAD
Contract: DynamicInterestRateModel
Description: Returns the multiplier applied to the vertex interest rate, which is used to dynamically adjust interest rates based on market conditions.
Function signature:
Return data:
uint256
The multiplier applied to the vertex interest rate, in WAD.
Contract: DynamicInterestRateModel
Description: Returns the next timestamp when the vertex multiplier will be updated.
Function signature:
Return data:
uint256
The next timestamp when vertexMultiplier will be updated, in unix time.