Olympus DAO contest - Jujic's results

Version 3 of Olympus protocol, a decentralized floating currency.

General Information

Platform: Code4rena

Start Date: 25/08/2022

Pot Size: $75,000 USDC

Total HM: 35

Participants: 147

Period: 7 days

Judge: 0xean

Total Solo HM: 15

Id: 156

League: ETH

Olympus DAO

Findings Distribution

Researcher Performance

Rank: 145/147

Findings: 1

Award: $11.03

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

11.0311 DAI - $11.03

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed

External Links

Lines of code

https://github.com/code-423n4/2022-08-olympus/blob/b5e139d732eb4c07102f149fb9426d356af617aa/src/modules/PRICE.sol#L154-L180

Vulnerability details

Impact

Oracle data feed is insufficiently validated. There is no check for stale price and round completeness. Price can be stale and can lead to wrong return value.

Proof of Concept

https://github.com/code-423n4/2022-08-olympus/blob/b5e139d732eb4c07102f149fb9426d356af617aa/src/modules/PRICE.sol#L154-L180

function getCurrentPrice() public view returns (uint256) { if (!initialized) revert Price_NotInitialized(); // Get prices from feeds uint256 ohmEthPrice; uint256 reserveEthPrice; { (, int256 ohmEthPriceInt, , uint256 updatedAt, ) = _ohmEthPriceFeed.latestRoundData(); // Use a multiple of observation frequency to determine what is too old to use. // Price feeds will not provide an updated answer if the data doesn't change much. // This would be similar to if the feed just stopped updating; therefore, we need a cutoff. if (updatedAt < block.timestamp - 3 * uint256(observationFrequency)) revert Price_BadFeed(address(_ohmEthPriceFeed)); ohmEthPrice = uint256(ohmEthPriceInt); int256 reserveEthPriceInt; (, reserveEthPriceInt, , updatedAt, ) = _reserveEthPriceFeed.latestRoundData(); if (updatedAt < block.timestamp - uint256(observationFrequency)) revert Price_BadFeed(address(_reserveEthPriceFeed)); reserveEthPrice = uint256(reserveEthPriceInt); } // Convert to OHM/RESERVE price uint256 currentPrice = (ohmEthPrice * _scaleFactor) / reserveEthPrice; return currentPrice; }

Tools Used

... (uint80 roundID, int256 ohmEthPriceInt, , uint256 updatedAt, uint80 answeredInRound) = _ohmEthPriceFeed.latestRoundData(); require(ohmEthPriceIn > 0, "ChainLink: price <= 0"); require(answeredInRound >= roundID, "ChainLink: Stale price"); ... (uint80 roundID, reserveEthPriceInt, , updatedAt, uint80 answeredInRound ) = _reserveEthPriceFeed.latestRoundData(); require(reserveEthPriceInt > 0, "ChainLink: price <= 0"); require(answeredInRound >= roundID, "ChainLink: Stale price"); ...

#0 - Oighty

2022-09-06T18:52:51Z

Duplicate. See comment on #441.

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