20,000 USDC
View results
Submission Details
Severity: high

Divide-Before-Multiply Vulnerability in _calculateInterest Function

Summary

The _calculateInterest function within the smart contract exhibits a critical vulnerability that could lead to incorrect interest and fees calculations.

Vulnerability Details

The vulnerability arises from dividing a value before performing multiplication, potentially leading to inaccurate results and financial losses for the users of the contract.

Impact

The _calculateInterest function aims to calculate the interest and fees accrued on a loan based on the loan details provided. However, the issue lies in the order of operations used in the calculation. Specifically, the function first divides timeElapsed by 365 days and then multiplies it with the l.interestRate, l.debt, and lenderFee. This order of operations can lead to significant precision loss and incorrect results.

/// @notice calculates interest accrued on a loan
/// @param l the loan to calculate for
/// @return interest the interest accrued
/// @return fees the fees accrued
function _calculateInterest(
Loan memory l
) internal view returns (uint256 interest, uint256 fees) {
uint256 timeElapsed = block.timestamp - l.startTimestamp;
interest = (l.interestRate * l.debt * timeElapsed) / 10000 / 365 days;
fees = (lenderFee * interest) / 10000;
interest -= fees;
}
interest = (l.interestRate * l.debt * timeElapsed) / 10000 / 365 days;

Here, the timeElapsed is divided by 365 days before performing the multiplication. As timeElapsed is typically represented in seconds (uint256), this division by a large value (365 days represented in seconds) can cause significant truncation and loss of precision, leading to incorrect interest and fees calculations.

For example, suppose the timeElapsed is approximately 31536000 seconds (1 year). After dividing by 365 days (represented as 1 years), the result would be 1, leading to a significant underestimation of the interest and fees accrued over the year. This could result in the loan being drastically undervalued, leading to potential financial losses for the lender or incorrect interest rates for the borrower.

Tools Used

manual review and slither

Recommendations

To address the divide-before-multiply vulnerability, it is essential to change the order of operations in the calculation. Instead of dividing timeElapsed by 365 days, the multiplication should be performed first and then divided by the total number of seconds in a year.

uint256 secondsPerYear = 365 days;
interest = (l.interestRate * l.debt * timeElapsed) / (10000 * secondsPerYear);

By making this change, the calculation will maintain the necessary precision, ensuring accurate interest and fees calculations. It is crucial to implement this fix and thoroughly test the updated function to ensure its correctness.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.