code-423n4 / 2024-03-ondo-finance-findings

5 stars 6 forks source link

Manipulation Oracle Price Leads to Financial Discrepancy #178

Closed c4-bot-10 closed 6 months ago

c4-bot-10 commented 6 months ago

Lines of code

https://github.com/code-423n4/2024-03-ondo-finance/blob/78779c30bebfd46e6f416b03066c55d587e8b30b/contracts/ousg/rOUSG.sol#L378

Vulnerability details

Description

In The getOUSGPrice function the issue is present in it and it’s directly influences the contract's financial calculations for minting and redeeming OUSG and it’s arise due to the contract's reliance on an external oracle for fetching OUSG prices without any present of secondary validation or fallbacks

function getOUSGPrice() public view returns (uint256 price) {
    (price, ) = oracle.getPriceData();
  }

Impact

The vulnerability is can lead to financial discrepancies within the contract and this resulting in unfair advantages of financial gaine for malicious actors, ultimately affecting all stakeholders. Over time, consistent manipulation of oracle prices even within what is considered 'safe' by the contract's own sanity checks can result in substantial financial losses

Proof of Concept

As scenario i fuzz with a scenario that the contract's behavior over 10,000 iterations with variable oracle prices. The oracle prices were slightly manipulated within acceptable bounds with scenario of oracle price inaccuracies. And as results it’s showcased a net gain in USDC received from redemptions compared to USDC spent on minting (Total USDC Spent: 10,000,000, Total USDC Received: 10,031,547.76), and this indicating a financial imbalance in the contract's operations over time Here is the fuzz test


import random
import numpy as np

def simulate_oracle_price(min_price=105, max_price=150, manipulation_factor=0.1):
    """
    Simulates oracle price with optional manipulation.
    Prices are normally distributed around a mean with a slight manipulation factor.
    """
    mean_price = (max_price + min_price) / 2
    manipulated_price = mean_price * (1 + random.uniform(-manipulation_factor, manipulation_factor))
    return max(min_price, min(max_price, manipulated_price))

def mint_ousg(usdc_amount, oracle_price):
    """
    Simplified minting logic based on oracle price.
    """
    return usdc_amount / oracle_price

def redeem_ousg(ousg_amount, oracle_price):
    """
    Simplified redemption logic based on oracle price.
    """
    return ousg_amount * oracle_price

def fuzz_test(iterations=10000, usdc_per_iteration=1000):
    """
    Fuzz test simulating oracle manipulation and its impact over multiple iterations.
    """
    total_usdc_spent = 0
    total_usdc_received = 0

    for _ in range(iterations):
        current_price = simulate_oracle_price()
        ousg_minted = mint_ousg(usdc_per_iteration, current_price)
        total_usdc_spent += usdc_per_iteration

        # Assume price manipulation occurs here
        manipulated_price = simulate_oracle_price()
        usdc_received = redeem_ousg(ousg_minted, manipulated_price)
        total_usdc_received += usdc_received

    print(f"Total USDC Spent: {total_usdc_spent}, Total USDC Received: {total_usdc_received}")
    return total_usdc_spent, total_usdc_received

# Run the fuzz test
fuzz_test_result = fuzz_test()
fuzz_test_result

Tools Used

Manual review

Recommended Mitigation Steps

Assessed type

Other

c4-pre-sort commented 6 months ago

0xRobocop marked the issue as insufficient quality report

c4-judge commented 6 months ago

3docSec marked the issue as duplicate of #144

c4-judge commented 6 months ago

3docSec marked the issue as unsatisfactory: Out of scope