toggleAutoRefinancingEnabled() can be called during auto-refinancing process.
Internal pre-conditions
Similar logic on-chain logic applies to off-chain simulation, leading to a case whereby the auto-refinance can't be vetoed for all users involved on-chain and because loan proposals have a max duration, refinanced loans might eventually fail to go through when finally passed on-chain; if the loan proposer withdraws their loan or the expected duration has passed.
External pre-conditions
No response
Attack Path
-The malicious user after toggling the auto-refinance on detects the pending transaction and quickly toggles off the autoRefinancingEnabled flag for the borrower.
-When the refinance function executes, the check if (autoRefinancingEnabled[borrower] == 0) fails.
-The transaction reverts with the error BorrowerDidNotEnableAutoRefinancing, preventing the refinancing process from completing for all the users involved.
-protocol removes the malicious user from auto-refinance but before the transaction is eventually processed on chain the expected time for loan re-payment has passed and loan is called and seized by lender. Or the proposal matched to refinance loan has expired or withdrawn by the proposer
Impact
The refinancing process is disrupted, preventing legitimate users from refinancing their loans and a subsequent loss of funds
PoC
below is the refinance function which process auto-refinance in batches.
the function checks if the autoRefinancingEnabled[borrower] == 0) which can be manipulated by a malicious borrower
function refinance(
Refinancing[] calldata refinancings
) external nonReentrant whenNotPaused onlyRole(REFINANCIER_ROLE) {
RefinancingResult[] memory results = new RefinancingResult[](refinancings.length);//
for (uint256 i; i < refinancings.length; ++i) {
Refinancing calldata refinancing = refinancings[i];//
(uint256 id, Loan memory loan, uint256 protocolFee) = _refinance(refinancing);
// Doing this check after the refinancing, but in realitiy
// it does not matter because the transaction simulation would've
// failed before it is submitted on-chain.
address borrower = loan.borrower;
if (autoRefinancingEnabled[borrower] == 0) {
revert BorrowerDidNotEnableAutoRefinancing(borrower);
}
results[i] = RefinancingResult(
hashProposal(refinancing.proposal),
refinancing.loanId,
id,
loan.lender,
loan.collateralAmount,
loan.loanAmount,
loan.interestRatePerSecond,
loan.minimumDuration,
protocolFee
);
}
emit LoansRefinanced(results);
}
here the malicious borrower toggles off auto-refinancing leading to revert of the whole transactions
Cool Ash Ostrich
High
Malicious user can front-run refinancing to cause DOS
Summary
https://github.com/sherlock-audit/2024-09-predict-fun/blob/main/predict-dot-loan/contracts/PredictDotLoan.sol#L502-L530 A vulnerability exists in the refinancing function where a malicious user can front-run the transaction by toggling off the autoRefinancingEnabled flag for borrowers. This causes a denial of service (DoS) by preventing the refinancing process from completing, thereby hindering legitimate users from refinancing their loans.
Root Cause
toggleAutoRefinancingEnabled() can be called during auto-refinancing process.
Internal pre-conditions
External pre-conditions
No response
Attack Path
-The malicious user after toggling the auto-refinance on detects the pending transaction and quickly toggles off the autoRefinancingEnabled flag for the borrower. -When the refinance function executes, the check if (autoRefinancingEnabled[borrower] == 0) fails. -The transaction reverts with the error BorrowerDidNotEnableAutoRefinancing, preventing the refinancing process from completing for all the users involved. -protocol removes the malicious user from auto-refinance but before the transaction is eventually processed on chain the expected time for loan re-payment has passed and loan is called and seized by lender. Or the proposal matched to refinance loan has expired or withdrawn by the proposer
Impact
The refinancing process is disrupted, preventing legitimate users from refinancing their loans and a subsequent loss of funds
PoC
below is the refinance function which process auto-refinance in batches. the function checks if the autoRefinancingEnabled[borrower] == 0) which can be manipulated by a malicious borrower
here the malicious borrower toggles off auto-refinancing leading to revert of the whole transactions
Mitigation
Ensure that the autoRefinancingEnabled flag cannot be toggled during the execution of the refinancing transaction.