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

Malicious lender can steal the collateral by frontrunning the `borrow()` call to change the loan terms

Summary

By calling the borrow() method, the user can borrow funds from a specified pool. However, the terms of the loans from that pool, such as auctionLength and interestRate, can be modified between the moment when the user sends the transaction and when the loan actually gets created. This can effectively give the malicious lender the opportunity to claim the collateral without a valid auction.

Vulnerability Details

Please consider the following scenario:

  1. Alice creates a pool of USDC/WETH in the protocol, setting the maxLoanRatio to 15 * 1e12, meaning for each borrowed WETH she expects a collateral of at least 4_000 USDC. She also sets auctionLength to 1 day.

  2. Bob sees Alice's pool, finds the terms favorable and decides to borrow 10 WETH from it, providing 40_000 USDC as a collateral. Assuming the price of WETH = 2_000 USDC, the loan will be 100% overcollateralized. It would be beneficial for Alice to claim the collateral without putting the loan to an auction.

  3. Alice sees the Bob's transaction in the mempool and frontruns it with calling setPool() method, overriding the auctionLength of her pool to 1 second.

  4. Alice puts the loan at an auction. Given that the auction time is one second, it will expire before anyone would be able to buy it (it's almost impossible for someone to buy the loan from an auction in the same block as the auction started, this will require backrunning and accepting the 0 interestRate).

  5. After 1 block Alice calls seizeLoan(), effectively claiming Bob's collateral.

The exact same scenario may also happen if Bob tries to refinance his loan to Alice's pool by calling refinance() method.

Impact

Borrower's collateral may be stolen by the lender or the borrower may be forced into a loan with conditions they have not agreed upon.

Tools Used

Manual Review

Recommendations

Add the critical loan's parameters, such as auctionLength and interestRate, to the Borrow struct, so that the borrower specifies the conditions they agree to and the borrowing can't be frontrun.

Support

FAQs

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