A user can buy his own loan and use another user's pool to do so, effectively bricking the loan and draining the other user's pool balance in the process.
Loans can be bought during an auction with the buyLoan function. The comments above the function state that anyone can buy a loan, but they must have a pool to do so. This isn't the case as there is no check inside the function that checks if the poolId points to a pool msg.sender owns.
Because of the missing check the following scenario can occur:
Lender1 creates a pool and for simplicity sake he trades his loanToken to collateralToken for a 1:1 ratio.
Borrower (malicious) borrows the entire poolBalance of Lender1's pool.
Lender2 creates a pool that uses the same loanToken and collateralToken as Lender1's pool.
Time passes and Lender1 puts up Borrower's pool up for auction.
Borrower buys his own loan and uses Lender2's pool as the new owner of his loan.
At this point the loan information is as follow:
loan.lender - Borrower
loan.loanToken - Lender2' loan token
loan.collateralToken - Lender2's collateral token
Even if someone attempts to repay Borrower's loan, he can't, because the poolId is generated from the above variables and no such pool exists, effectively bricking the loan and costing Lender2's entire poolBalance.
POC
Loss of funds for lenders and bricking of loans.
Manual review
Foundry
Add a check inside buyLoan which checks if the poolId that has been passed is actually a pool owner by msg.sender.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.