Skip to content

Latest commit

 

History

History
191 lines (124 loc) · 12.1 KB

eip-2362.md

File metadata and controls

191 lines (124 loc) · 12.1 KB
eip title author discussions-to status type category created
2362
Numeric Pull Oracle Interface
Alliance of Decentralized Oracles (eips@theado.org), Brenda Loya (@brendaloya), Adán SDPC (@aesedepece)
Draft
Standards Track
ERC
2019-11-06

Simple Summary

A standard interface for numeric pull oracles.

Abstract

Smart contracts on Ethereum require the use of oracles (external reporters) for acquiring knowledge of any piece of data that does not belong to the Ethereum state.
A standard interface for oracles is described here, allowing different oracle implementations to be interchangeable from the point of view of the consumer, and lead to increased security and freedom of choice.

Motivation

As the value held by smart contracts that rely on off-chain data keeps growing, the security of oracles systems and the ability of these to be interchangeable and combined together will become paramount. Due to the modular nature of decentralized finance protocols, attacks on oracle mechanisms do not only pose a substantive risk of financial loss for their users, but also a systemic risk for the entire Ethereum ecosystem.

The Ethereum ecosystem currently has a rich variety of oracle implementations available. Each different oracle solution has its own distinctive features and trade-offs, specially when it comes to their security and economic models, their degree of decentralization, and even their intended use cases. Due to this diversity in approaches, the programming interfaces that these oracles offer are mostly incompatible with each other.

This lack of standardization forces developers to be locked into a single oracles provider. The only way for them to escape from this "vendor lock-in" is to write specific adapters to each oracle system they may choose for a given project, which is obviously inconvenient and an unnecessary increment to the surface of attack of the consumer contracts.

The goal of this proposal is therefore to introduce a unified, bare-bones contract interface that enables smart contract developers to source a specific data point from different oracle systems in a uniform, plug-and-play manner.

This new proposal is a cooperation between current oracle systems and direct users of these. The specification below reflects this collaboration and addresses the main reasons why former standardization attempts were not successful.

Specification

Scope

Generally speaking, there are two different types of oracles: push and pull oracles. Where push oracles are expected to send back a response to the consumer and pull oracles allow consumers to pull or call/read the data onto their own systems. This specification is for pull based oracles only.

This proposal focuses namely on numeric data points, as these have been proven of special relevance to decentralized finance protocols, which are an increasingly widespread use case of the Ethereum smart contracts capabilities.

Definitions

Oracle
An entity that reports data to the blockchain. In different oracle systems, this can be an account or a contract.
Consumer
A smart contract which receives or reads data from an oracle.
ID
A way of indexing a specific data point that an oracle reports. May be derived from or tied to a explicit query, for which the oracle provides the answer in form of a _Value_.
Value
A piece of data associated with an ID, as reported by an oracle. This is the answer to a query that is tied to a specific ID. Other equivalent terms that have been used include: result, answer, data, outcome.

Pull-based Interface

This is the specification for the pull-based interface:

interface IERC2362
{
	function valueFor(bytes32 _id) external view returns(int256 _value,uint256 _timestamp,uint256 _statusCode);
}
  • valueFor MUST return a status code of 404 if the value for an id is not available yet.
  • Once a value is first available for an id, valueFor MUST return the value, along the timestamp representing when such value was set, and a status code of 200.
  • May the value associated to an id be updated, valueFor MUST return the newest available value, along the timestamp representing when such update took place, and a status code of 200.

Inputs

bytes32 id

A standard descriptor of the data point we are querying a value for.

IDs are built deterministically as the bytes32 value resulting from the Keccak256 hash digest of the concatenation of a data point type, a hyphen, a caption, another hyphen, and a number of decimal positions:

keccak256(type + "-" + caption + "-" + decimalPlaces)

The specific hyphen character is the hyphen-minus (Unicode code point U+002D / HTML -). To avoid ambiguity, the use of this character is not allowed inside the type or caption fields.

It is up to the implementor of an ERC-2362 compliant contract to decide which IDs to support, i.e. for which IDs will valueFor return a value and timestamp at some point, and for which it will always revert.

These ids MUST however be uniform across all providers: multiple EIP-2362 compliant contracts can give different values and timestamps for the same id, but they must be referring to the same data point.

Registered IDs

These are the initally registered IDs for usage in ERC-2362 compliant contracts:

Type Caption DecimalPlaces String ID
Price ETH/USD 3 Price-ETH/USD-3 dfaa6f747f0f012e8f2069d6ecacff25f5cdf0258702051747439949737fc0b5
Price BTC/USD 3 Price-BTC/USD-3 637b7efb6b620736c247aaa282f3898914c0bef6c12faff0d3fe9d4bea783020
Price XAU/USD 3 Price-XAU/USD-3 2dfb033e1ae0529b328985942d27f2d5a62213f3a2d97ca8e27ad2864c5af942
Price DAI/USD 6 Price-DAI/USD-6 9899e35601719f1348e09967349f72c7d04800f17c14992d6dcf2f17fac713ea

IDs a represented here in hexadecimal encoding for the sake of legibility, but ERC-2362 compliant contract MUST handle them as bytes32 at all times.

This EIP is not a central directory for the registered IDs, which are instead maintained by the Alliance of Decentralized Oracles in ADOIPs-0010.

Registration of IDs is done with informative purposes only. Registration of an ID is not compulsory, and unregistered IDs can be used without any restrictions. However, it is recommended that commonly used value pairs are registered and have an ID publicly assigned to them, so that it becomes much easier to find multiple oracles that provide uniform data points that can be aggregated together without formatting risks (e.g. different oracles using a different number of decimal places when encoding floating point numbers).

Outputs

uint timestamp

Timestamp (in the Unix format as used by the EVM) associated to the returned value.

It is up to the implementor of an EIP-2362 compliant contract to set the associated timestamp to one of these:

  • the timestamp of the block in which the returned value was last mutated (by invoking block.timestamp or now() at the updating transaction).
  • an oracle-specific timestamp that offers a more precise metric of when the reported value was actually probed.
int value

Latest value available for the requested id.

To accommodate for decimal values (which are common in prices and rates) this is expected to be multiplied by a power of ten such as 10**9 or 10**18. The specific power of ten MUST explicitly be stated by the id used as input.

uint status

Describes the value's status. For consistency, the status codes will correspond to the codes used for HTTP status codes

Status codes:

  • 200 OK
  • 400 Bad Request
  • 404 Not Found

Rationale

Currently deployed contracts require oracles and individual companies to build specific adapters for each implementation. Future builds by both oracle adapters and new companies can create a world where oracles are interchangeable. Diversity in oracle technology paired with oracle implementations being interchangeable can drastically increase security of oracle consumers since attacks on oracles can be minimized by projects utilizing multiple oracles in their design (averages, medians, etc.).

Prior art

A former attempt to standardizing an oracle interface(EIP-1154) was not widely adopted and abandoned early as specifically too broad/general to provide any efficiency gains.

EIP-1154 prescribed two functions for pulling (resultFor) and pushing (receiveResult) data where the consumer would pull data or the oracle provider would push data to the consumer contract. Both functions specified inputs and results as bytes data (bytes32 and bytes) and had a conversion cost associated with them that was deemed insignificant through testing within the EIP discussion. More information is available here:

When abandoning EIP-1154, its own author concluded:

“It seems wasteful to specify something only to force proprietary interpretations of data on oracles anyway, and have silly things like putting ABI encoded stuff in data only to unwrap it and reinterpret it before putting it in a different format. At that point, just have the proprietary endpoint and use plain function calls.” — Alan Lu

Multiple Oracle Consumers

It is to be expected that the co-existence of multiple

Oracle consumers can choose as many oracles as they wish and mix and match the types based on their needs (i.e. average value from several oracles e.g. Compound’s and Maker’s open oracle designs).

Result Immutability

In the proposed specifications, oracle consumers determine when results are immutable once they use the value to execute and finalize a transaction. However, the use of multiple oracles and a dispute period is highly recommended for the oracle consumers to increase security since finality of a value can be affected by an oracle attack but as with any attack on chain, it becomes extremely expensive to attack over time and eventually “good/correct” values will make it on-chain.

Implementation

Interfaces:

Examples:

  • IERC2362 compliant mock: can be used in tests as a mock that provides an ERC2362 compliant oracle with no decentralization or security features whatsoever (anyone can freely report a value).
  • Medianizer contract: pulls a data point from multiple oracles at once, and returns the median value through an ERC2362 compliant interface.
  • Aggregator contract: a single ERC2362 compliant contract providing values for multiple IDs as read from a series of ERC2362 compliant contracts, i.e. acts as a router that forwards the query to different contract depending on the ID.
  • Witnet's BTC/USD Price Feed: a Witnet powered price feed that provides values for ID 637b7efb6b620736c247aaa282f3898914c0bef6c12faff0d3fe9d4bea783020 (Price-ETH/USD-3).

Copyright

Copyright and related rights waived via CC0.