creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/presets/ChainlinkConvertPushOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\nimport \"../OnDemandOracle.sol\";\r\nimport \"../interfaces/AggregatorInterface.sol\";\r\n\r\n/// @notice Chainlink oracle conversion for OnDemand oracles compatibility: converts a /ETH feed to /USD\r\ncontract ChainlinkConvertPushOracle is OnDemandOracle {\r\n  address public immutable feed0;\r\n  address public immutable feed1;\r\n\r\n  constructor(address _feed0, address _feed1){\r\n    require(_feed0 != address(0) && _feed1 != address(0), \"Invalid Feed\");\r\n    require(AggregatorInterface(_feed0).decimals() == 18 && AggregatorInterface(_feed1).decimals() == 8, \"Invalid decimals\");\r\n    feed0 = _feed0;\r\n    feed1 = _feed1;\r\n  }\r\n  \r\n  /// @notice Returns the latest price answer \r\n  function latestAnswer() public override virtual view returns (int256) {\r\n    return AggregatorInterface(feed0).latestAnswer() * AggregatorInterface(feed1).latestAnswer() / 1e18;\r\n  }\r\n  \r\n  \r\n  /// @notice Returns the latest price answer \r\n  function lastUpdate() public override virtual view returns (uint256) {\r\n    (,,, uint256 updatedAt,) = AggregatorInterface(feed0).latestRoundData();\r\n    return updatedAt;\r\n  }\r\n  \r\n  function description() public override view returns (string memory) {\r\n    return string(abi.encodePacked(AggregatorInterface(feed0).description(), \"/\", AggregatorInterface(feed1).description()));\r\n  }\r\n}\r\n"
      },
      "src/OnDemandOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\nimport \"./IOnDemandOracle.sol\";\r\n\r\n\r\n/// @notice On-demand oracle structure, can be extended for various use cases\r\nabstract contract OnDemandOracle is IOnDemandOracle {\r\n  int256 internal _latestAnswer;\r\n  uint internal _lastUpdate;\r\n  // Default staleness infinite: cant become stale\r\n  uint public maxStaleness = type(uint).max;\r\n  uint public constant decimals = 8;\r\n  \r\n  /// @notice Update and get latest oracle answer based on signed offchain data\r\n  /// @dev Should be overriden with particular price update logic, \r\n  function updateAnswer(bytes calldata priceUpdateData) external payable virtual returns (int256){\r\n    _updateAnswer(priceUpdateData);\r\n    require(!isStale(), \"Oracle is Stale\");\r\n    return latestAnswer();\r\n  }\r\n  \r\n  /// @notice Price update logic\r\n  function _updateAnswer(bytes calldata priceUpdateData) internal virtual {}\r\n  \r\n  /// @notice Is price old and needs to be updated\r\n  function isStale() public view returns (bool) {\r\n    return (block.timestamp - lastUpdate() > maxStaleness);\r\n  }\r\n  \r\n  /// @notice Returns the latest price answer \r\n  function latestAnswer() public virtual view returns (int256) {\r\n    return _latestAnswer;\r\n  }\r\n  \r\n  /// @notice Get lats update time\r\n  function lastUpdate() public virtual view returns (uint256) {\r\n    return _lastUpdate;\r\n  }\r\n  \r\n  /// @notice Oracle description\r\n  function description() public virtual view returns (string memory){\r\n    return \"OnDemandOracle\";\r\n  }\r\n}\r\n"
      },
      "src/interfaces/AggregatorInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\ninterface AggregatorInterface {\r\n  function latestAnswer() external view returns (int256);\r\n  function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\r\n  function decimals() external view returns (uint8);\r\n  function description() external view returns (string memory);\r\n}"
      },
      "src/IOnDemandOracle.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.19;\r\n\r\n/// @notice IOnDemandOracle used for oracles that get their value from offchain signed data\r\ninterface IOnDemandOracle {\r\n  /// @notice Get latest oracle answer (may be stale)\r\n  function latestAnswer() external view returns (int256);\r\n  \r\n  /// @notice Update and get latest oracle answer based on signed offchain data\r\n  /// Reverts on bad priceUpdateData\r\n  function updateAnswer(bytes calldata priceUpdateData) external payable returns (int256);\r\n  \r\n  function decimals() external view returns (uint256);\r\n  \r\n  function lastUpdate() external view returns (uint256);\r\n  \r\n  function isStale() external view returns (bool);\r\n  \r\n  function description() external view returns (string memory);\r\n}"
      }
    },
    "settings": {
      "remappings": [
        "@redstone-finance/evm-connector/=node_modules/@redstone-finance/evm-connector/",
        "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
        "@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/",
        "forge-std/=lib/forge-std/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}