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

5 stars 4 forks source link

dhank - A lender can lend 0 amount of LOAN_TOKEN to lock borrowOffer 's remaining collatteral amount. #315

Open sherlock-admin2 opened 1 month ago

sherlock-admin2 commented 1 month ago

dhank

Medium

A lender can lend 0 amount of LOAN_TOKEN to lock borrowOffer 's remaining collatteral amount.

Summary

In the current implementation a user can match against a borrowerOffer proposal and lock his collatteral token by lending a 0 amount.

This can happen when a matchProposals() is called where a loan offer is matched with a borrower offer by fulfilling the entire loan amount mentioned in borrow offer.

Since the collatterisation ratio of the loanOffer should be always less than borrow offer while matching , there will be a remaining amount of collatteralAmount in the proposal even though the entire loan amount is fulfilled.

This can be exploited by the user by calling the acceptBorrowRequest() with that proposal id and the fulfillamount as 0.

Since the check done (here)[https://github.com/sherlock-audit/2024-09-predict-fun/blob/41e70f9eed3f00dd29aba4038544150f5b35dccb/predict-dot-loan/contracts/PredictDotLoan.sol#L1161-L1171] doesnt check the case of 0 fulfillAmount it will the calculate the requiredCollateral amount as the proposal.collateralAmount - fulfillment.collateralAmount whhich is later locked inside the protocol

    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;
        }
    }

Root Cause

A proposal can exist where fullfillment.loanAMount == proposal.loanAmount and fulfillment.collatteralAMount > proposal.collatteralAMount. This will occur when a loanOffer proposal is matched with borrowProposal to fulfillment the entire amount of the borrowOffer

Internal pre-conditions

a matchProposal() should be called to result in this below condition fullfillment.loanAMount == proposal.loanAmount and fulfillment.collatteralAMount > proposal.

External pre-conditions

No response

Attack Path

No response

Impact

A lender can lend 0 amount of LOAN_TOKEN and lock all the remaining non zero amount of collatteral by matching the borrower's proposal.

PoC

none

Mitigation

add neccessary check to identify the fulfillamount.