Skip to content

Latest commit

 

History

History
112 lines (80 loc) · 5.42 KB

088.md

File metadata and controls

112 lines (80 loc) · 5.42 KB

Swift Mahogany Urchin

Medium

Borrower can cause loss of lender's fund by exploiting Optimistic Oracle resolution process

Summary

UMA Optimistic Oracle's resolution process can be used to cause significant financial losses for lenders as borrowers will exploit the timing of initial proposals and challenge periods to obtain loans with soon-to-be worthless collateral.

Root Cause

To understand the root cause, we first need to explain how UMA's Optimistic Oracle (OO) resolution works:

  1. Initial Proposal: Anyone can submit an initial proposal for a question's outcome at any time.
  2. Challenge Period: After an initial proposal, there's a 2-hour challenge period during which anyone can dispute the proposed outcome.
  3. Resolution: a. If no one disputes during the challenge period, the proposed outcome is accepted as final. b. If disputed, the question goes to UMA's Data Verification Mechanism (DVM) for resolution, which can take 48-72 hours.

The vulnerability arises because the PredictDotLoan contract allows loan creation at any point during this process, including the challenge period. This creates exploitable windows where a borrower can take out a loan knowing the collateral will soon be worthless.

In PredictDotLoan.sol:_assertQuestionPriceUnavailable() at https://github.com/sherlock-audit/2024-09-predict-fun/blob/main/predict-dot-loan/contracts/PredictDotLoan.sol#L1468

function _assertQuestionPriceUnavailable(QuestionType questionType, bytes32 questionId) private view {
    if (questionType == QuestionType.Binary) {
        _assertBinaryOutcomeQuestionPriceUnavailable(UMA_CTF_ADAPTER, questionId);
    } else {
        if (_isNegRiskMarketDetermined(questionId)) {
            revert MarketResolved();
        }
        _assertBinaryOutcomeQuestionPriceUnavailable(NEG_RISK_UMA_CTF_ADAPTER, questionId);
    }
}

This function only checks if the question price is available, not considering the proposal or challenge period status.

In PredictDotLoan.sol:_assertBinaryOutcomeQuestionPriceUnavailable():

function _assertBinaryOutcomeQuestionPriceUnavailable(address umaCtfAdapter, bytes32 questionId) private view {
    (bool isAvailable, bytes4 umaError) = _isBinaryOutcomeQuestionPriceAvailable(umaCtfAdapter, questionId);

    if (isAvailable) {
        revert QuestionResolved();
    } else if (umaError != 0x579a4801) {
        revert AbnormalQuestionState();
    }
}

This function only reverts if the question is resolved or in an abnormal state, but doesn't consider the proposal or challenge period.

In PredictDotLoan.sol:acceptLoanOffer():

function acceptLoanOffer(Proposal calldata proposal, uint256 fulfillAmount) external nonReentrant whenNotPaused {
    _assertProposalIsLoanOffer(proposal);
    _acceptOffer(proposal, fulfillAmount);
}

This function doesn't include any additional checks related to the Oracle's resolution process.

In PredictDotLoan.sol:_acceptOffer():

function _acceptOffer(Proposal calldata proposal, uint256 fulfillAmount) private {
    bytes32 proposalId = hashProposal(proposal);
    uint256 positionId = _derivePositionId(proposal);

    _assertProposalValidity(proposalId, proposal, positionId, fulfillAmount);
    // ... rest of the function
}

The _assertProposalValidity() function called here doesn't include checks for the Oracle's proposal or challenge period status as it calls _assertQuestionPriceUnavailable.

Internal pre-conditions

  1. [UMA's Optimistic Oracle] is about to receive an initial proposal or be in the challenge period for a question that will render a collateral token worthless
  2. [Lender] needs to have created a loan offer for the soon-to-be worthless collateral token

External pre-conditions

No response

Attack Path

  1. Borrower monitors the UMA Optimistic Oracle for questions at critical stages: a. Just before an expected initial proposal submission (which can occur at any time depending on the time of the question e..g. will gold hit a particular price before end of 2024, which can be resolved anytime in 2024?) b. During the 2-hour challenge period after an initial proposal
  2. Borrower procures the required collateral tokens at a much lower market price, anticipating the imminent negative resolution
  3. Borrower identifies a loan offer for the collateral token that will soon be worthless
  4. Borrower calls acceptLoanOffer() function at the opportune moment a. Just before a proposer submits an unfavorable outcome by front-running the initial proposal b. During the 2-hour challenge period of an unfavorable outcome or during the dispute period in case of disputes
  5. PredictDotLoan contract checks question status, which is still considered unresolved, and allows the loan
  6. Loan is created, and borrower receives the loan amount
  7. After the 2-hour challenge period (or dispute period if applicable), the question is resolved, rendering the collateral worthless
  8. Borrower does not repay the loan, as the collateral is now worthless

Impact

The lender suffers a loss equal to the full loan amount. The borrower gains this amount minus the cost of procuring the collateral tokens and any transaction fees. Even if the borrower couldn't procure the tokens at a significantly lower price, the lender still suffers a complete loss of the loaned funds with minimal loss to borrower. The borrower's profit is any difference between the loan amount and their cost to acquire the collateral tokens.

PoC

No response

Mitigation