The calculation of timeDifference in getTRate is incorrect
Summary
The calculation of timeDifference in getTRate is incorrect as it does not properly account for each individual borrower's timestamp at which they first borrowed JUSD.
Vulnerability Detail
JOJO's calculation for timeDifference in the getTRate function, which is how the current interest percentage is determined for a borrower, is not correctly tabulating the time difference for each borrower. Instead, getTRate uses the timestamp at which the borrow rate is set. However, lastUpdateTimestamp is only updated when the borrowFeeRate is updated and not each time a borrower interacts with the protocol. This means a borrower's interest rate will constantly accumulate over time, instead of being amortized over the time difference in which they last interacted with the protocol.
Impact
A borrower may end up paying dramatically more in interest than expected. Additionally, new borrowers will end up paying interest over a period of time that they did not borrow for. For example, in the case where the borrowFeeRate has not been updated in a year, a new borrower will end up paying interest as if they have held a borrow for a year instead of for the initial time of the t0Rate.
Consider implementing either of the following suggestions for correctly tabulating interest per borrower:
A borrower's account should store the initial block.timestamp of when they borrowed JUSD. Then, each time a borrower interacts with the protocol, their interest is calculated from the saved timestamp to the current block.timestamp where this time difference is used in the getTRate calculation. The interest should then be added to the amount borrowed and the timestamp in the borrower's account should be updated. This 'checkpoints' the interest accrual upon each interaction with the lending contract.
The JUSDBank contract tabulates the interest accrued on the total borrows each time any user interacts with the protocol, and then calculates the amount of interest owed per-user by determining the individual amount borrowed relative to the total amount borrowed.
In both instances, the interest is tabulated per-interaction. This is accomplished by amortizing the interest rate over one year, and caching the last block timestamp interest was accounted for. Then, the protocol is able to apply interest to a user or a borrow pool based on the time difference from the last interaction.
ArbitraryExecution
high
The calculation of
timeDifference
ingetTRate
is incorrectSummary
The calculation of
timeDifference
ingetTRate
is incorrect as it does not properly account for each individual borrower's timestamp at which they first borrowed JUSD.Vulnerability Detail
JOJO's calculation for
timeDifference
in thegetTRate
function, which is how the current interest percentage is determined for a borrower, is not correctly tabulating the time difference for each borrower. Instead,getTRate
uses the timestamp at which the borrow rate is set. However,lastUpdateTimestamp
is only updated when theborrowFeeRate
is updated and not each time a borrower interacts with the protocol. This means a borrower's interest rate will constantly accumulate over time, instead of being amortized over the time difference in which they last interacted with the protocol.Impact
A borrower may end up paying dramatically more in interest than expected. Additionally, new borrowers will end up paying interest over a period of time that they did not borrow for. For example, in the case where the
borrowFeeRate
has not been updated in a year, a new borrower will end up paying interest as if they have held a borrow for a year instead of for the initial time of thet0Rate
.Code Snippet
https://github.com/JOJOexchange/JUSDV1/blob/011e10d36257a404c8c1d7d2b8c9f01a2b7a1969/src/Impl/JUSDBankStorage.sol#L52
Tool used
Manual review.
Recommendation
Consider implementing either of the following suggestions for correctly tabulating interest per borrower:
block.timestamp
of when they borrowed JUSD. Then, each time a borrower interacts with the protocol, their interest is calculated from the saved timestamp to the currentblock.timestamp
where this time difference is used in thegetTRate
calculation. The interest should then be added to the amount borrowed and the timestamp in the borrower's account should be updated. This 'checkpoints' the interest accrual upon each interaction with the lending contract.JUSDBank
contract tabulates the interest accrued on the total borrows each time any user interacts with the protocol, and then calculates the amount of interest owed per-user by determining the individual amount borrowed relative to the total amount borrowed.In both instances, the interest is tabulated per-interaction. This is accomplished by amortizing the interest rate over one year, and caching the last block timestamp interest was accounted for. Then, the protocol is able to apply interest to a user or a borrow pool based on the time difference from the last interaction.