In the refinance function the new pool balance is updated twice which leads to the pool balance being lower than expected.
In the Lender contract in the refinance function the balance is updated twice - once by calling the _updatePoolBalance function and once by subtracting the pool balance with the debt.
This leads to the pool balance being lower than it is and every time someone refinances the pool balance is lowered twice.
If the owner tries to get his money from the pool he won't be able to collect the full amount if there are people that refinanced their loans to that pool.
`
Add this as state variables to the test to work correctly:
Borrow[] borrowArray;
Refinance[] refinances;
Add this test in the Lender.t.sol contract and run it to see the vulnerability:
function testRefinancing() public {
vm.startPrank(lender1);
Pool memory p = Pool({
lender: lender1,
loanToken: address(loanToken),
collateralToken: address(collateralToken),
minLoanSize: 100*10**18,
poolBalance: 1000*10**18,
maxLoanRatio: 2*10**18,
auctionLength: 1,
interestRate: 1000,
outstandingLoans: 0
});
lender.setPool(p);
vm.stopPrank();
vm.startPrank(lender2);
Pool memory p1 = Pool({
lender: lender2,
loanToken: address(loanToken),
collateralToken: address(collateralToken),
minLoanSize: 100*10**18,
poolBalance: 1000*10**18,
maxLoanRatio: 2*10**18,
auctionLength: 1,
interestRate: 1000,
outstandingLoans: 0
});
lender.setPool(p1);
vm.stopPrank();
bytes32 currentPoolId = lender.getPoolId(lender1, address(loanToken), address(collateralToken));
bytes32 currentPoolId2 = lender.getPoolId(lender2, address(loanToken), address(collateralToken));
vm.startPrank(borrower);
Borrow memory borrow = Borrow({
poolId: currentPoolId,
debt: 200e18,
collateral: 100e18
});
borrowArray.push(borrow);
lender.borrow(borrowArray);
Refinance memory refinance = Refinance({
loanId: 0,
poolId: currentPoolId2,
debt: 300e18,
collateral: 150e18
});
refinances.push(refinance);
lender.refinance(refinances);
vm.stopPrank();
(,,,,uint256 poolBalance2,,,,) = lender.pools(currentPoolId2);
(,,,,uint256 poolBalance,,,,) = lender.pools(currentPoolId);
console.log("Borrower balance: ", loanToken.balanceOf(borrower));
console.log("Borrower balance: ", collateralToken.balanceOf(borrower));
console.log("Pool2 balance: ", poolBalance2);
console.log("Pool1 balance: ", poolBalance);
console.log("Lender contract balance: ", collateralToken.balanceOf(address(lender)));
}
In this test we see that after refinancing I am only borrowing 300 loan tokens and then the pool balance is updated from 1000 loan tokens to 400 loan tokens which is twice the 300 borrowed loan tokens.
Visual Studio Code, Foundry
Remove one of the lines where the pool balance is updated.
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.