20,000 USDC
View results
Submission Details
Severity: high

Borrower has to pay more than usual if current year is a leap year

Summary

In _calculateInterest(), the interest is calculated by (l.interestRate * l.debt * timeElapsed) / 10000 / 365 days where l is the loan's interestRate and debt amount, timeElapsed is calculated by block.timestamp - l.startTimestamp. As you can see the 365 days is hardcoded, which is a wrong assumption that every year has 365 days, while it is not since leap year has 366 days.

Vulnerability Details

The contract lacks function to check if current year is a leap year, and this is a one-time deployed contract with user's funds in it, it can't be updated every 4 years. Which will make the interest higher than it should be for almost a full year after February 29th, 2024.

Impact

The interest is unfairly higher for borrower when the current year of the world is a leap year. This can take effect on borrower as soon as the calendar pass to March/2024 next year, which is a leap year itself.

Tools Used

Manual

Recommendations

I have done a function to check if current year is a leap year, which is inspired by this 2 information:

  1. Leap year calculation formula: https://www.cuemath.com/calculators/leap-year-calculator/ (We don't have to check for century years now with the formulation of divide by 400, since we still have 77 years left to reach the year of 2100).

  2. Current year calculation formula: https://ethereum.stackexchange.com/questions/132708/how-to-get-current-year-from-timestamp-solidity.

So, the finished modification I would like to propose is:

+ function isLeapYear() public view returns (bool) {
+ uint currentYear = (block.timestamp / 31557600) + 1970;
+ return currentYear % 4 == 0 ? true : false;
+ }
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;
+ if (isLeapYear()) {
+ interest = (l.interestRate * l.debt * timeElapsed) / 10000 / 366 days;
+ } else {
+ interest = (l.interestRate * l.debt * timeElapsed) / 10000 / 365 days;
+ }
fees = (lenderFee * interest) / 10000;
interest -= fees;
}

Support

FAQs

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

Give us feedback!