-
Notifications
You must be signed in to change notification settings - Fork 120
Created OpenOracleFrameworkOracle.sol #28
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// SPDX-License-Identifier: MIT | ||
// Using the same Copyleft License as in the original Repository | ||
pragma solidity 0.6.12; | ||
import "@boringcrypto/boring-solidity/contracts/libraries/BoringMath.sol"; | ||
import "../interfaces/IOracle.sol"; | ||
|
||
// Open Oracle Framework Interface | ||
interface IOpenOracleFramework { | ||
function getFeed(uint256 feedID) external view returns (uint256, uint256, uint256); | ||
} | ||
|
||
// Open Oracle Framework TWAP Interface | ||
interface IOpenOracleFrameworkTWAP { | ||
function getTWAP( | ||
address OOFContract, | ||
uint256[] memory feedIDs, | ||
uint256[] memory timestampstart, | ||
uint256[] memory timestampfinish, | ||
bool strictMode) | ||
external view returns (uint256[] memory TWAP); | ||
} | ||
|
||
contract OpenOracleFramework is IOracle { | ||
using BoringMath for uint256; // Keep everything in uint256 | ||
|
||
// Calculates the latest rate | ||
function _get( | ||
address oracle, | ||
uint256 feedId | ||
) internal view returns (uint256) { | ||
uint256 price; | ||
uint256 decimals; | ||
(price, , decimals) = IOpenOracleFramework(oracle).getFeed(feedId); | ||
return price / decimals; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this already conform to the Kashi oracle standard of providing the price of 1e18 of asset? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We standardize all feed returns to be 18 dec yes. |
||
} | ||
|
||
// Calculates the 24h TWAP rate | ||
function _getTWAP( | ||
address twap, | ||
address oracle, | ||
uint256 feedId | ||
) internal view returns (uint256) { | ||
|
||
uint256 decimals; | ||
(,,decimals) = IOpenOracleFramework(oracle).getFeed(feedId); | ||
|
||
uint256[] memory feedIdInput = new uint256[](1); | ||
uint256[] memory twapStart = new uint256[](1); | ||
uint256[] memory twapEnd = new uint256[](1); | ||
|
||
feedIdInput[0] = feedId; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you have any mapping from feedIds to price feeds? (what the price feed represents e.g. ETH/USDC There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no mappings as oracles are free to submit any data they want for their oracle. You could simply check through getfeedlist for a matching name though. |
||
twapStart[0] = block.timestamp - 60*60*24; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What reasoning makes you choose a 24hour TWAP? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 24h TWAP gives enough data and time to help protect flash events, while also being flexible enough to adapt to sudden market changes. The 24h TWAP provided could easily be changed though, depending on how much actual compatibility, the front end could pool creators choose the TWAP when an oof oracles detected, as all oracles are compatible with arb TWAPs. |
||
twapEnd[0] = block.timestamp; | ||
|
||
uint256 price = IOpenOracleFrameworkTWAP(twap).getTWAP(oracle,feedIdInput,twapStart,twapEnd,false)[0]; | ||
return price / decimals; | ||
} | ||
|
||
function getDataParameter( | ||
address multiply, | ||
address divide, | ||
uint256 decimals | ||
) public pure returns (bytes memory) { | ||
return abi.encode(multiply, divide, decimals); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the encoding here is incoherent with get and peek There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the documentation, we assumed that these fns act as getspot and getprice, and assumed there was a need to know spot when TWAPs were used. So get was made to get the latest price update where peek waa the TWAP value to be protected. |
||
} | ||
|
||
// Get the latest exchange rate | ||
/// @inheritdoc IOracle | ||
function get(bytes calldata data) public override returns (bool, uint256) { | ||
(address oracle, uint256 feedId) = abi.decode(data, (address, uint256)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the data encoded seems to be different between peek and get There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See before |
||
return (true, _get(oracle, feedId)); | ||
} | ||
|
||
// Check the last exchange rate without any state changes | ||
/// @inheritdoc IOracle | ||
function peek(bytes calldata data) public view override returns (bool, uint256) { | ||
(address twap, address oracle, uint256 feedId) = abi.decode(data, (address, address, uint256)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should Oracle and TWAP be hardcoded to the official deployments? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oracle should not as that oracles simply a reference oracle ran by us, the real power from oof and use would be for anyone to use the framework to create pools for lending. The TWAP can be hardcoded though as thats oracle agnostic and just a tool to grab all values and create the TWAP. |
||
return (true, _getTWAP(twap, oracle, feedId)); | ||
} | ||
|
||
// Check the current spot exchange rate without any state changes | ||
/// @inheritdoc IOracle | ||
function peekSpot(bytes calldata data) external view override returns (uint256 rate) { | ||
(address oracle, uint256 feedId) = abi.decode(data, (address, uint256)); | ||
return _get(oracle, feedId); | ||
} | ||
|
||
/// @inheritdoc IOracle | ||
function name(bytes calldata) public view override returns (string memory) { | ||
return "Open Oracle Framework"; | ||
} | ||
|
||
/// @inheritdoc IOracle | ||
function symbol(bytes calldata) public view override returns (string memory) { | ||
return "OOF"; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the spot price manipulatable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As these are oracles they choose the spot price source, they would probably use a platform like coingecko or the ETH price index which already uses multiple exchange prices to form prices making manipulation almost impossible unless spending bns USD. We also have the oracles have a threshold for multisjg, so 1 price submit will not be returned by the oracle as the latest, only median prices from n threshold.