Attacker can deny new loans to a pool by exploiting Lender.refinance() to set pool.poolBalance to 0.
There are two keys to this attack:
Lender.refinance() doesn't verify that the input poolId parameter isn't the same as the loan's current pool, allowing a borrower to refinance into the same pool,
Lender.refinance() subtracts the loan's debt from pool.poolBalance twice, first in L636 then again in L698.
An attacker can combine these to:
take a loan with the pool,
call refinance enough times until pool.poolBalance has been set to 0
By corrupting pool.poolBalance the pool can't take any new loans as Lender.borrow() will revert at L243.
Proof of concept. First add this utility function in Lender.sol:
Then add the test to test/Lender.t.sol:
The pool state gets corrupted by having pool.poolBalance set to 0, which prevents the pool from taking on any new loans.
Manual
Remove the second deduction at L698. Also consider whether borrowers should be able to refinance() back into the same pool & if not then revert in this case.
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.