Use of hardcoded price deviation in baseOracleCircuitBreaker()
The `LibOracle::baseOracleCircuitBreaker()` uses the hardcoded value of 50% price deviation, which might be too large when using the ETH as a base price reference. Moreover, the fixed % deviation is considered too risky because the protocol's DAO or admin will not be able to update it in production.\\nThis report raises an issue regarding the `priceDeviation` variable only, as the `invalidFetchData` (2-hour stale check) was flagged as a known issue.\\nThe `baseOracleCircuitBreaker()` is used for verifying the price reported by Chainlink. If the reported price is invalid or its price deviation when compared to the protocol's cached oracle price is more than 50%, the function will fall back to get Uniswap's TWAP price instead.\\nHowever, the `baseOracleCircuitBreaker()` uses a hardcoded value of 50% price deviation (0.5 ether), which might be too large when using the ETH as a base price reference. Moreover, the fixed % deviation is considered too risky because the protocol's DAO or admin will not be able to update it in production.\\n```\\n    //@audit -- this report raises an issue regarding the priceDeviation variable only, as the invalidFetchData (2-hour stale check) was flagged as a known issue\\n    function baseOracleCircuitBreaker(\\n        uint256 protocolPrice,\\n        uint80 roundId,\\n        int256 chainlinkPrice,\\n        uint256 timeStamp,\\n        uint256 chainlinkPriceInEth\\n    ) private view returns (uint256 _protocolPrice) {\\n        bool invalidFetchData = roundId == 0 || timeStamp == 0\\n            || timeStamp > block.timestamp || chainlinkPrice <= 0\\n            || block.timestamp > 2 hours + timeStamp;\\n        uint256 chainlinkDiff = chainlinkPriceInEth > protocolPrice\\n            ? chainlinkPriceInEth - protocolPrice\\n            : protocolPrice - chainlinkPriceInEth;\\n      bool priceDeviation =\\n          protocolPrice > 0 && chainlinkDiff.div(protocolPrice) > 0.5 ether;\\n\\n        //@dev if there is issue with chainlink, get twap price. Compare twap and chainlink\\n      if (invalidFetchData || priceDeviation) { //@audit -- this report raises an issue regarding the priceDeviation variable only, as the invalidFetchData (2-hour stale check) was flagged as a known issue\\n            // rest of code\\n        } else {\\n            return chainlinkPriceInEth;\\n        }\\n    }\\n```\\n\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/libraries/LibOracle.sol#L77-L78\\nhttps://github.com/Cyfrin/2023-09-ditto/blob/a93b4276420a092913f43169a353a6198d3c21b9/contracts/libraries/LibOracle.sol#L81
The % price deviation should be a variable updatable by the protocol's DAO or admin in production.
This report raises an issue regarding the `priceDeviation` variable only, as the `invalidFetchData` (2-hour stale check) was flagged as a known issue.\\nThe use of the hardcoded value of 50% price deviation (0.5 ether) might be too large when using the ETH as a base price reference. Moreover, the fixed % deviation is considered too risky because the protocol's DAO or admin will not be able to update it in production.\\nConsequently, the check for price deviation in the `baseOracleCircuitBreaker()` might not be effective enough for filtering out the stale price in production, directly affecting the quality of the oracle price that will be consumed by the core functions of the `Ditto` protocol (HIGH impact).
```\\n    //@audit -- this report raises an issue regarding the priceDeviation variable only, as the invalidFetchData (2-hour stale check) was flagged as a known issue\\n    function baseOracleCircuitBreaker(\\n        uint256 protocolPrice,\\n        uint80 roundId,\\n        int256 chainlinkPrice,\\n        uint256 timeStamp,\\n        uint256 chainlinkPriceInEth\\n    ) private view returns (uint256 _protocolPrice) {\\n        bool invalidFetchData = roundId == 0 || timeStamp == 0\\n            || timeStamp > block.timestamp || chainlinkPrice <= 0\\n            || block.timestamp > 2 hours + timeStamp;\\n        uint256 chainlinkDiff = chainlinkPriceInEth > protocolPrice\\n            ? chainlinkPriceInEth - protocolPrice\\n            : protocolPrice - chainlinkPriceInEth;\\n      bool priceDeviation =\\n          protocolPrice > 0 && chainlinkDiff.div(protocolPrice) > 0.5 ether;\\n\\n        //@dev if there is issue with chainlink, get twap price. Compare twap and chainlink\\n      if (invalidFetchData || priceDeviation) { //@audit -- this report raises an issue regarding the priceDeviation variable only, as the invalidFetchData (2-hour stale check) was flagged as a known issue\\n            // rest of code\\n        } else {\\n            return chainlinkPriceInEth;\\n        }\\n    }\\n```\\n