Attacker can grief auction, decrease pool balance & increase outstanding loans by buying an auctioned loan back to the same pool.
Lender.buyLoan() doesn't check if the poolId parameter is the same pool that has auctioned the loan. An attacker can use Lender.buyLoan() to grief the selling pool by stopping the auction via buying the auctioned loan back to the same pool. This also reduces that pool's balance and increases that pool's outstanding loans, negatively impacting the pool's financials.
Proof of concept: first add the following utility functions to Lender.sol:
Then add the test to test/Lender.t.sol:
Attacker can grief any auction stopping it at will by buying the auctioned loan back to the originating pool. This also decreases the pool's balance & increases the pool's outstanding loans, hurting the pool financially.
Manual
Lender.buyLoan() must check poolId parameter does not match the selling poolId.
The decrease in pool balance & increase in pool outstanding debt is due to a mismatch between L489-490 & L498-502 where the first includes protocolInterest but the second doesn't.
The same mismatch occurs in giveLoan() compare L387-388 vs L396-400 but this isn't directly exploitable as only the lender can call giveLoan(), giveLoan() should also have a sanity check that poolId != oldPoolId
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.