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

2 stars 2 forks source link

Pheonix - An attacker can potentially consume all loan proposals at relatively low cost #198

Open sherlock-admin2 opened 3 weeks ago

sherlock-admin2 commented 3 weeks ago

Pheonix

Medium

An attacker can potentially consume all loan proposals at relatively low cost

Summary

A malicious attacker can stack up repeated calls of acceptLoanOffer() , repay() in a same block thereby consuming loan proposals without giving any interest. Lenders will not get any compensation for providing liquidity and will have to sign proposals again.

Root Cause

The repay() function is responsible for repayment of the loan by borrower. It calculates the debt based on time elapsed since the start of loan can change the loan status from Active/Called to Repaid https://github.com/sherlock-audit/2024-09-predict-fun/blob/main/predict-dot-loan/contracts/PredictDotLoan.sol#L454-L474

However, there's no requirement of minimum duration required for a loan before repay() is called. This implies that the act of borrowing and repaying can be performed in the same block. Since interest amount is time dependent, it will be zero.

A malicious attacker can take advantage of this by calling acceptLoanOffer() and repay() in the same block potentially consuming the all or majority of loan proposals.

The cost of attack is also relatively low since attacker only needs to pay gas fee and protocol fee which is between 0% to 2% On the contrary, consuming all or majority of the loan offers will hinder refinance() process by repeatedly consuming loans leading to more defaults. Lenders receive no compensation for providing liquidity and are burdened with the inconvenience of having to sign new loan offers repeatedly.

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

  1. The malicious borrower calls acceptLoanOffer() for a loan offer.
  2. Immediately within the same block, the borrower calls repay() before any significant time passes, allowing the borrower to return the principal without interest.
  3. This process is repeated multiple times, consuming all available loan offers in just a few transactions.

Impact

  1. All or majority of loan offers being consumed in just few transactions.
  2. Hindered refinance functionality leading to more defaults.
  3. Bad user experience for lenders, leading to trust erosion.

PoC

No response

Mitigation

Introduce a minimum loan duration for repay() function.

sherlock-admin2 commented 2 weeks ago

The protocol team fixed this issue in the following PRs/commits: https://github.com/PredictDotFun/predict-dot-loan/pull/51