Vulnerability Details
Impact
Lender fails to giveLoan because of inconsistent length between loadIds and poolIds, which wastes the gas fees of the Lender.
Proof of concept
function giveLoan(
uint256[] calldata loanIds,
bytes32[] calldata poolIds
) external {
for (uint256 i = 0; i < loanIds.length; i++) {
uint256 loanId = loanIds[i];
bytes32 poolId = poolIds[i];
...
}
}
Here is the giveLoan function which does not check if the loanIds and poolIds have the same length. For example, the lender mistakenly leaves out one of the poolIds which means the last loanId does not map to any poolId since loanIds.length = poolIds.length + 1. Hence, since there is an out-of-bounds error when getting the pool id, poolId = poolIds[i], the entire function will revert due to this error.
function test_giveLoanDifferentLength() public {
test_borrow();
vm.startPrank(lender2);
Pool memory p = Pool({
lender: lender2,
loanToken: address(loanToken),
collateralToken: address(collateralToken),
minLoanSize: 100 * 10 ** 18,
poolBalance: 1000 * 10 ** 18,
maxLoanRatio: 2 * 10 ** 18,
auctionLength: 1 days,
interestRate: 1000,
outstandingLoans: 0
});
lender.setPool(p);
uint256[] memory loanIds = new uint256[](1);
loanIds[0] = 0;
bytes32[] memory poolIds = new bytes32[](0);
vm.startPrank(lender1);
lender.giveLoan(loanIds, poolIds);
}
forge test --match-test giveLoanDifferentLength -vvvv
How to fix
function giveLoan(
uint256[] calldata loanIds,
bytes32[] calldata poolIds
) external {
+ if (loanIds.length != poolIds.length) revert GiveLoanLengthMismatch();
for (uint256 i = 0; i < loanIds.length; i++) {
uint256 loanId = loanIds[i];
bytes32 poolId = poolIds[i];
...
}
}