Ondo Finance - baz1ka's results

Institutional-Grade Finance, Now Onchain.

General Information

Platform: Code4rena

Start Date: 29/03/2024

Pot Size: $36,500 USDC

Total HM: 5

Participants: 72

Period: 5 days

Judge: 3docSec

Total Solo HM: 1

Id: 357

League: ETH

Ondo Finance

Findings Distribution

Researcher Performance

Rank: 46/72

Findings: 1

Award: $8.28

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

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

Vulnerability details

Vulnerability Details

Functions ousgInstantManager.mint(), ousgInstantManager.mintRebasingOUSG(), ousgInstantManager.redeem() and ousgInstantManager.redeemRebasingOUSG() fully rely on output of ousgInstantManager.getOUSGPrice(). This function returns price of OUSG in USDC from oracle.

function getOUSGPrice() public view returns (uint256 price) {
  (price, ) = oracle.getPriceData();
  require(
    price > MINIMUM_OUSG_PRICE,
    "OUSGInstantManager::getOUSGPrice: Price unexpectedly low"
  );
}

As written in natspec.

@dev Sanity check: this function will revert if the price is unexpectedly low

For that, there is require statement that checks whether price from oracle satisfies minimum OUSG price in USDC which is 105e18. But there is no guarantee that price won't go lower than MINIMUM_OUSG_PRICE, so If price naturally goes lower (oracle aggregates price from exchangers where price is lower, owners of OUSG make more sales in OUSG/USDC pool, etc.) then all of mint and redeem functions won't work as transaction would revert. As contract ousgInstantManager is not upgradable and price of OUSG constantly lower than MINIMUM_OUSG_PRICE users won't be able to retrieve their USDC for owned OUSG and rOUSG and they would lose all of deposited USDC.

Impact

Deposited by users USDC are stuck if price naturally or not goes lower than MINIMUM_OUSG_PRICE.

To mitigate that, protocol should make this variable dynamic and add ability to change it by configurer (or admin). In that case, if configurer lowers minimum OUSG price then user can redeem their USDC even if price is low, so they can get back at least part of initial deposit.

@@ -59,9 +59,6 @@ contract OUSGInstantManager is
   // Role to pause minting and redemptions
   bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

-  // Safety circuit breaker in case of Oracle malfunction
-  uint256 public constant MINIMUM_OUSG_PRICE = 105e18;
-
   // Helper constant that allows us to precisely specify fees in basis points
   uint256 public constant FEE_GRANULARITY = 10_000;

@@ -89,6 +86,9 @@ contract OUSGInstantManager is
   // The address that receives USDC for subscriptions
   address public immutable usdcReceiver;

+  // Safety circuit breaker in case of Oracle malfunction
+  uint256 public minimumOUSGPrice = 105e18;
+
   // Address of the oracle that provides the `ousgPrice`
   IRWAOracle public oracle;

@@ -479,7 +479,7 @@ contract OUSGInstantManager is
   function getOUSGPrice() public view returns (uint256 price) {
     (price, ) = oracle.getPriceData();
     require(
-      price > MINIMUM_OUSG_PRICE,
+      price > minimumOUSGPrice,
       "OUSGInstantManager::getOUSGPrice: Price unexpectedly low"
     );
   }
@@ -788,6 +788,16 @@ contract OUSGInstantManager is
     emit RedeemUnpaused();
   }

+  /// @notice Change minimum OUSG price
+  function changeMinimumOUSGPrice(
+    uint256 _newMinimumOUSGPrice
+  ) external onlyRole(CONFIGURER_ROLE) {
+    uint256 oldMinimumOUSGPrice = minimumOUSGPrice;
+    minimumOUSGPrice = _newMinimumOUSGPrice;
+
+    emit MinimumOUSGPriceSet(oldMinimumOUSGPrice, _newMinimumOUSGPrice);
+  }
@@ -322,4 +322,15 @@ interface IOUSGInstantManager {
     address oldInvestorBasedRateLimiter,
     address newInvestorBasedRateLimiter
   );
+
+  /**
+   * @notice Event emitted when minimum OUSG price is set
+   *
+   * @param oldMinimumOUSGPrice Old minimum OUSG price
+   * @param newMinimumOUSGPrice New minimum OUSG price
+   */
+  event MinimumOUSGPriceSet(
+    uint256 oldMinimumOUSGPrice,
+    uint256 newMinimumOUSGPrice
+  );
 }

Assessed type

Oracle

#0 - c4-pre-sort

2024-04-04T04:33:23Z

0xRobocop marked the issue as duplicate of #245

#1 - c4-judge

2024-04-09T13:01:21Z

3docSec changed the severity to QA (Quality Assurance)

#2 - c4-judge

2024-04-09T13:01:56Z

3docSec marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter