sherlock-audit / 2024-09-predict-fun-judging

0 stars 0 forks source link

Energetic Tangelo Starfish - Malicious user will DOS refinance(batch) by reverting on ERC1155Received() #243

Open sherlock-admin2 opened 2 days ago

sherlock-admin2 commented 2 days ago

Energetic Tangelo Starfish

High

Malicious user will DOS refinance(batch) by reverting on ERC1155Received()

Summary

The refinance(batch) function refinances users' loans. Since loans are replaced with more favorable ones, the user's initial collateral may exceed the required amount. Therefore, in the _refinance function, there is a call to _transferExcessCollateralIfAny. This function sends the excess collateral to the borrower. As the collateral is CTF — an ERC1155 standard token, when calling CTF.safeTransferFrom(address(this), receiver, positionId, excessCollateral, "") a callback to the receiver's address occurs, invoking the onERC1155Received function. Thus, an intentional or accidental revert within this function will lead to the entire refinance(batch) function call being interrupted, and regular users' loans will also not be refinanced.

Root Cause

In PredictDotLoan::_refinance::1119, the possibility of a revert call is not checked. Since _refinance is called for each loan in PredictDotLoan::refinance(batch), a revert of one loan will lead to a revert of the entire transaction.

Internal pre-conditions

The REFINANCIER must include the attacker's loan in the refinancings (it is impossible to identify the attacker at the off-chain list formation stage). The attacker's loan should be refinanced into a loan where its collateral is greater than necessary. (In an active market, this is also a very common occurrence, especially considering that in most cases, the required collateral is rounded down.)

function _calculateCollateralAmountRequired(
        Proposal calldata proposal,
        Fulfillment storage fulfillment,
        uint256 fulfillAmount
    ) private view returns (uint256 collateralAmountRequired) {
        if (fulfillment.loanAmount + fulfillAmount == proposal.loanAmount) {
            collateralAmountRequired = proposal.collateralAmount - fulfillment.collateralAmount;
        } else {
            collateralAmountRequired = (proposal.collateralAmount * fulfillAmount) / proposal.loanAmount;
        }
    }

External pre-conditions

No external pre-conditions

Attack Path

The attacker must write a smart contract that will take debts on the platform, and revert the ERC1155Received call from the Predict.loan address

Impact

DoS of the refinance(batch) function. The protocol will not be able to refinance users' loans on more favorable terms. An attacker can exploit this to take advantage of more favorable loan offers themselves, preventing them from being used to refinance existing loans. This disrupts the protocol's functionality, for which off-chain software is written. To carry out this attack, the attacker only needs to create a loan on the platform by exchanging their CTF for Loan Tokens, losing almost nothing in the process.

PoC

No response

Mitigation

You should either wrap the safeTransferFrom call in a try catch, or follow the Solidity Withdraw Pattern, letting each user withdraw their funds from the contract in a separate transaction.