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

Borrower can avoid liquidation by buying his/her own loan with fake tokens pool

Summary

Due to the fact that there is no TokenMismatch() validation, anyone can bring the loan to a fake pool with fake token pairs and take advantage of becoming the loan.lender (calling buyLoan()). Especially for borrower.

Vulnerability Details

In the event of the auction, borrower observes that there is no pool willing to buy his/her loan and it nearly gets to an end of the auction. Here he/she can set a pool with fake loanToken and collateralToken and self-buy his/her loan with the pool via buyLoan(), which makes he/she become the loan's lender and control liquidation flow of his/her loan. https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol#L465, as you can see there is no check if pool.loanToken != loan.loanToken and pool.collateralToken != loan.collateralToken.

POC

Actors: Borrower, Lender1
**Pools: Pool1 with fake token pairs, which is the pool of the borrower to self-buy his/her loan.

  1. Lender1 starts the auction of the Borrower's loan.

  2. Borrower knows the loan debt above and adds fake loanToken to Pool1 so that the poolBalance is enough for the loan via addToPool().

  3. Borrower buys the loan via buyLoan() with loanId and Pool1Id as the params. Since the function doesn't check if the new pool's loanToken and collateralToken is the same as loanId's pairs, this successfully passes.

  4. Borrower now becomes the loan.lender and avoid being liquidated, since the auction can only be started by the loan.lender (assuming there is no pool around with alike pairs and the borrower doesn't want to use refinance()).

Impact

The borrower of the loan can prevent his/her loan from being liquidated. Creating bad outstanding debts in the protocol.

Tools Used

Manual

Recommendations

  1. Implement a validation for token pairs in buyLoan() like other functions in the protocol.

+ Pool memory pool = pools[poolId];
+ // validate the new loan
+ if (pool.loanToken != loan.loanToken) revert TokenMismatch();
+ if (pool.collateralToken != loan.collateralToken) revert TokenMismatch();

Support

FAQs

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