20,000 USDC
View results
Submission Details
Severity: gas
Valid

Lack of updating the auctionLength parameter in the giveLoan() and buyLoan()

Summary

The Lender::giveLoan() and Lender::buyLoan() lack updating the loan's auctionLength parameter to match the new pool. Either a borrower or a lender can lose their benefits.

Vulnerability Details

The giveLoan() and buyLoan() do not update the loan's auctionLength parameter to match the new pool while updating other parameters.

function giveLoan(
uint256[] calldata loanIds,
bytes32[] calldata poolIds
) external {
for (uint256 i = 0; i < loanIds.length; i++) {
...
// update the loan with the new info
@> loans[loanId].lender = pool.lender;
@> loans[loanId].interestRate = pool.interestRate;
@> loans[loanId].startTimestamp = block.timestamp;
@> loans[loanId].auctionStartTimestamp = type(uint256).max;
@> loans[loanId].debt = totalDebt;
...
}
}
// ...SNIPPED...
function buyLoan(uint256 loanId, bytes32 poolId) public {
...
// update the loan with the new info
@> loans[loanId].lender = msg.sender;
@> loans[loanId].interestRate = pools[poolId].interestRate;
@> loans[loanId].startTimestamp = block.timestamp;
@> loans[loanId].auctionStartTimestamp = type(uint256).max;
@> loans[loanId].debt = totalDebt;
...
}
  • The giveLoan() updates the loan's other params, but the auctionLength: https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L416-L420

  • The buyLoan() updates the loan's other params, but the auctionLength: https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L518-L522

Impact

In the case of giveLoan(), if the new pool has a longer auction length than the previous pool, a borrower will lose benefits from the longer auction length (the new pool cannot have a shorter auction length in this case).

Similarly, in the case of buyLoan(), a borrower will lose their benefits if the new pool has a longer auction length than the previous pool. On the other hand, if the new pool has a shorter auction length than the previous pool, a lender (the new pool's owner) may lose their benefits instead.

Tools Used

Manual Review

Recommendations

I recommend updating the auctionLength parameter in both the giveLoan() and buyLoan(), as shown below.

function giveLoan(
uint256[] calldata loanIds,
bytes32[] calldata poolIds
) external {
for (uint256 i = 0; i < loanIds.length; i++) {
...
// update the loan with the new info
loans[loanId].lender = pool.lender;
loans[loanId].interestRate = pool.interestRate;
loans[loanId].startTimestamp = block.timestamp;
loans[loanId].auctionStartTimestamp = type(uint256).max;
loans[loanId].debt = totalDebt;
+ loans[loanId].auctionLength = pool.auctionLength;
...
}
}
// ...SNIPPED...
function buyLoan(uint256 loanId, bytes32 poolId) public {
...
// update the loan with the new info
loans[loanId].lender = msg.sender;
loans[loanId].interestRate = pools[poolId].interestRate;
loans[loanId].startTimestamp = block.timestamp;
loans[loanId].auctionStartTimestamp = type(uint256).max;
loans[loanId].debt = totalDebt;
+ loans[loanId].auctionLength = pools[poolId].auctionLength;
...
}

Support

FAQs

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