{ "address": "0xE7A3635E2F1f92A9F9D06EFFe9f74369A5ae9767", "abi": [ { "inputs": [ { "internalType": "string", "name": "infoName_", "type": "string" }, { "components": [ { "internalType": "uint8", "name": "mainSource", "type": "uint8" }, { "components": [ { "internalType": "uint8", "name": "hops", "type": "uint8" }, { "components": [ { "internalType": "contract IChainlinkAggregatorV3", "name": "feed", "type": "address" }, { "internalType": "bool", "name": "invertRate", "type": "bool" }, { "internalType": "uint256", "name": "token0Decimals", "type": "uint256" } ], "internalType": "struct ChainlinkStructs.ChainlinkFeedData", "name": "feed1", "type": "tuple" }, { "components": [ { "internalType": "contract IChainlinkAggregatorV3", "name": "feed", "type": "address" }, { "internalType": "bool", "name": "invertRate", "type": "bool" }, { "internalType": "uint256", "name": "token0Decimals", "type": "uint256" } ], "internalType": "struct ChainlinkStructs.ChainlinkFeedData", "name": "feed2", "type": "tuple" }, { "components": [ { "internalType": "contract IChainlinkAggregatorV3", "name": "feed", "type": "address" }, { "internalType": "bool", "name": "invertRate", "type": "bool" }, { "internalType": "uint256", "name": "token0Decimals", "type": "uint256" } ], "internalType": "struct ChainlinkStructs.ChainlinkFeedData", "name": "feed3", "type": "tuple" } ], "internalType": "struct ChainlinkStructs.ChainlinkConstructorParams", "name": "chainlinkParams", "type": "tuple" }, { "components": [ { "internalType": "contract IRedstoneOracle", "name": "oracle", "type": "address" }, { "internalType": "bool", "name": "invertRate", "type": "bool" }, { "internalType": "uint256", "name": "token0Decimals", "type": "uint256" } ], "internalType": "struct RedstoneStructs.RedstoneOracleData", "name": "redstoneOracle", "type": "tuple" } ], "internalType": "struct FallbackCLRSOracleL2.CLRSConstructorParams", "name": "cLRSParams_", "type": "tuple" }, { "internalType": "address", "name": "sequencerUptimeFeed_", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [ { "internalType": "uint256", "name": "errorId_", "type": "uint256" } ], "name": "FluidOracleError", "type": "error" }, { "inputs": [], "name": "FALLBACK_ORACLE_MAIN_SOURCE", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "chainlinkOracleData", "outputs": [ { "internalType": "uint256", "name": "chainlinkExchangeRate_", "type": "uint256" }, { "internalType": "contract IChainlinkAggregatorV3", "name": "chainlinkFeed1_", "type": "address" }, { "internalType": "bool", "name": "chainlinkInvertRate1_", "type": "bool" }, { "internalType": "uint256", "name": "chainlinkExchangeRate1_", "type": "uint256" }, { "internalType": "contract IChainlinkAggregatorV3", "name": "chainlinkFeed2_", "type": "address" }, { "internalType": "bool", "name": "chainlinkInvertRate2_", "type": "bool" }, { "internalType": "uint256", "name": "chainlinkExchangeRate2_", "type": "uint256" }, { "internalType": "contract IChainlinkAggregatorV3", "name": "chainlinkFeed3_", "type": "address" }, { "internalType": "bool", "name": "chainlinkInvertRate3_", "type": "bool" }, { "internalType": "uint256", "name": "chainlinkExchangeRate3_", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getExchangeRate", "outputs": [ { "internalType": "uint256", "name": "exchangeRate_", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getExchangeRateLiquidate", "outputs": [ { "internalType": "uint256", "name": "exchangeRate_", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getExchangeRateOperate", "outputs": [ { "internalType": "uint256", "name": "exchangeRate_", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "infoName", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "redstoneOracleData", "outputs": [ { "internalType": "uint256", "name": "redstoneExchangeRate_", "type": "uint256" }, { "internalType": "contract IRedstoneOracle", "name": "redstoneOracle_", "type": "address" }, { "internalType": "bool", "name": "redstoneInvertRate_", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "sequencerL2Data", "outputs": [ { "internalType": "address", "name": "sequencerUptimeFeed_", "type": "address" }, { "internalType": "uint256", "name": "maxGracePeriod_", "type": "uint256" }, { "internalType": "bool", "name": "isSequencerUp_", "type": "bool" }, { "internalType": "uint256", "name": "lastUptimeStartedAt_", "type": "uint256" }, { "internalType": "uint256", "name": "gracePeriod_", "type": "uint256" }, { "internalType": "bool", "name": "gracePeriodPassed_", "type": "bool" }, { "internalType": "uint256", "name": "lastOutageStartedAt_", "type": "uint256" }, { "internalType": "bool", "name": "isSequencerUpAndValid_", "type": "bool" } ], "stateMutability": "view", "type": "function" } ], "transactionHash": "0xf5940faf4c555a3838be8dd25343963be17d45eb00360309d7faa6a2568c2ac5", "receipt": { "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A", "contractAddress": null, "transactionIndex": 3, "gasUsed": "2682521", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockHash": "0x5d48d6a4f94aab9b453ec14867ffa3609bf3ac16cd4704230773a037cad2fb05", "transactionHash": "0xf5940faf4c555a3838be8dd25343963be17d45eb00360309d7faa6a2568c2ac5", "logs": [], "blockNumber": 229063962, "cumulativeGasUsed": "3393592", "status": 1, "byzantium": true }, "args": [ "USDT for 1 ARB", { "mainSource": 1, "chainlinkParams": { "hops": 2, "feed1": { "feed": "0xb2A824043730FE05F3DA2efaFa1CBbe83fa548D6", "invertRate": false, "token0Decimals": 18 }, "feed2": { "feed": "0x3f3f5dF88dC9F13eac63DF89EC16ef6e7E25DdE7", "invertRate": true, "token0Decimals": 6 }, "feed3": { "feed": "0x0000000000000000000000000000000000000000", "invertRate": false, "token0Decimals": 0 } }, "redstoneOracle": { "oracle": "0x0000000000000000000000000000000000000000", "invertRate": false, "token0Decimals": 0 } }, "0xFdB631F5EE196F0ed6FAa767959853A9F217697D" ], "numDeployments": 1, "solcInputHash": "ca9e5aa54012862807c9d9299b1ce928", "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"infoName_\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"mainSource\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"hops\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"feed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invertRate\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"token0Decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct ChainlinkStructs.ChainlinkFeedData\",\"name\":\"feed1\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"feed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invertRate\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"token0Decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct ChainlinkStructs.ChainlinkFeedData\",\"name\":\"feed2\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"feed\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invertRate\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"token0Decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct ChainlinkStructs.ChainlinkFeedData\",\"name\":\"feed3\",\"type\":\"tuple\"}],\"internalType\":\"struct ChainlinkStructs.ChainlinkConstructorParams\",\"name\":\"chainlinkParams\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"contract IRedstoneOracle\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"invertRate\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"token0Decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct RedstoneStructs.RedstoneOracleData\",\"name\":\"redstoneOracle\",\"type\":\"tuple\"}],\"internalType\":\"struct FallbackCLRSOracleL2.CLRSConstructorParams\",\"name\":\"cLRSParams_\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sequencerUptimeFeed_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidOracleError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FALLBACK_ORACLE_MAIN_SOURCE\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainlinkOracleData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainlinkExchangeRate_\",\"type\":\"uint256\"},{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"chainlinkFeed1_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"chainlinkInvertRate1_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainlinkExchangeRate1_\",\"type\":\"uint256\"},{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"chainlinkFeed2_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"chainlinkInvertRate2_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainlinkExchangeRate2_\",\"type\":\"uint256\"},{\"internalType\":\"contract IChainlinkAggregatorV3\",\"name\":\"chainlinkFeed3_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"chainlinkInvertRate3_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"chainlinkExchangeRate3_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExchangeRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExchangeRateLiquidate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExchangeRateOperate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"infoName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"redstoneOracleData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"redstoneExchangeRate_\",\"type\":\"uint256\"},{\"internalType\":\"contract IRedstoneOracle\",\"name\":\"redstoneOracle_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"redstoneInvertRate_\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sequencerL2Data\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"sequencerUptimeFeed_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxGracePeriod_\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isSequencerUp_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"lastUptimeStartedAt_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"gracePeriod_\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"gracePeriodPassed_\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"lastOutageStartedAt_\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isSequencerUpAndValid_\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"cLRSParams_\":\"CLRS Fallback Oracle data\",\"infoName_\":\"Oracle identify helper name.\",\"sequencerUptimeFeed_\":\"L2 sequencer uptime Chainlink feed\"}},\"getExchangeRate()\":{\"details\":\"Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for backwards compatibility.\"}},\"title\":\"Chainlink / Redstone Oracle (with fallback) for Layer 2 (with sequencer outage detection)\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"FALLBACK_ORACLE_MAIN_SOURCE()\":{\"notice\":\"which oracle to use as main source: - 1 = Chainlink ONLY (no fallback) - 2 = Chainlink with Redstone Fallback - 3 = Redstone with Chainlink Fallback\"},\"chainlinkOracleData()\":{\"notice\":\"returns all Chainlink oracle related data as utility for easy off-chain use / block explorer in a single view method\"},\"constructor\":{\"notice\":\"sets the main source, Chainlink Oracle and Redstone Oracle data.\"},\"getExchangeRateLiquidate()\":{\"notice\":\"Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations\"},\"getExchangeRateOperate()\":{\"notice\":\"Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates\"},\"infoName()\":{\"notice\":\"helper string to easily identify the oracle. E.g. token symbols\"},\"redstoneOracleData()\":{\"notice\":\"returns all Redstone oracle related data as utility for easy off-chain use / block explorer in a single view method\"},\"sequencerL2Data()\":{\"notice\":\"returns all sequencer uptime feed related data\"}},\"notice\":\"Gets the exchange rate between the underlying asset and the peg asset by using: the price from a Chainlink price feed or a Redstone Oracle with one of them being used as main source and the other one acting as a fallback if the main source fails for any reason. Reverts if fetched rate is 0.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracle/oraclesL2/fallbackCLRSOracleL2.sol\":\"FallbackCLRSOracleL2\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"contracts/oracle/error.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Error {\\n error FluidOracleError(uint256 errorId_);\\n}\\n\",\"keccak256\":\"0xc7b7e945238168d216c480e9dd4fbaaf8780645d58c47f9abdaa4f29910568fe\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary ErrorTypes {\\n /***********************************|\\n | FluidOracleL2 | \\n |__________________________________*/\\n\\n /// @notice thrown when sequencer on a L2 has an outage and grace period has not yet passed.\\n uint256 internal constant FluidOracleL2__SequencerOutage = 60000;\\n\\n /***********************************|\\n | UniV3CheckCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the delta between main price source and check rate source is exceeding the allowed delta\\n uint256 internal constant UniV3CheckCLRSOracle__InvalidPrice = 60001;\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant UniV3CheckCLRSOracle__InvalidParams = 60002;\\n\\n /// @notice thrown when the exchange rate is zero, even after all possible fallbacks depending on config\\n uint256 internal constant UniV3CheckCLRSOracle__ExchangeRateZero = 60003;\\n\\n /***********************************|\\n | FluidOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid info name is passed into a fluid oracle (e.g. not set or too long)\\n uint256 internal constant FluidOracle__InvalidInfoName = 60010;\\n\\n /***********************************|\\n | sUSDe Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant SUSDeOracle__InvalidParams = 60102;\\n\\n /***********************************|\\n | Pendle Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant PendleOracle__InvalidParams = 60201;\\n\\n /// @notice thrown when the Pendle market Oracle has not been initialized yet\\n uint256 internal constant PendleOracle__MarketNotInitialized = 60202;\\n\\n /// @notice thrown when the Pendle market does not have 18 decimals\\n uint256 internal constant PendleOracle__MarketInvalidDecimals = 60203;\\n\\n /// @notice thrown when the Pendle market returns an unexpected price\\n uint256 internal constant PendleOracle__InvalidPrice = 60204;\\n\\n /***********************************|\\n | CLRS2UniV3CheckCLRSOracleL2 | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even after all possible fallbacks depending on config\\n uint256 internal constant CLRS2UniV3CheckCLRSOracleL2__ExchangeRateZero = 60301;\\n\\n /***********************************|\\n | Ratio2xFallbackCLRSOracleL2 | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even after all possible fallbacks depending on config\\n uint256 internal constant Ratio2xFallbackCLRSOracleL2__ExchangeRateZero = 60311;\\n\\n /***********************************|\\n | Chainlink Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant ChainlinkOracle__InvalidParams = 61001;\\n\\n /***********************************|\\n | UniswapV3 Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant UniV3Oracle__InvalidParams = 62001;\\n\\n /// @notice thrown when constructor is called with invalid ordered seconds agos values\\n uint256 internal constant UniV3Oracle__InvalidSecondsAgos = 62002;\\n\\n /// @notice thrown when constructor is called with invalid delta values > 100%\\n uint256 internal constant UniV3Oracle__InvalidDeltas = 62003;\\n\\n /***********************************|\\n | WstETh Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant WstETHOracle__InvalidParams = 63001;\\n\\n /***********************************|\\n | Redstone Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant RedstoneOracle__InvalidParams = 64001;\\n\\n /***********************************|\\n | Fallback Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant FallbackOracle__InvalidParams = 65001;\\n\\n /***********************************|\\n | FallbackCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\\n uint256 internal constant FallbackCLRSOracle__ExchangeRateZero = 66001;\\n\\n /***********************************|\\n | WstETHCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\\n uint256 internal constant WstETHCLRSOracle__ExchangeRateZero = 67001;\\n\\n /***********************************|\\n | CLFallbackUniV3Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\\n uint256 internal constant CLFallbackUniV3Oracle__ExchangeRateZero = 68001;\\n\\n /***********************************|\\n | WstETHCLRS2UniV3CheckCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\\n uint256 internal constant WstETHCLRS2UniV3CheckCLRSOracle__ExchangeRateZero = 69001;\\n\\n /***********************************|\\n | WeETh Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant WeETHOracle__InvalidParams = 70001;\\n}\\n\",\"keccak256\":\"0xf19666bfe3d92c9449423d8d35f35e39a4beac9e23cf547e1e38427ef13a6838\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/fluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidOracle } from \\\"./interfaces/iFluidOracle.sol\\\";\\nimport { ErrorTypes } from \\\"./errorTypes.sol\\\";\\nimport { Error as OracleError } from \\\"./error.sol\\\";\\n\\n/// @title FluidOracle\\n/// @notice Base contract that any Fluid Oracle must implement\\nabstract contract FluidOracle is IFluidOracle, OracleError {\\n /// @dev short helper string to easily identify the oracle. E.g. token symbols\\n //\\n // using a bytes32 because string can not be immutable.\\n bytes32 private immutable _infoName;\\n\\n constructor(string memory infoName_) {\\n if (bytes(infoName_).length > 32 || bytes(infoName_).length == 0) {\\n revert FluidOracleError(ErrorTypes.FluidOracle__InvalidInfoName);\\n }\\n\\n // convert string to bytes32\\n bytes32 infoNameBytes32_;\\n assembly {\\n infoNameBytes32_ := mload(add(infoName_, 32))\\n }\\n _infoName = infoNameBytes32_;\\n }\\n\\n /// @inheritdoc IFluidOracle\\n function infoName() external view returns (string memory) {\\n // convert bytes32 to string\\n uint256 length_;\\n while (length_ < 32 && _infoName[length_] != 0) {\\n length_++;\\n }\\n bytes memory infoNameBytes_ = new bytes(length_);\\n for (uint256 i; i < length_; i++) {\\n infoNameBytes_[i] = _infoName[i];\\n }\\n return string(infoNameBytes_);\\n }\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateOperate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateLiquidate() external view virtual returns (uint256 exchangeRate_);\\n}\\n\",\"keccak256\":\"0x2b56537a18379b4d7f69b9d95ebdb39e302951dbcaca882c27b4405bf1ea784b\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/fluidOracleL2.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidOracle } from \\\"./interfaces/iFluidOracle.sol\\\";\\nimport { ErrorTypes } from \\\"./errorTypes.sol\\\";\\nimport { IChainlinkAggregatorV3 } from \\\"./interfaces/external/IChainlinkAggregatorV3.sol\\\";\\nimport { Error as OracleError } from \\\"./error.sol\\\";\\n\\n/// @title FluidOracleL2\\n/// @notice Base contract that any Fluid Oracle L2 must implement\\nabstract contract FluidOracleL2 is IFluidOracle, OracleError {\\n /// @dev Chainlink L2 Sequencer Uptime feed to detect sequencer outages\\n IChainlinkAggregatorV3 internal _SEQUENCER_ORACLE;\\n /// @dev max time period until oracle assumes normal behavior after a sequencer outage.\\n uint256 internal constant _SEQUENCER_MAX_GRACE_PERIOD = 45 minutes;\\n\\n /// @notice sets the L2 sequencer uptime Chainlink feed\\n constructor(address sequencerUptimeFeed_) {\\n _SEQUENCER_ORACLE = IChainlinkAggregatorV3(sequencerUptimeFeed_);\\n }\\n\\n /// @notice returns all sequencer uptime feed related data\\n function sequencerL2Data()\\n public\\n view\\n returns (\\n address sequencerUptimeFeed_,\\n uint256 maxGracePeriod_,\\n bool isSequencerUp_,\\n uint256 lastUptimeStartedAt_,\\n uint256 gracePeriod_,\\n bool gracePeriodPassed_,\\n uint256 lastOutageStartedAt_,\\n bool isSequencerUpAndValid_\\n )\\n {\\n uint80 uptimeStartRoundId_;\\n (isSequencerUp_, uptimeStartRoundId_, lastUptimeStartedAt_) = _sequencerUpStatus();\\n\\n if (isSequencerUp_) {\\n (gracePeriod_, gracePeriodPassed_, lastOutageStartedAt_) = _gracePeriod(\\n uptimeStartRoundId_,\\n lastUptimeStartedAt_\\n );\\n } else {\\n gracePeriod_ = _SEQUENCER_MAX_GRACE_PERIOD;\\n (uint80 roundId_, , , , ) = _SEQUENCER_ORACLE.latestRoundData();\\n lastOutageStartedAt_ = _lastSequencerOutageStart(roundId_ + 1);\\n }\\n\\n return (\\n address(_SEQUENCER_ORACLE),\\n _SEQUENCER_MAX_GRACE_PERIOD,\\n isSequencerUp_,\\n lastUptimeStartedAt_,\\n gracePeriod_,\\n gracePeriodPassed_,\\n lastOutageStartedAt_,\\n isSequencerUp_ && gracePeriodPassed_\\n );\\n }\\n\\n /// @dev ensures that the sequencer is up and grace period has passed\\n function _ensureSequencerUpAndValid() internal view {\\n (bool isSequencerUp_, uint80 uptimeStartRoundId_, uint256 uptimeStartedAt_) = _sequencerUpStatus();\\n\\n if (!isSequencerUp_) {\\n revert FluidOracleError(ErrorTypes.FluidOracleL2__SequencerOutage);\\n }\\n\\n (, bool gracePeriodPassed_, ) = _gracePeriod(uptimeStartRoundId_, uptimeStartedAt_);\\n if (!gracePeriodPassed_) {\\n revert FluidOracleError(ErrorTypes.FluidOracleL2__SequencerOutage);\\n }\\n }\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateOperate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateLiquidate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @dev finds last round before `uptimeStartRoundId_` where sequencer status was down, incl. handling cases of\\n /// consecutive rounds where status was down.\\n function _lastSequencerOutageStart(uint80 uptimeStartRoundId_) private view returns (uint256 outageStartedAt_) {\\n uint80 roundId_ = uptimeStartRoundId_;\\n int256 answer_;\\n uint256 startedAt_;\\n do {\\n (roundId_, answer_, startedAt_, , ) = _SEQUENCER_ORACLE.getRoundData(roundId_ - 1);\\n if (answer_ != 0) {\\n // sequencer was down at this round, update outage started at data\\n outageStartedAt_ = startedAt_;\\n } // else: while loop is going to break\\n } while (answer_ != 0 && startedAt_ > 0);\\n }\\n\\n /// @dev finds last round where sequencer status was up, incl. handling cases of consecutive rounds where status was up.\\n function _sequencerUpStatus()\\n private\\n view\\n returns (bool isSequencerUp_, uint80 uptimeStartRoundId_, uint256 uptimeStartedAt_)\\n {\\n (uint80 roundId_, int256 answer_, uint256 startedAt_, , ) = _SEQUENCER_ORACLE.latestRoundData();\\n if (answer_ != 0) {\\n // sequencer is down currently.\\n return (false, 0, 0);\\n }\\n\\n isSequencerUp_ = true;\\n\\n // cover case where there were other consecutive uptime report rounds in between\\n uptimeStartRoundId_ = roundId_;\\n uptimeStartedAt_ = startedAt_;\\n if (uptimeStartedAt_ > 0) {\\n do {\\n (roundId_, answer_, startedAt_, , ) = _SEQUENCER_ORACLE.getRoundData(roundId_ - 1);\\n if (answer_ == 0) {\\n // sequencer was up at this round, consecutive uptime so update uptime start data\\n uptimeStartRoundId_ = roundId_;\\n uptimeStartedAt_ = startedAt_;\\n } // else: while loop is going to break\\n } while (answer_ == 0 && startedAt_ > 0);\\n } // else if startedAt == 0, then it is the first ever round.\\n }\\n\\n /// @dev returns the `gracePeriod_` duration and if the grace period has `passed_` based on\\n /// current uptime round data vs the last sequencer outage duration.\\n function _gracePeriod(\\n uint80 uptimeStartRoundId_,\\n uint256 uptimeStartedAt_\\n ) private view returns (uint256 gracePeriod_, bool passed_, uint256 outageStartedAt_) {\\n uint256 uptimeDuration_ = block.timestamp - uptimeStartedAt_;\\n if (uptimeStartedAt_ == 0 || uptimeDuration_ > _SEQUENCER_MAX_GRACE_PERIOD) {\\n return (_SEQUENCER_MAX_GRACE_PERIOD, true, 0);\\n }\\n\\n outageStartedAt_ = _lastSequencerOutageStart(uptimeStartRoundId_);\\n\\n // grace period is outage duration, capped at _SEQUENCER_MAX_GRACE_PERIOD\\n gracePeriod_ = uptimeStartedAt_ - outageStartedAt_; // outage duration\\n if (gracePeriod_ > _SEQUENCER_MAX_GRACE_PERIOD) {\\n gracePeriod_ = _SEQUENCER_MAX_GRACE_PERIOD;\\n }\\n\\n return (gracePeriod_, uptimeDuration_ > gracePeriod_, outageStartedAt_);\\n }\\n}\\n\",\"keccak256\":\"0x8e70aa5ab5574d0a32cece6a05fd8296efd527281ebc3c236ecad2fc8e310a6b\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/implementations/chainlinkOracleImpl.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { IChainlinkAggregatorV3 } from \\\"../interfaces/external/IChainlinkAggregatorV3.sol\\\";\\nimport { Error as OracleError } from \\\"../error.sol\\\";\\nimport { OracleUtils } from \\\"../libraries/oracleUtils.sol\\\";\\nimport { ChainlinkStructs } from \\\"./structs.sol\\\";\\n\\n/// @title Chainlink Oracle implementation\\n/// @notice This contract is used to get the exchange rate via up to 3 hops at Chainlink price feeds.\\n/// The rate is multiplied with the previous rate at each hop.\\n/// E.g. to go from wBTC to USDC (assuming rates for example):\\n/// 1. wBTC -> BTC https://data.chain.link/ethereum/mainnet/crypto-other/wbtc-btc, rate: 0.92.\\n/// 2. BTC -> USD https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd rate: 30,000.\\n/// 3. USD -> USDC https://data.chain.link/ethereum/mainnet/stablecoins/usdc-usd rate: 0.98. Must invert feed: 1.02\\n/// finale rate would be: 0.92 * 30,000 * 1.02 = 28,152\\nabstract contract ChainlinkOracleImpl is OracleError, ChainlinkStructs {\\n /// @notice Chainlink price feed 1 to check for the exchange rate\\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED1;\\n /// @notice Chainlink price feed 2 to check for the exchange rate\\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED2;\\n /// @notice Chainlink price feed 3 to check for the exchange rate\\n IChainlinkAggregatorV3 internal immutable _CHAINLINK_FEED3;\\n\\n /// @notice Flag to invert the price or not for feed 1 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\\n bool internal immutable _CHAINLINK_INVERT_RATE1;\\n /// @notice Flag to invert the price or not for feed 2 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\\n bool internal immutable _CHAINLINK_INVERT_RATE2;\\n /// @notice Flag to invert the price or not for feed 3 (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\\n bool internal immutable _CHAINLINK_INVERT_RATE3;\\n\\n /// @notice constant value for price scaling to reduce gas usage for feed 1\\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER1;\\n /// @notice constant value for inverting price to reduce gas usage for feed 1\\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND1;\\n\\n /// @notice constant value for price scaling to reduce gas usage for feed 2\\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER2;\\n /// @notice constant value for inverting price to reduce gas usage for feed 2\\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND2;\\n\\n /// @notice constant value for price scaling to reduce gas usage for feed 3\\n uint256 internal immutable _CHAINLINK_PRICE_SCALER_MULTIPLIER3;\\n /// @notice constant value for inverting price to reduce gas usage for feed 3\\n uint256 internal immutable _CHAINLINK_INVERT_PRICE_DIVIDEND3;\\n\\n /// @notice constructor sets the Chainlink price feed and invertRate flag for each hop.\\n /// E.g. `invertRate_` should be true if for the USDC/ETH pool it's expected that the oracle returns USDC per 1 ETH\\n constructor(ChainlinkConstructorParams memory params_) {\\n if (\\n (params_.hops < 1 || params_.hops > 3) || // hops must be 1, 2 or 3\\n (address(params_.feed1.feed) == address(0) || params_.feed1.token0Decimals == 0) || // first feed must always be defined\\n (params_.hops > 1 && (address(params_.feed2.feed) == address(0) || params_.feed2.token0Decimals == 0)) || // if hops > 1, feed 2 must be defined\\n (params_.hops > 2 && (address(params_.feed3.feed) == address(0) || params_.feed3.token0Decimals == 0)) // if hops > 2, feed 3 must be defined\\n ) {\\n revert FluidOracleError(ErrorTypes.ChainlinkOracle__InvalidParams);\\n }\\n\\n _CHAINLINK_FEED1 = params_.feed1.feed;\\n _CHAINLINK_FEED2 = params_.feed2.feed;\\n _CHAINLINK_FEED3 = params_.feed3.feed;\\n\\n _CHAINLINK_INVERT_RATE1 = params_.feed1.invertRate;\\n _CHAINLINK_INVERT_RATE2 = params_.feed2.invertRate;\\n _CHAINLINK_INVERT_RATE3 = params_.feed3.invertRate;\\n\\n // Actual desired output rate example USDC/ETH (6 decimals / 18 decimals).\\n // Note ETH has 12 decimals more than USDC.\\n // 0.000515525322211842331991619857165357691 // 39 decimals. ETH for 1 USDC\\n // 1954.190000000000433 // 15 decimals. USDC for 1 ETH\\n\\n // to get to PRICE_SCLAER_MULTIPLIER and INVERT_PRICE_DIVIDEND:\\n // fetched Chainlink price is in token1Decimals per 1 token0Decimals.\\n // E.g. for an USDC/ETH price feed it's in ETH 18 decimals.\\n // for an BTC/USD price feed it's in USD 8 decimals.\\n // So to scale to 1e27 we need to multiply by 1e27 - token0Decimals.\\n // E.g. for USDC/ETH it would be: fetchedPrice * 1e21\\n //\\n // or for inverted (x token0 per 1 token1), formula would be:\\n // = 1e27 * 10**token0Decimals / fetchedPrice\\n // E.g. for USDC/ETH it would be: 1e33 / fetchedPrice\\n\\n // no support for token1Decimals with more than OracleUtils.RATE_OUTPUT_DECIMALS decimals for now as extremely unlikely case\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER1 = 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - params_.feed1.token0Decimals);\\n _CHAINLINK_INVERT_PRICE_DIVIDEND1 = 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + params_.feed1.token0Decimals);\\n\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER2 = params_.hops > 1\\n ? 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - params_.feed2.token0Decimals)\\n : 1;\\n _CHAINLINK_INVERT_PRICE_DIVIDEND2 = params_.hops > 1\\n ? 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + params_.feed2.token0Decimals)\\n : 1;\\n\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER3 = params_.hops > 2\\n ? 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - params_.feed3.token0Decimals)\\n : 1;\\n _CHAINLINK_INVERT_PRICE_DIVIDEND3 = params_.hops > 2\\n ? 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + params_.feed3.token0Decimals)\\n : 1;\\n }\\n\\n /// @dev Get the exchange rate from Chainlike oracle price feed(s)\\n /// @return rate_ The exchange rate in `OracleUtils.RATE_OUTPUT_DECIMALS`\\n function _getChainlinkExchangeRate() internal view returns (uint256 rate_) {\\n rate_ = _readFeedRate(\\n _CHAINLINK_FEED1,\\n _CHAINLINK_INVERT_RATE1,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER1,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND1\\n );\\n if (rate_ == 0 || address(_CHAINLINK_FEED2) == address(0)) {\\n // rate 0 or only 1 hop -> return rate of price feed 1\\n return rate_;\\n }\\n rate_ =\\n (rate_ *\\n _readFeedRate(\\n _CHAINLINK_FEED2,\\n _CHAINLINK_INVERT_RATE2,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER2,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND2\\n )) /\\n (10 ** OracleUtils.RATE_OUTPUT_DECIMALS);\\n\\n if (rate_ == 0 || address(_CHAINLINK_FEED3) == address(0)) {\\n // rate 0 or 2 hops -> return rate of feed 1 combined with feed 2\\n return rate_;\\n }\\n\\n // 3 hops -> return rate of feed 1 combined with feed 2 & feed 3\\n rate_ =\\n (rate_ *\\n _readFeedRate(\\n _CHAINLINK_FEED3,\\n _CHAINLINK_INVERT_RATE3,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER3,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND3\\n )) /\\n (10 ** OracleUtils.RATE_OUTPUT_DECIMALS);\\n }\\n\\n /// @dev reads the exchange `rate_` from a Chainlink price `feed_` taking into account scaling and `invertRate_`\\n function _readFeedRate(\\n IChainlinkAggregatorV3 feed_,\\n bool invertRate_,\\n uint256 priceMultiplier_,\\n uint256 invertDividend_\\n ) private view returns (uint256 rate_) {\\n try feed_.latestRoundData() returns (uint80, int256 exchangeRate_, uint256, uint256, uint80) {\\n // Return the price in `OracleUtils.RATE_OUTPUT_DECIMALS`\\n if (invertRate_) {\\n return invertDividend_ / uint256(exchangeRate_);\\n } else {\\n return uint256(exchangeRate_) * priceMultiplier_;\\n }\\n } catch {\\n return 0;\\n }\\n }\\n\\n /// @notice returns all Chainlink oracle related data as utility for easy off-chain use / block explorer in a single view method\\n function chainlinkOracleData()\\n public\\n view\\n returns (\\n uint256 chainlinkExchangeRate_,\\n IChainlinkAggregatorV3 chainlinkFeed1_,\\n bool chainlinkInvertRate1_,\\n uint256 chainlinkExchangeRate1_,\\n IChainlinkAggregatorV3 chainlinkFeed2_,\\n bool chainlinkInvertRate2_,\\n uint256 chainlinkExchangeRate2_,\\n IChainlinkAggregatorV3 chainlinkFeed3_,\\n bool chainlinkInvertRate3_,\\n uint256 chainlinkExchangeRate3_\\n )\\n {\\n return (\\n _getChainlinkExchangeRate(),\\n _CHAINLINK_FEED1,\\n _CHAINLINK_INVERT_RATE1,\\n _readFeedRate(\\n _CHAINLINK_FEED1,\\n _CHAINLINK_INVERT_RATE1,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER1,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND1\\n ),\\n _CHAINLINK_FEED2,\\n _CHAINLINK_INVERT_RATE2,\\n address(_CHAINLINK_FEED2) == address(0)\\n ? 0\\n : _readFeedRate(\\n _CHAINLINK_FEED2,\\n _CHAINLINK_INVERT_RATE2,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER2,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND2\\n ),\\n _CHAINLINK_FEED3,\\n _CHAINLINK_INVERT_RATE3,\\n address(_CHAINLINK_FEED3) == address(0)\\n ? 0\\n : _readFeedRate(\\n _CHAINLINK_FEED3,\\n _CHAINLINK_INVERT_RATE3,\\n _CHAINLINK_PRICE_SCALER_MULTIPLIER3,\\n _CHAINLINK_INVERT_PRICE_DIVIDEND3\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0xe7656c6a48277513acca3c891d53960682f949e1913a6377b2f4a7b1a6132772\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/implementations/fallbackOracleImpl.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { IRedstoneOracle } from \\\"../interfaces/external/IRedstoneOracle.sol\\\";\\nimport { Error as OracleError } from \\\"../error.sol\\\";\\nimport { ChainlinkOracleImpl } from \\\"./chainlinkOracleImpl.sol\\\";\\nimport { RedstoneOracleImpl } from \\\"./redstoneOracleImpl.sol\\\";\\n\\n/// @title Fallback Oracle implementation\\n/// @notice This contract is used to get the exchange rate from a main oracle feed and a fallback oracle feed.\\n//\\n// @dev inheriting contracts should implement a view method to expose `_FALLBACK_ORACLE_MAIN_SOURCE`\\nabstract contract FallbackOracleImpl is OracleError, RedstoneOracleImpl, ChainlinkOracleImpl {\\n /// @dev which oracle to use as main source:\\n /// - 1 = Chainlink ONLY (no fallback)\\n /// - 2 = Chainlink with Redstone Fallback\\n /// - 3 = Redstone with Chainlink Fallback\\n uint8 internal immutable _FALLBACK_ORACLE_MAIN_SOURCE;\\n\\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\\n /// @param mainSource_ which oracle to use as main source:\\n /// - 1 = Chainlink ONLY (no fallback)\\n /// - 2 = Chainlink with Redstone Fallback\\n /// - 3 = Redstone with Chainlink Fallback\\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\\n constructor(\\n uint8 mainSource_,\\n ChainlinkConstructorParams memory chainlinkParams_,\\n RedstoneOracleData memory redstoneOracle_\\n )\\n ChainlinkOracleImpl(chainlinkParams_)\\n RedstoneOracleImpl(\\n address(redstoneOracle_.oracle) == address(0)\\n ? RedstoneOracleData(IRedstoneOracle(_REDSTONE_ORACLE_NOT_SET_ADDRESS), false, 1)\\n : redstoneOracle_\\n )\\n {\\n if (mainSource_ < 1 || mainSource_ > 3) {\\n revert FluidOracleError(ErrorTypes.FallbackOracle__InvalidParams);\\n }\\n _FALLBACK_ORACLE_MAIN_SOURCE = mainSource_;\\n }\\n\\n /// @dev returns the exchange rate for the main oracle source, or the fallback source (if configured) if the main exchange rate\\n /// fails to be fetched. If returned rate is 0, fetching rate failed or something went wrong.\\n /// @return exchangeRate_ exchange rate\\n /// @return fallback_ whether fallback was necessary or not\\n function _getRateWithFallback() internal view returns (uint256 exchangeRate_, bool fallback_) {\\n if (_FALLBACK_ORACLE_MAIN_SOURCE == 1) {\\n // 1 = Chainlink ONLY (no fallback)\\n exchangeRate_ = _getChainlinkExchangeRate();\\n } else if (_FALLBACK_ORACLE_MAIN_SOURCE == 2) {\\n // 2 = Chainlink with Redstone Fallback\\n exchangeRate_ = _getChainlinkExchangeRate();\\n if (exchangeRate_ == 0) {\\n fallback_ = true;\\n exchangeRate_ = _getRedstoneExchangeRate();\\n }\\n } else {\\n // 3 = Redstone with Chainlink Fallback\\n exchangeRate_ = _getRedstoneExchangeRate();\\n if (exchangeRate_ == 0) {\\n fallback_ = true;\\n exchangeRate_ = _getChainlinkExchangeRate();\\n }\\n }\\n }\\n\\n /// @dev returns the exchange rate for Chainlink, or Redstone if configured & Chainlink fails.\\n function _getChainlinkOrRedstoneAsFallback() internal view returns (uint256 exchangeRate_) {\\n exchangeRate_ = _getChainlinkExchangeRate();\\n\\n if (exchangeRate_ == 0 && _FALLBACK_ORACLE_MAIN_SOURCE != 1) {\\n // Chainlink failed but Redstone is configured too -> try Redstone\\n exchangeRate_ = _getRedstoneExchangeRate();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xff1e1ab767ff250777dcb7fb70dc5a0392bb666bf4f65d27d338aaceb76554bc\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/implementations/redstoneOracleImpl.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { IRedstoneOracle } from \\\"../interfaces/external/IRedstoneOracle.sol\\\";\\nimport { Error as OracleError } from \\\"../error.sol\\\";\\nimport { OracleUtils } from \\\"../libraries/oracleUtils.sol\\\";\\nimport { RedstoneStructs } from \\\"./structs.sol\\\";\\n\\n/// @title Redstone Oracle implementation\\n/// @notice This contract is used to get the exchange rate from a Redstone Oracle\\nabstract contract RedstoneOracleImpl is OracleError, RedstoneStructs {\\n /// @notice Redstone price oracle to check for the exchange rate\\n IRedstoneOracle internal immutable _REDSTONE_ORACLE;\\n /// @notice Flag to invert the price or not (to e.g. for WETH/USDC pool return prive of USDC per 1 WETH)\\n bool internal immutable _REDSTONE_INVERT_RATE;\\n\\n /// @notice constant value for price scaling to reduce gas usage\\n uint256 internal immutable _REDSTONE_PRICE_SCALER_MULTIPLIER;\\n /// @notice constant value for inverting price to reduce gas usage\\n uint256 internal immutable _REDSTONE_INVERT_PRICE_DIVIDEND;\\n\\n address internal immutable _REDSTONE_ORACLE_NOT_SET_ADDRESS = 0x000000000000000000000000000000000000dEaD;\\n\\n /// @notice constructor sets the Redstone oracle data\\n constructor(RedstoneOracleData memory oracleData_) {\\n if (address(oracleData_.oracle) == address(0) || oracleData_.token0Decimals == 0) {\\n revert FluidOracleError(ErrorTypes.RedstoneOracle__InvalidParams);\\n }\\n\\n _REDSTONE_ORACLE = oracleData_.oracle;\\n _REDSTONE_INVERT_RATE = oracleData_.invertRate;\\n\\n // for explanation on how to get to scaler multiplier and dividend see `chainlinkOracleImpl.sol`.\\n // no support for token1Decimals with more than OracleUtils.RATE_OUTPUT_DECIMALS decimals for now as extremely unlikely case\\n _REDSTONE_PRICE_SCALER_MULTIPLIER = address(oracleData_.oracle) == _REDSTONE_ORACLE_NOT_SET_ADDRESS\\n ? 1\\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - oracleData_.token0Decimals);\\n _REDSTONE_INVERT_PRICE_DIVIDEND = address(oracleData_.oracle) == _REDSTONE_ORACLE_NOT_SET_ADDRESS\\n ? 1\\n : 10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + oracleData_.token0Decimals);\\n }\\n\\n /// @dev Get the exchange rate from Redstone oracle\\n /// @param rate_ The exchange rate in `OracleUtils.RATE_OUTPUT_DECIMALS`\\n function _getRedstoneExchangeRate() internal view returns (uint256 rate_) {\\n try _REDSTONE_ORACLE.getExchangeRate() returns (uint256 exchangeRate_) {\\n if (_REDSTONE_INVERT_RATE) {\\n // invert the price\\n return _REDSTONE_INVERT_PRICE_DIVIDEND / exchangeRate_;\\n } else {\\n return exchangeRate_ * _REDSTONE_PRICE_SCALER_MULTIPLIER;\\n }\\n } catch {\\n return 0;\\n }\\n }\\n\\n /// @notice returns all Redstone oracle related data as utility for easy off-chain use / block explorer in a single view method\\n function redstoneOracleData()\\n public\\n view\\n returns (uint256 redstoneExchangeRate_, IRedstoneOracle redstoneOracle_, bool redstoneInvertRate_)\\n {\\n return (\\n address(_REDSTONE_ORACLE) == _REDSTONE_ORACLE_NOT_SET_ADDRESS ? 0 : _getRedstoneExchangeRate(),\\n _REDSTONE_ORACLE,\\n _REDSTONE_INVERT_RATE\\n );\\n }\\n}\\n\",\"keccak256\":\"0x49082d966015853f5fa8074a5ab209df61e8ec8353f3f08ced5dc77f8b578b4b\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/implementations/structs.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IChainlinkAggregatorV3 } from \\\"../interfaces/external/IChainlinkAggregatorV3.sol\\\";\\nimport { IRedstoneOracle } from \\\"../interfaces/external/IRedstoneOracle.sol\\\";\\n\\nabstract contract ChainlinkStructs {\\n struct ChainlinkFeedData {\\n /// @param feed address of Chainlink feed.\\n IChainlinkAggregatorV3 feed;\\n /// @param invertRate true if rate read from price feed must be inverted.\\n bool invertRate;\\n /// @param token0Decimals decimals of asset 0. E.g. for a USDC/ETH feed, USDC is token0 and has 6 decimals.\\n /// (token1Decimals are available directly via Chainlink `FEED.decimals()`)\\n uint256 token0Decimals;\\n }\\n\\n struct ChainlinkConstructorParams {\\n /// @param param hops count of hops, used for sanity checks. Must be 1, 2 or 3.\\n uint8 hops;\\n /// @param feed1 Chainlink feed 1 data. Required.\\n ChainlinkFeedData feed1;\\n /// @param feed2 Chainlink feed 2 data. Required if hops > 1.\\n ChainlinkFeedData feed2;\\n /// @param feed3 Chainlink feed 3 data. Required if hops > 2.\\n ChainlinkFeedData feed3;\\n }\\n}\\n\\nabstract contract RedstoneStructs {\\n struct RedstoneOracleData {\\n /// @param oracle address of Redstone oracle.\\n IRedstoneOracle oracle;\\n /// @param invertRate true if rate read from price feed must be inverted.\\n bool invertRate;\\n /// @param token0Decimals decimals of asset 0. E.g. for a USDC/ETH feed, USDC is token0 and has 6 decimals.\\n /// (token1Decimals are available directly via Redstone `Oracle.decimals()`)\\n uint256 token0Decimals;\\n }\\n}\\n\",\"keccak256\":\"0x90d026dc5f1762c704f30eaaf485c0e8eb6314832a311db3ec73759e81dbde33\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/interfaces/external/IChainlinkAggregatorV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\n/// from https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\\n/// Copyright (c) 2018 SmartContract ChainLink, Ltd.\\n\\ninterface IChainlinkAggregatorV3 {\\n /// @notice represents the number of decimals the aggregator responses represent.\\n function decimals() external view returns (uint8);\\n\\n function description() external view returns (string memory);\\n\\n function version() external view returns (uint256);\\n\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n}\\n\",\"keccak256\":\"0xaeea1f12d1c381bde8418eab05206d6472b246158584190fce0d09913912a7ef\",\"license\":\"MIT\"},\"contracts/oracle/interfaces/external/IRedstoneOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IRedstoneOracle {\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset\\n // @dev custom Redstone adapter for Instadapp implementation\\n function getExchangeRate() external view returns (uint256 exchangeRate_);\\n\\n /**\\n * @notice Returns the number of decimals for the price feed\\n * @dev By default, RedStone uses 8 decimals for data feeds\\n * @return decimals The number of decimals in the price feed values\\n */\\n // see https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/on-chain-relayer/contracts/price-feeds/PriceFeedBase.sol#L51C12-L51C20\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0xd9a844e86035a935fe06c5937d2fb8796fd150771716246b77c6226e32c9d129\",\"license\":\"MIT\"},\"contracts/oracle/interfaces/iFluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IFluidOracle {\\n /// @dev Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for\\n /// backwards compatibility.\\n function getExchangeRate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates\\n function getExchangeRateOperate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations\\n function getExchangeRateLiquidate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice helper string to easily identify the oracle. E.g. token symbols\\n function infoName() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xeba2e991e41f8b68e2d639935931aadf39e15ea94ea7aa65b2fb3039d27dca63\",\"license\":\"MIT\"},\"contracts/oracle/libraries/oracleUtils.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @title Oracle utils library\\n/// @notice implements common utility methods for Fluid Oracles\\nlibrary OracleUtils {\\n /// @dev The scaler for max delta point math (100%)\\n uint256 internal constant HUNDRED_PERCENT_DELTA_SCALER = 10_000;\\n /// @dev output precision of rates\\n uint256 internal constant RATE_OUTPUT_DECIMALS = 27;\\n\\n /// @dev checks if `mainSourceRate_` is within a `maxDeltaPercent_` of `checkSourceRate_`. Returns true if so.\\n function isRateOutsideDelta(\\n uint256 mainSourceRate_,\\n uint256 checkSourceRate_,\\n uint256 maxDeltaPercent_\\n ) internal pure returns (bool) {\\n uint256 offset_ = (checkSourceRate_ * maxDeltaPercent_) / HUNDRED_PERCENT_DELTA_SCALER;\\n return (mainSourceRate_ > (checkSourceRate_ + offset_) || mainSourceRate_ < (checkSourceRate_ - offset_));\\n }\\n}\\n\",\"keccak256\":\"0x968b1a0606875abd523895c5075cf6c34c296919e77b0da7dd952374398e2a4c\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/oracles/fallbackCLRSOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { FluidOracle } from \\\"../fluidOracle.sol\\\";\\nimport { FallbackOracleImpl } from \\\"../implementations/fallbackOracleImpl.sol\\\";\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\n\\n/// @title Chainlink / Redstone Oracle (with fallback)\\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\\n/// the price from a Chainlink price feed or a Redstone Oracle with one of them being used as main source and\\n/// the other one acting as a fallback if the main source fails for any reason. Reverts if fetched rate is 0.\\ncontract FallbackCLRSOracle is FluidOracle, FallbackOracleImpl {\\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\\n /// @param infoName_ Oracle identify helper name.\\n /// @param mainSource_ which oracle to use as main source: 1 = Chainlink, 2 = Redstone (other one is fallback).\\n /// @param chainlinkParams_ chainlink Oracle constructor params struct.\\n /// @param redstoneOracle_ Redstone Oracle data. (address can be set to zero address if using Chainlink only)\\n constructor(\\n string memory infoName_,\\n uint8 mainSource_,\\n ChainlinkConstructorParams memory chainlinkParams_,\\n RedstoneOracleData memory redstoneOracle_\\n ) FallbackOracleImpl(mainSource_, chainlinkParams_, redstoneOracle_) FluidOracle(infoName_) {}\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRateOperate() public view virtual override returns (uint256 exchangeRate_) {\\n (exchangeRate_, ) = _getRateWithFallback();\\n\\n if (exchangeRate_ == 0) {\\n revert FluidOracleError(ErrorTypes.FallbackCLRSOracle__ExchangeRateZero);\\n }\\n }\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRateLiquidate() public view virtual override returns (uint256 exchangeRate_) {\\n (exchangeRate_, ) = _getRateWithFallback();\\n\\n if (exchangeRate_ == 0) {\\n revert FluidOracleError(ErrorTypes.FallbackCLRSOracle__ExchangeRateZero);\\n }\\n }\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRate() public view virtual override returns (uint256 exchangeRate_) {\\n return getExchangeRateOperate();\\n }\\n\\n /// @notice which oracle to use as main source:\\n /// - 1 = Chainlink ONLY (no fallback)\\n /// - 2 = Chainlink with Redstone Fallback\\n /// - 3 = Redstone with Chainlink Fallback\\n function FALLBACK_ORACLE_MAIN_SOURCE() public view returns (uint8) {\\n return _FALLBACK_ORACLE_MAIN_SOURCE;\\n }\\n}\\n\",\"keccak256\":\"0x2387ea4548e05dd50d632597cadf041629465cba8816870ac90322d492574506\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/oraclesL2/fallbackCLRSOracleL2.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { FluidOracleL2 } from \\\"../fluidOracleL2.sol\\\";\\nimport { FallbackCLRSOracle } from \\\"../oracles/fallbackCLRSOracle.sol\\\";\\n\\n/// @title Chainlink / Redstone Oracle (with fallback) for Layer 2 (with sequencer outage detection)\\n/// @notice Gets the exchange rate between the underlying asset and the peg asset by using:\\n/// the price from a Chainlink price feed or a Redstone Oracle with one of them being used as main source and\\n/// the other one acting as a fallback if the main source fails for any reason. Reverts if fetched rate is 0.\\ncontract FallbackCLRSOracleL2 is FluidOracleL2, FallbackCLRSOracle {\\n struct CLRSConstructorParams {\\n /// @param mainSource which oracle to use as main source for wstETH <> CLRS: 1 = Chainlink, 2 = Redstone (other one is fallback).\\n uint8 mainSource;\\n /// @param chainlinkParams chainlink Oracle constructor params struct for wstETH <> CLRS.\\n ChainlinkConstructorParams chainlinkParams;\\n /// @param redstoneOracle Redstone Oracle data for wstETH <> CLRS. (address can be set to zero address if using Chainlink only)\\n RedstoneOracleData redstoneOracle;\\n }\\n\\n /// @notice sets the main source, Chainlink Oracle and Redstone Oracle data.\\n /// @param infoName_ Oracle identify helper name.\\n /// @param cLRSParams_ CLRS Fallback Oracle data\\n /// @param sequencerUptimeFeed_ L2 sequencer uptime Chainlink feed\\n constructor(\\n string memory infoName_,\\n CLRSConstructorParams memory cLRSParams_,\\n address sequencerUptimeFeed_\\n )\\n FallbackCLRSOracle(infoName_, cLRSParams_.mainSource, cLRSParams_.chainlinkParams, cLRSParams_.redstoneOracle)\\n FluidOracleL2(sequencerUptimeFeed_)\\n {}\\n\\n /// @inheritdoc FluidOracleL2\\n function getExchangeRateOperate()\\n public\\n view\\n virtual\\n override(FallbackCLRSOracle, FluidOracleL2)\\n returns (uint256 exchangeRate_)\\n {\\n _ensureSequencerUpAndValid();\\n return super.getExchangeRateOperate();\\n }\\n\\n /// @inheritdoc FluidOracleL2\\n function getExchangeRateLiquidate()\\n public\\n view\\n virtual\\n override(FallbackCLRSOracle, FluidOracleL2)\\n returns (uint256 exchangeRate_)\\n {\\n _ensureSequencerUpAndValid();\\n return super.getExchangeRateLiquidate();\\n }\\n\\n /// @inheritdoc FluidOracleL2\\n function getExchangeRate()\\n public\\n view\\n virtual\\n override(FallbackCLRSOracle, FluidOracleL2)\\n returns (uint256 exchangeRate_)\\n {\\n return getExchangeRateOperate();\\n }\\n}\\n\",\"keccak256\":\"0x68afc66ee3eb7dc3c93304c6a55d5eab7fe65e8f8a81fb39caed06b8d5665559\",\"license\":\"BUSL-1.1\"}},\"version\":1}", "bytecode": "0x6102e060405261dead610120523480156200001957600080fd5b5060405162001f9738038062001f978339810160408190526200003c916200067e565b828260000151836020015184604001518282828160006001600160a01b031682600001516001600160a01b031614620000765781620000a2565b6040518060600160405280610120516001600160a01b0316815260200160001515815260200160018152505b600080546001600160a01b0319166001600160a01b038c161790558851899060201080620000cf57508051155b15620000f75760405163c82fc46560e01b815261ea6a60048201526024015b60405180910390fd5b6020015160805280516001600160a01b031615806200011857506040810151155b156200013c5760405163c82fc46560e01b815261fa016004820152602401620000ee565b80516001600160a01b0390811660a0526020820151151560c05261012051825182169116146200018b5760408101516200017890601b62000772565b6200018590600a6200088b565b6200018e565b60015b60e0526101205181516001600160a01b03908116911614620001cf576040810151620001bc90601b620008a0565b620001c990600a6200088b565b620001d2565b60015b61010052508051600160ff9091161080620001f457506003816000015160ff16115b806200021d57506020810151516001600160a01b031615806200021d5750602081015160400151155b806200025857506001816000015160ff161180156200025857506040810151516001600160a01b031615806200025857506040808201510151155b806200029457506002816000015160ff161180156200029457506060810151516001600160a01b03161580620002945750606081015160400151155b15620002b85760405163c82fc46560e01b815261ee496004820152602401620000ee565b60208082018051516001600160a01b039081166101405260408085018051518316610160526060860180515190931661018052835185015115156101a0525184015115156101c05290519092015115156101e0525101516200031c90601b62000772565b6200032990600a6200088b565b610200526020810151604001516200034390601b620008a0565b6200035090600a6200088b565b610220528051600160ff909116116200036b5760016200038d565b60408082015101516200038090601b62000772565b6200038d90600a6200088b565b610240528051600160ff90911611620003a8576001620003ca565b6040808201510151620003bd90601b620008a0565b620003ca90600a6200088b565b610260528051600260ff90911611620003e557600162000408565b606081015160400151620003fb90601b62000772565b6200040890600a6200088b565b610280528051600260ff909116116200042357600162000446565b6060810151604001516200043990601b620008a0565b6200044690600a6200088b565b6102a05250600160ff8416108062000461575060038360ff16115b15620004855760405163c82fc46560e01b815261fde96004820152602401620000ee565b505060ff166102c05250620008b695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715620004d757620004d76200049c565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200050857620005086200049c565b604052919050565b805160ff811681146200052257600080fd5b919050565b6001600160a01b03811681146200053d57600080fd5b50565b6000606082840312156200055357600080fd5b6200055d620004b2565b905081516200056c8162000527565b8152602082015180151581146200058257600080fd5b806020830152506040820151604082015292915050565b60008183036101c0811215620005ae57600080fd5b620005b8620004b2565b9150620005c58362000510565b8252610140601f1982011215620005db57600080fd5b50604051608081016001600160401b03811182821017156200060157620006016200049c565b604052620006126020840162000510565b815262000623846040850162000540565b6020820152620006378460a0850162000540565b60408201526200064c84610100850162000540565b606082015260208201526200066683610160840162000540565b604082015292915050565b8051620005228162000527565b600080600061020084860312156200069557600080fd5b83516001600160401b0380821115620006ad57600080fd5b818601915086601f830112620006c257600080fd5b815181811115620006d757620006d76200049c565b60209150620006ef601f8201601f19168301620004dd565b81815288838386010111156200070457600080fd5b60005b828110156200072457848101840151828201850152830162000707565b5060008383830101528096505050620007408782880162000599565b93505050620007536101e0850162000671565b90509250925092565b634e487b7160e01b600052601160045260246000fd5b818103818111156200078857620007886200075c565b92915050565b600181815b80851115620007cf578160001904821115620007b357620007b36200075c565b80851615620007c157918102915b93841c939080029062000793565b509250929050565b600082620007e85750600162000788565b81620007f75750600062000788565b81600181146200081057600281146200081b576200083b565b600191505062000788565b60ff8411156200082f576200082f6200075c565b50506001821b62000788565b5060208310610133831016604e8410600b841016171562000860575081810a62000788565b6200086c83836200078e565b80600019048211156200088357620008836200075c565b029392505050565b6000620008998383620007d7565b9392505050565b808201808211156200078857620007886200075c565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c05161154d62000a4a600039600081816094015281816110de01526111170152600081816104a40152610ac30152600081816104830152610aa20152600081816103b201526109cc01526000818161039101526109ab0152600081816102c801526108e90152600081816102a701526108c8015260008181610401015281816104620152610a8101526000818161030f01528181610370015261098a0152600081816102410152818161028601526108a70152600081816103e00152818161044101528181610a100152610a600152600081816102ee0152818161034f015281816109190152610969015260008181610220015281816102650152610886015260006104f701526000610c9901526000610cc801526000818161059e0152610c6f01526000818161052e0152818161057b0152610bc00152600081816105ec01526106b1015261154d6000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063abd5f95d1161005b578063abd5f95d14610186578063dc4595121461019b578063e6aa216c146101ff578063f3190c891461017057600080fd5b80633437eac41461008d5780637557ca41146100c357806388c35209146101365780638e7bfbc014610170575b600080fd5b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b6100cb610207565b604080519a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c0152971515978a01979097526060890195909552928616608088015290151560a087015260c086015290921660e0840152901515610100830152610120820152610140016100ba565b61013e6104f0565b6040805193845273ffffffffffffffffffffffffffffffffffffffff90921660208401521515908201526060016100ba565b6101786105c3565b6040519081526020016100ba565b61018e6105da565b6040516100ba919061117e565b6101a361073f565b6040805173ffffffffffffffffffffffffffffffffffffffff909916895260208901979097529415159587019590955260608601929092526080850152151560a084015260c0830191909152151560e0820152610100016100ba565b610178610875565b60008060008060008060008060008061021e61087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006102ec7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8216156103db576103d67f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6103de565b60005b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8216156104cd576104c87f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6104d0565b60005b995099509950995099509950995099509950995090919293949596979899565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161461057557610570610bbc565b610578565b60005b937f000000000000000000000000000000000000000000000000000000000000000093507f000000000000000000000000000000000000000000000000000000000000000092509050565b60006105cd610cf0565b6105d5610d94565b905090565b606060005b60208110801561064557507f0000000000000000000000000000000000000000000000000000000000000000816020811061061c5761061c6111ea565b1a60f81b7fff000000000000000000000000000000000000000000000000000000000000001615155b1561065c578061065481611248565b9150506105df565b60008167ffffffffffffffff81111561067757610677611280565b6040519080825280601f01601f1916602001820160405280156106a1576020820181803683370190505b50905060005b82811015610738577f000000000000000000000000000000000000000000000000000000000000000081602081106106e1576106e16111ea565b1a60f81b8282815181106106f7576106f76111ea565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061073081611248565b9150506106a7565b5092915050565b6000806000806000806000806000610755610de1565b919850909650905086156107795761076d8187610f8e565b9196509450925061082f565b610a8c945060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081091906112ce565b50505050905061082b816001610826919061131e565b610ff8565b9350505b60005473ffffffffffffffffffffffffffffffffffffffff16610a8c888888888884801561085a57508a5b98509850985098509850985098509850509091929394959697565b60006105d56105c3565b600061090d7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b905080158061095057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16155b156109585790565b610964601b600a611463565b6109f07f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6109fa9083611476565b610a04919061148d565b9050801580610a4757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16155b15610a4f5790565b610a5b601b600a611463565b610ae77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b610af19083611476565b6105d5919061148d565b60008473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015610b82575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610b7f918101906112ce565b60015b610b8e57506000610bb4565b8815610baa57610b9e848861148d565b95505050505050610bb4565b610b9e8885611476565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6aa216c6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c63575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c60918101906114c8565b60015b610c6d5750600090565b7f000000000000000000000000000000000000000000000000000000000000000015610cc357610cbd817f000000000000000000000000000000000000000000000000000000000000000061148d565b91505090565b610cbd7f000000000000000000000000000000000000000000000000000000000000000082611476565b90565b6000806000610cfd610de1565b92509250925082610d43576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261ea6060048201526024015b60405180910390fd5b6000610d4f8383610f8e565b5091505080610d8e576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261ea606004820152602401610d3a565b50505050565b6000610d9e6110d9565b5090506000819003610ced576040517fc82fc465000000000000000000000000000000000000000000000000000000008152620101d16004820152602401610d3a565b60008060008060008060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610e55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7991906112ce565b505092509250925081600014610e99575060009586955085945092505050565b600195508294508093506000841115610f86575b60005473ffffffffffffffffffffffffffffffffffffffff16639a6fc8f5610ed66001866114e1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815269ffffffffffffffffffff909116600482015260240160a060405180830381865afa158015610f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5991906112ce565b509295509093509150506000829003610f73578294508093505b81158015610f815750600081115b610ead575b505050909192565b6000808080610f9d8542611504565b9050841580610fad5750610a8c81115b15610fc557610a8c6001600093509350935050610ff1565b610fce86610ff8565b9150610fda8286611504565b9350610a8c841115610fec57610a8c93505b831091505b9250925092565b60008181805b60005473ffffffffffffffffffffffffffffffffffffffff16639a6fc8f56110276001866114e1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815269ffffffffffffffffffff909116600482015260240160a060405180830381865afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110aa91906112ce565b5092955090935091505081156110be578093505b81158015906110cd5750600081115b610ffe57505050919050565b6000807f000000000000000000000000000000000000000000000000000000000000000060ff166001036111155761110f61087f565b91509091565b7f000000000000000000000000000000000000000000000000000000000000000060ff166002036111615761114861087f565b91508160000361115d5750600161110f610bbc565b9091565b611169610bbc565b91508160000361115d5750600161110f61087f565b600060208083528351808285015260005b818110156111ab5785810183015185820160400152820161118f565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361127957611279611219565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b805169ffffffffffffffffffff811681146112c957600080fd5b919050565b600080600080600060a086880312156112e657600080fd5b6112ef866112af565b9450602086015193506040860151925060608601519150611312608087016112af565b90509295509295909350565b69ffffffffffffffffffff81811683821601908082111561073857610738611219565b600181815b8085111561139a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561138057611380611219565b8085161561138d57918102915b93841c9390800290611346565b509250929050565b6000826113b15750600161145d565b816113be5750600061145d565b81600181146113d457600281146113de576113fa565b600191505061145d565b60ff8411156113ef576113ef611219565b50506001821b61145d565b5060208310610133831016604e8410600b841016171561141d575081810a61145d565b6114278383611341565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561145957611459611219565b0290505b92915050565b600061146f83836113a2565b9392505050565b808202811582820484141761145d5761145d611219565b6000826114c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156114da57600080fd5b5051919050565b69ffffffffffffffffffff82811682821603908082111561073857610738611219565b8181038181111561145d5761145d61121956fea2646970667358221220b55d32518abbf89bf508efb1fbfb12e3822c8d7ae8b114a6b55258e79c2e53a964736f6c63430008150033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063abd5f95d1161005b578063abd5f95d14610186578063dc4595121461019b578063e6aa216c146101ff578063f3190c891461017057600080fd5b80633437eac41461008d5780637557ca41146100c357806388c35209146101365780638e7bfbc014610170575b600080fd5b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b6100cb610207565b604080519a8b5273ffffffffffffffffffffffffffffffffffffffff998a1660208c0152971515978a01979097526060890195909552928616608088015290151560a087015260c086015290921660e0840152901515610100830152610120820152610140016100ba565b61013e6104f0565b6040805193845273ffffffffffffffffffffffffffffffffffffffff90921660208401521515908201526060016100ba565b6101786105c3565b6040519081526020016100ba565b61018e6105da565b6040516100ba919061117e565b6101a361073f565b6040805173ffffffffffffffffffffffffffffffffffffffff909916895260208901979097529415159587019590955260608601929092526080850152151560a084015260c0830191909152151560e0820152610100016100ba565b610178610875565b60008060008060008060008060008061021e61087f565b7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006102ec7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8216156103db576103d67f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6103de565b60005b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8216156104cd576104c87f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6104d0565b60005b995099509950995099509950995099509950995090919293949596979899565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161461057557610570610bbc565b610578565b60005b937f000000000000000000000000000000000000000000000000000000000000000093507f000000000000000000000000000000000000000000000000000000000000000092509050565b60006105cd610cf0565b6105d5610d94565b905090565b606060005b60208110801561064557507f0000000000000000000000000000000000000000000000000000000000000000816020811061061c5761061c6111ea565b1a60f81b7fff000000000000000000000000000000000000000000000000000000000000001615155b1561065c578061065481611248565b9150506105df565b60008167ffffffffffffffff81111561067757610677611280565b6040519080825280601f01601f1916602001820160405280156106a1576020820181803683370190505b50905060005b82811015610738577f000000000000000000000000000000000000000000000000000000000000000081602081106106e1576106e16111ea565b1a60f81b8282815181106106f7576106f76111ea565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508061073081611248565b9150506106a7565b5092915050565b6000806000806000806000806000610755610de1565b919850909650905086156107795761076d8187610f8e565b9196509450925061082f565b610a8c945060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156107ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081091906112ce565b50505050905061082b816001610826919061131e565b610ff8565b9350505b60005473ffffffffffffffffffffffffffffffffffffffff16610a8c888888888884801561085a57508a5b98509850985098509850985098509850509091929394959697565b60006105d56105c3565b600061090d7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b905080158061095057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16155b156109585790565b610964601b600a611463565b6109f07f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b6109fa9083611476565b610a04919061148d565b9050801580610a4757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16155b15610a4f5790565b610a5b601b600a611463565b610ae77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000610afb565b610af19083611476565b6105d5919061148d565b60008473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa925050508015610b82575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610b7f918101906112ce565b60015b610b8e57506000610bb4565b8815610baa57610b9e848861148d565b95505050505050610bb4565b610b9e8885611476565b949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6aa216c6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c63575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c60918101906114c8565b60015b610c6d5750600090565b7f000000000000000000000000000000000000000000000000000000000000000015610cc357610cbd817f000000000000000000000000000000000000000000000000000000000000000061148d565b91505090565b610cbd7f000000000000000000000000000000000000000000000000000000000000000082611476565b90565b6000806000610cfd610de1565b92509250925082610d43576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261ea6060048201526024015b60405180910390fd5b6000610d4f8383610f8e565b5091505080610d8e576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261ea606004820152602401610d3a565b50505050565b6000610d9e6110d9565b5090506000819003610ced576040517fc82fc465000000000000000000000000000000000000000000000000000000008152620101d16004820152602401610d3a565b60008060008060008060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610e55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7991906112ce565b505092509250925081600014610e99575060009586955085945092505050565b600195508294508093506000841115610f86575b60005473ffffffffffffffffffffffffffffffffffffffff16639a6fc8f5610ed66001866114e1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815269ffffffffffffffffffff909116600482015260240160a060405180830381865afa158015610f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5991906112ce565b509295509093509150506000829003610f73578294508093505b81158015610f815750600081115b610ead575b505050909192565b6000808080610f9d8542611504565b9050841580610fad5750610a8c81115b15610fc557610a8c6001600093509350935050610ff1565b610fce86610ff8565b9150610fda8286611504565b9350610a8c841115610fec57610a8c93505b831091505b9250925092565b60008181805b60005473ffffffffffffffffffffffffffffffffffffffff16639a6fc8f56110276001866114e1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815269ffffffffffffffffffff909116600482015260240160a060405180830381865afa158015611086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110aa91906112ce565b5092955090935091505081156110be578093505b81158015906110cd5750600081115b610ffe57505050919050565b6000807f000000000000000000000000000000000000000000000000000000000000000060ff166001036111155761110f61087f565b91509091565b7f000000000000000000000000000000000000000000000000000000000000000060ff166002036111615761114861087f565b91508160000361115d5750600161110f610bbc565b9091565b611169610bbc565b91508160000361115d5750600161110f61087f565b600060208083528351808285015260005b818110156111ab5785810183015185820160400152820161118f565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361127957611279611219565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b805169ffffffffffffffffffff811681146112c957600080fd5b919050565b600080600080600060a086880312156112e657600080fd5b6112ef866112af565b9450602086015193506040860151925060608601519150611312608087016112af565b90509295509295909350565b69ffffffffffffffffffff81811683821601908082111561073857610738611219565b600181815b8085111561139a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561138057611380611219565b8085161561138d57918102915b93841c9390800290611346565b509250929050565b6000826113b15750600161145d565b816113be5750600061145d565b81600181146113d457600281146113de576113fa565b600191505061145d565b60ff8411156113ef576113ef611219565b50506001821b61145d565b5060208310610133831016604e8410600b841016171561141d575081810a61145d565b6114278383611341565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561145957611459611219565b0290505b92915050565b600061146f83836113a2565b9392505050565b808202811582820484141761145d5761145d611219565b6000826114c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000602082840312156114da57600080fd5b5051919050565b69ffffffffffffffffffff82811682821603908082111561073857610738611219565b8181038181111561145d5761145d61121956fea2646970667358221220b55d32518abbf89bf508efb1fbfb12e3822c8d7ae8b114a6b55258e79c2e53a964736f6c63430008150033", "devdoc": { "kind": "dev", "methods": { "constructor": { "params": { "cLRSParams_": "CLRS Fallback Oracle data", "infoName_": "Oracle identify helper name.", "sequencerUptimeFeed_": "L2 sequencer uptime Chainlink feed" } }, "getExchangeRate()": { "details": "Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for backwards compatibility." } }, "title": "Chainlink / Redstone Oracle (with fallback) for Layer 2 (with sequencer outage detection)", "version": 1 }, "userdoc": { "kind": "user", "methods": { "FALLBACK_ORACLE_MAIN_SOURCE()": { "notice": "which oracle to use as main source: - 1 = Chainlink ONLY (no fallback) - 2 = Chainlink with Redstone Fallback - 3 = Redstone with Chainlink Fallback" }, "chainlinkOracleData()": { "notice": "returns all Chainlink oracle related data as utility for easy off-chain use / block explorer in a single view method" }, "constructor": { "notice": "sets the main source, Chainlink Oracle and Redstone Oracle data." }, "getExchangeRateLiquidate()": { "notice": "Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations" }, "getExchangeRateOperate()": { "notice": "Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates" }, "infoName()": { "notice": "helper string to easily identify the oracle. E.g. token symbols" }, "redstoneOracleData()": { "notice": "returns all Redstone oracle related data as utility for easy off-chain use / block explorer in a single view method" }, "sequencerL2Data()": { "notice": "returns all sequencer uptime feed related data" } }, "notice": "Gets the exchange rate between the underlying asset and the peg asset by using: the price from a Chainlink price feed or a Redstone Oracle with one of them being used as main source and the other one acting as a fallback if the main source fails for any reason. Reverts if fetched rate is 0.", "version": 1 }, "storageLayout": { "storage": [ { "astId": 21741, "contract": "contracts/oracle/oraclesL2/fallbackCLRSOracleL2.sol:FallbackCLRSOracleL2", "label": "_SEQUENCER_ORACLE", "offset": 0, "slot": "0", "type": "t_contract(IChainlinkAggregatorV3)25368" } ], "types": { "t_contract(IChainlinkAggregatorV3)25368": { "encoding": "inplace", "label": "contract IChainlinkAggregatorV3", "numberOfBytes": "20" } } } }