20,000 USDC
View results
Submission Details
Severity: high

QOL Business Logic in calculateInterest

Summary

This novel concept of continuous loans and the dropping of the usual loan market incumbent characteristics like loan expiration times and loan periods unearths some amazing capabilities. Many of which are built into this contract explicitly.

For example, Interest on the current loan is calculated when repaying (from the interest rate used when taking the loan), BUT the pool owner is able to use the updateInterestRate function at any time.

An increased Interest Rate would be unfair to the user,BUTt a decreased one would negate the need to explicitly refinance to another pool if one becomes available at a fairer price to the borrower.

If this recommendation were to be followed:

  1. a savvy mempool watching lender may be able to save their lending business from moving to another pool, by lowering interest Rates.

  2. a savvy mempool watching borrower may want to repay their loan sooner in order to take advantage of the lower rate by the current lender.

I understand that this functionality is already possible by utilizing the current novel design of the smart contract, BUT current lenders aren't able to open new pools with the same tokens and participate in the marketplace for keeping their current customers business.

This simple change adds the missing piece of the puzzle to this novel marketplace design for continuous loans by allowing the current lenders to compete with new pools and the same tokens

Vulnerability Details

Any time you are able to provide value to users without having them sign transactions would be a decreased attack area, making this vulnerability report like a gas saving one; a vulnerability saving optimization if you will ;)

Impact

A Delightful User Experience by allowing the current lenders to compete with new pools for the same tokens

Tools Used

Manual Review

Recommendations

Use the smaller of the two numbers for interest rate calculation, (pool.interestRate vs loan.interestRate)
i.e.

/// @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;
+ bytes32 poolId = getPoolId(l.lender, l.loanToken, l.collateralToken);
+ uint256 poolInterestRate = pools[poolId].interestRate;
+ if (poolInterestRate < l.interestRate) {
+ interest = (poolInterestRate * l.debt * timeElapsed) / 10000 / 365 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.