The buyLoan
function does not validate if the caller (msg.sender
) is the actual owner of the pool with the given pool id (poolId
). This leads to the inability to repay/seize/auction/refinance the loan and the funds being stuck (for both the lender and the borrower).
An auctioned loan can be bought with the buyLoan
function, providing the loan id (loanId
) and the pool id (poolId
) for the pool to move the loan to. However, it is currently not checked if the caller, msg.sender
is the actual pool owner. Consequently, anyone can call the buyLoan
function for a loan that is currently being auctioned. This will assign the msg.sender
as the new lender of the loan (see line 518). Therefore, anyone can be the new lender without having a pool but utilizing someone else's pool.
As a result, whenever the pool id for a loan is determined as the keccak256 hash of the loan.lender
, loan.loanToken
, and the loan.collateralToken
(e.g., by using the getPoolId
function), this pool id is potentially different than the actual pool id that was supplied to the buyLoan
call.
Subsequently, when the borrower attempts to repay the loan, the determined pool id will use the new loan.lender
, which is set to the incorrect lender address and points to a pool that does not yet exist. The repay
function will then revert in line 314 due to subtracting the loan debt from outstandingLoans
, which is 0.
Ultimately, the loan is stuck, and any further actions are not possible.
Determining the pool id of such a bought loan will be incorrect and not the actual pool id that was supplied to the buyLoan
function. This incorrect pool id is potentially pointing to a non-existent pool, causing the borrower to be unable to repay the loan due to reverting in line 314 of the repay
function caused by insufficient outstandingLoans
(i.e., zero).
Moreover, attempting to use buyLoan
will fail as well due to the same reason as above.
Effectively, both the lender and the borrower have their funds stuck.
Manual Review
Consider verifying that the caller (msg.sender
) is the actual lender of the given poolId
by checking pools[poolId].lender == msg.sender
in the buyLoan
function.
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.