Reay calculates the interest and fee and transfer the total debt + interest to the contract and fee to the fee receiver.
Collateral amount is transferred to the borrower.
at last the loan struct is deleted.
function repay(uint256[] calldata loanIds) public {
for (uint256 i = 0; i < loanIds.length; i++) {
uint256 loanId = loanIds[i];
Loan memory loan = loans[loanId];
(
uint256 lenderInterest,
uint256 protocolInterest
) = _calculateInterest(loan);
bytes32 poolId = getPoolId(
loan.lender,
loan.loanToken,
loan.collateralToken
);
_updatePoolBalance(
poolId,
pools[poolId].poolBalance + loan.debt + lenderInterest
);
pools[poolId].outstandingLoans -= loan.debt; ----------------->> outstanding value update
IERC20(loan.loanToken).transferFrom(
msg.sender,
address(this),
loan.debt + lenderInterest ---------------------->> debt + interest to sent to contract
);
IERC20(loan.loanToken).transferFrom(
msg.sender,
feeReceiver,
protocolInterest -------------------------------->>> fee to fee receiver
);
IERC20(loan.collateralToken).transfer(
loan.borrower,
loan.collateral ------------------------------------------------->> borrower is sent with collateral.
);
emit Repaid(
msg.sender,
loan.lender,
loanId,
loan.debt,
loan.collateral,
loan.interestRate,
loan.startTimestamp
);
delete loans[loanId]; ---------------------------------->> loan is deleted.
}
}
Since the loan struct is deleted after making the transfer calls, borrower can re-eneter the repay function and drain out the contract funds.
Manual review.
Load the loan details in separate struct in local memory and delete the loan at the start of the function.
use the temporary struct data in further down process.