mirror of
https://github.com/Instadapp/fluid-contracts-public.git
synced 2024-07-29 21:57:37 +00:00
81 lines
3.8 KiB
Solidity
81 lines
3.8 KiB
Solidity
|
// SPDX-License-Identifier: BUSL-1.1
|
||
|
pragma solidity 0.8.21;
|
||
|
|
||
|
import { ErrorTypes } from "../errorTypes.sol";
|
||
|
import { IRedstoneOracle } from "../interfaces/external/IRedstoneOracle.sol";
|
||
|
import { Error as OracleError } from "../error.sol";
|
||
|
import { ChainlinkOracleImpl } from "./chainlinkOracleImpl.sol";
|
||
|
import { RedstoneOracleImpl } from "./redstoneOracleImpl.sol";
|
||
|
|
||
|
/// @title Fallback Oracle implementation
|
||
|
/// @notice This contract is used to get the exchange rate from a main oracle feed and a fallback oracle feed.
|
||
|
//
|
||
|
// @dev inheriting contracts should implement a view method to expose `_FALLBACK_ORACLE_MAIN_SOURCE`
|
||
|
abstract contract FallbackOracleImpl is OracleError, RedstoneOracleImpl, ChainlinkOracleImpl {
|
||
|
/// @dev which oracle to use as main source:
|
||
|
/// - 1 = Chainlink ONLY (no fallback)
|
||
|
/// - 2 = Chainlink with Redstone Fallback
|
||
|
/// - 3 = Redstone with Chainlink Fallback
|
||
|
uint8 internal immutable _FALLBACK_ORACLE_MAIN_SOURCE;
|
||
|
|
||
|
/// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.
|
||
|
/// @param mainSource_ which oracle to use as main source:
|
||
|
/// - 1 = Chainlink ONLY (no fallback)
|
||
|
/// - 2 = Chainlink with Redstone Fallback
|
||
|
/// - 3 = Redstone with Chainlink Fallback
|
||
|
/// @param chainlinkParams_ chainlink Oracle constructor params struct.
|
||
|
/// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)
|
||
|
constructor(
|
||
|
uint8 mainSource_,
|
||
|
ChainlinkConstructorParams memory chainlinkParams_,
|
||
|
RedstoneOracleData memory redstoneOracle_
|
||
|
)
|
||
|
ChainlinkOracleImpl(chainlinkParams_)
|
||
|
RedstoneOracleImpl(
|
||
|
address(redstoneOracle_.oracle) == address(0)
|
||
|
? RedstoneOracleData(IRedstoneOracle(_REDSTONE_ORACLE_NOT_SET_ADDRESS), false, 1)
|
||
|
: redstoneOracle_
|
||
|
)
|
||
|
{
|
||
|
if (mainSource_ < 1 || mainSource_ > 3) {
|
||
|
revert FluidOracleError(ErrorTypes.FallbackOracle__InvalidParams);
|
||
|
}
|
||
|
_FALLBACK_ORACLE_MAIN_SOURCE = mainSource_;
|
||
|
}
|
||
|
|
||
|
/// @dev returns the exchange rate for the main oracle source, or the fallback source (if configured) if the main exchange rate
|
||
|
/// fails to be fetched. If returned rate is 0, fetching rate failed or something went wrong.
|
||
|
/// @return exchangeRate_ exchange rate
|
||
|
/// @return fallback_ whether fallback was necessary or not
|
||
|
function _getRateWithFallback() internal view returns (uint256 exchangeRate_, bool fallback_) {
|
||
|
if (_FALLBACK_ORACLE_MAIN_SOURCE == 1) {
|
||
|
// 1 = Chainlink ONLY (no fallback)
|
||
|
exchangeRate_ = _getChainlinkExchangeRate();
|
||
|
} else if (_FALLBACK_ORACLE_MAIN_SOURCE == 2) {
|
||
|
// 2 = Chainlink with Redstone Fallback
|
||
|
exchangeRate_ = _getChainlinkExchangeRate();
|
||
|
if (exchangeRate_ == 0) {
|
||
|
fallback_ = true;
|
||
|
exchangeRate_ = _getRedstoneExchangeRate();
|
||
|
}
|
||
|
} else {
|
||
|
// 3 = Redstone with Chainlink Fallback
|
||
|
exchangeRate_ = _getRedstoneExchangeRate();
|
||
|
if (exchangeRate_ == 0) {
|
||
|
fallback_ = true;
|
||
|
exchangeRate_ = _getChainlinkExchangeRate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// @dev returns the exchange rate for Chainlink, or Redstone if configured & Chainlink fails.
|
||
|
function _getChainlinkOrRedstoneAsFallback() internal view returns (uint256 exchangeRate_) {
|
||
|
exchangeRate_ = _getChainlinkExchangeRate();
|
||
|
|
||
|
if (exchangeRate_ == 0 && _FALLBACK_ORACLE_MAIN_SOURCE != 1) {
|
||
|
// Chainlink failed but Redstone is configured too -> try Redstone
|
||
|
exchangeRate_ = _getRedstoneExchangeRate();
|
||
|
}
|
||
|
}
|
||
|
}
|