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

A malicious lender can frontrun borrower's `Lender.borrow()` with `Lender.updateInterestRate()` to increase interest rate higher than previously seen.

Summary

Lender.borrow() uses pool.interestRate as loan's interest rate and is prone to frontrunning by malicious lender who wants to increase interest rate.

Vulnerability Details

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

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

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol#L249-L260

function borrow(Borrow[] calldata borrows) public {
...
Loan memory loan = Loan({
lender: pool.lender,
borrower: msg.sender,
loanToken: pool.loanToken,
collateralToken: pool.collateralToken,
debt: debt,
collateral: collateral,
interestRate: pool.interestRate, // @audit - sandwiching with updateInterestRate
startTimestamp: block.timestamp,
auctionStartTimestamp: type(uint256).max,
auctionLength: pool.auctionLength
});
...
}

Impact

Borrower will have to pay higher interest rate than previously seen without any notice.

Tools Used

Manual Review

Recommendations

Borrower should specify expected interest rate when borrowing, and it should be equal to pool's interest rate.

struct Borrow {
/// @notice the pool ID to borrow from
bytes32 poolId;
/// @notice the amount to borrow
uint256 debt;
/// @notice the amount of collateral to put up
uint256 collateral;
+ /// @notice the interest rate
+ uint256 interestRate;
}
function borrow(Borrow[] calldata borrows) public {
for (uint256 i = 0; i < borrows.length; i++) {
bytes32 poolId = borrows[i].poolId;
uint256 debt = borrows[i].debt;
uint256 collateral = borrows[i].collateral;
// get the pool info
Pool memory pool = pools[poolId];
+ if (borrows[i].interestRate != pool.interestRate) revert WrongInterestRate();
...
}

Support

FAQs

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