Due to missing validation for the input pool in the buyAuction function, an attacker can steal an auctioned loan and convert it to the collateral or obtain the debt amount with a negligible expense.
The buyAuction function doesn't validate the input poolId for the same set of loan and collateral tokens as the loan. The only necessary conditions for a pool to eligible are:
The interest rate must not be higher than the currentAuctionRate
The value of pool balance must not be less than the current total debt of the loan.
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L465-L534
This allows an attacker to create a pool with random tokens and perform the following attack:
The attacker first creates two ERC20 tokens and then creates a pool with the following state:
balance > totalDebt of the auctioned loan.
interest rate < currentAuctionRate
The attacker buys the auctioned loan passing in this newly created poolId. Since the necessary conditions are met, the loan is now transferred to the attacker.
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L465-L534
To be able to receive repayments and to seize the loan the attacker needs to have a pool with the same set of loan / collateral token and an outstanding debt greater than or equal to the debt of this loan.
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L292-L345
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L548-L586
For this the attacker creates a pool with the same set of loan / collateral token and sets the balance of the pool equal to the debt of this loan. To get an outstanding debt, the attacker sets the maxLoanRatio to type(uint256).max and borrows the debt amount himself for negligible amount of collateral.
The attacker then creates an auction for this loan. Now he will either be able to:
Obtain the debt amount from the borrower if the borrower repays.
Obtain the debt amount if somebody else buys this loan.
Obtain the collateral amount by seizing the loan if nobody buys.
Auctioned loans can be stolen and converted to the collateral amount or the debt amount. This will disrupt the accounting of the system and will make it insolvent. ie. eventually for a pool owner, either there wouldn't be enough tokens in the contract to withdraw funds from a pool or there would be no collateral to seize from.
Manual review
Keep validations for the pool tokens and the owner in the buyAuction function.
https://github.com/Cyfrin/2023-07-beedle/blob/658e046bda8b010a5b82d2d85e824f3823602d27/src/Lender.sol#L465-L534
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.