Thankful Ivory Mantaray
Medium
The implementation of the updateJumpRateModelInternal
function in the BaseJumpRateModelV2
contract contains a calculation error that affects the multiplierPerTimestamp
. The current code divides the multiplierPerTimestamp
by the kink_
parameter, which is incorrect according to the provided documentation and the intended design of the interest rate model. The kink_
should not influence the calculation of the multiplier directly but is only relevant for determining the threshold where the "jump multiplier" is applied when the utilization rate exceeds the kink.
Although the Compound V2 interest rate model includes kink_
in the multiplier calculation, this is because Compound uses block-based time measurements (e.g., blocksPerYear
) instead of timestamps. The Mach Finance protocol uses timestamp-based measurements (timestampsPerYear
), and its documentation does not support including kink_
in the multiplier calculation.
The root cause of the issue is the incorrect formula used for calculating multiplierPerTimestamp. In the current code:
function updateJumpRateModelInternal(
uint256 baseRatePerYear,
uint256 multiplierPerYear,
uint256 jumpMultiplierPerYear,
uint256 kink_
) internal {
baseRatePerTimestamp = ((baseRatePerYear * BASE) / timestampsPerYear) / BASE;
@> multiplierPerTimestamp = (multiplierPerYear * BASE) / (timestampsPerYear * kink_);
jumpMultiplierPerTimestamp = ((jumpMultiplierPerYear * BASE) / timestampsPerYear) / BASE;
kink = kink_;
emit NewInterestParams(baseRatePerTimestamp, multiplierPerTimestamp, jumpMultiplierPerTimestamp, kink);
}
The documentation specifies that the multiplierPerTimestamp
is derived from the annual multiplier (multiplierPerYear
) and the timestamps per year (timestampsPerYear
), and should not be affected by the kink_
parameter.
The jump rate model calculates the interest for a specific asset by using the utilization rate up to the kink point. When utilization exceeds the kink_
, the jump multiplier is used, but the multiplier itself should not be modified by kink. The kink_
is only used to specify the utilization threshold of interest rate growth (up to the kink and beyond the kink).
This miscalculation leads to incorrect interest rate calculations, as the multiplierPerTimestamp
is being scaled based on an irrelevant parameter (kink_
). This error will affect both the borrow and supply rates. The borrow rate calculation depends on the multiplierPerTimestamp
, and the supply rate is also influenced by these interest rate calculations. As a result, this could distort interest rates, making them higher or lower than intended, potentially disrupting market incentives and leading to inefficient liquidity utilization or rate imbalances.
Similar to Moonwell, the calculation for multiplierPerTimestamp
should be based solely on the annual multiplier (multiplierPerYear
) and the number of timestamps per year (timestampsPerYear
). The kink_
parameter should not affect this calculation. As described, the correct formula for multiplierPerTimestamp
is:
multiplierPerTimestamp = ((multiplierPerYear * BASE) / timestampsPerYear) / BASE;