20,000 USDC
View results
Submission Details
Severity: high
Valid

refinance reduced poolBalance twice, resulting in pool losses

Summary

The poolBalance is reduced twice in the refinance function, resulting ina pool loss.

Vulnerability Details

// now lets deduct our tokens from the new pool
// @audit first here
_updatePoolBalance(poolId, pools[poolId].poolBalance - debt);
pools[poolId].outstandingLoans += debt;
if (debtToPay > debt) {
// we owe more in debt so we need the borrower to give us more loan tokens
// transfer the loan tokens from the borrower to the contract
IERC20(loan.loanToken).transferFrom(
msg.sender,
address(this),
debtToPay - debt
);
} else if (debtToPay < debt) {
// we have excess loan tokens so we give some back to the borrower
// first we take our borrower fee
uint256 fee = (borrowerFee * (debt - debtToPay)) / 10000;
IERC20(loan.loanToken).transfer(feeReceiver, fee);
// transfer the loan tokens from the contract to the borrower
IERC20(loan.loanToken).transfer(msg.sender, debt - debtToPay - fee);
}
// transfer the protocol fee to governance
IERC20(loan.loanToken).transfer(feeReceiver, protocolInterest);
// update loan debt
loans[loanId].debt = debt;
// update loan collateral
if (collateral > loan.collateral) {
// transfer the collateral tokens from the borrower to the contract
IERC20(loan.collateralToken).transferFrom(
msg.sender,
address(this),
collateral - loan.collateral
);
} else if (collateral < loan.collateral) {
// transfer the collateral tokens from the contract to the borrower
IERC20(loan.collateralToken).transfer(
msg.sender,
loan.collateral - collateral
);
}
emit Repaid(
msg.sender,
loan.lender,
loanId,
debt,
collateral,
loan.interestRate,
loan.startTimestamp
);
loans[loanId].collateral = collateral;
// update loan interest rate
loans[loanId].interestRate = pool.interestRate;
// update loan start timestamp
loans[loanId].startTimestamp = block.timestamp;
// update loan auction start timestamp
loans[loanId].auctionStartTimestamp = type(uint256).max;
// update loan auction length
loans[loanId].auctionLength = pool.auctionLength;
// update loan lender
loans[loanId].lender = pool.lender;
// update pool balance
// @audit second here
pools[poolId].poolBalance -= debt;

Look at the lines of code I marked above

Impact

Each time a lender calls refinance, funds for the pool corresponding to the new poolId are damaged.

Tools Used

Manual review

Recommendations

Only need reduce once

Support

FAQs

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