20,000 USDC
View results
Submission Details
Severity: high

lender can force borrowe to pay more interest and then liquidate borrower with 1000% interest

Summary

lender can force borrowe to pay more interest and then liquidate borrower with 1000% interest.

Vulnerability Details

when the borrower borrows from lender pool in the middle of the outstanding loan can adjust the interest rate and because the borrower borrow the money with lower interest thinks he going to pay that amount of interest however the lender adjusts it and Force the borrower pay unacepable huge interest and can liquidate the borrower

https://github.com/Cyfrin/2023-07-beedle/blob/991133b9b4a8d121499a68f4f8c706bd11a6821c/src/Lender.sol#L221-L226

/// @param interestRate the new interest rate
function updateInterestRate(bytes32 poolId, uint256 interestRate) external {
if (pools[poolId].lender != msg.sender) revert Unauthorized();
if (interestRate > MAX_INTEREST_RATE) revert PoolConfig();
pools[poolId].interestRate = interestRate;
emit PoolInterestRateUpdated(poolId, interestRate);
}

how?: look at the Repay function in lender.sol this function is for borrower for paying the debt of loan but it calculates the interest trough _calculateInterestfunction which is again using interest rate that borrower set to pool to calculate interest.

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;
}

Repay function is calculation interest through _calculateInterest function

function repay(uint256[] calldata loanIds) public {
for (uint256 i = 0; i < loanIds.length; i++) {
uint256 loanId = loanIds[i];
// get the loan info
Loan memory loan = loans[loanId];
// calculate the interest
(
uint256 lenderInterest,
uint256 protocolInterest
) = _calculateInterest(loan);
bytes32 poolId = getPoolId(
loan.lender,
loan.loanToken,
loan.collateralToken
);
// update the pool balance
_updatePoolBalance(
poolId,
pools[poolId].poolBalance + loan.debt + lenderInterest
);
pools[poolId].outstandingLoans -= loan.debt;
// transfer the loan tokens from the borrower to the pool
IERC20(loan.loanToken).transferFrom(
msg.sender,
address(this),
loan.debt + lenderInterest
);
// transfer the protocol fee to the fee receiver
IERC20(loan.loanToken).transferFrom(
msg.sender,
feeReceiver,
protocolInterest
);
// transfer the collateral tokens from the contract to the borrower
IERC20(loan.collateralToken).transfer(
loan.borrower,
loan.collateral
);
emit Repaid(
msg.sender,
loan.lender,
loanId,
loan.debt,
loan.collateral,
loan.interestRate,
loan.startTimestamp
);
// delete the loan
delete loans[loanId];
}
}

Impact

lender can Force borrower to pay huge unacceptable/unafordble interest when they get the loan with little interest and can liquidate them. borrower can fall to trap.

Tools Used

manually

Recommendations

  • Consider avoiding increasing interest in the middle of the outstanding loans in the pool or apply the new interest for new loans only.

Support

FAQs

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

Give us feedback!