|
1 | 1 | # @api3/data-feed-proxy-combinators
|
2 | 2 |
|
3 |
| -> For general information about Api3 data feeds, dAPIs, and other services, end users are recommended to refer to the [official Api3 dApp documentation](https://docs.api3.org/dapps/). |
4 |
| -
|
5 |
| -## What is this? |
6 |
| - |
7 |
| -This repository contains a suite of utility smart contracts designed to work with and extend the functionality of Api3 data feeds. These contracts, often referred to as "proxy combinators" or "adapters," act as wrappers around existing data feeds, allowing dApp developers to transform, derive, or normalize data feed values to suit their specific application needs. |
8 |
| - |
9 |
| -The content in this directory provides insights into these combinator contracts, their design, and their intended use cases. For low-level documentation about functionality and usage, refer to the Natspec docstrings and the implementation of the respective contracts. |
10 |
| - |
11 | 3 | ## Overview
|
12 | 4 |
|
13 |
| -Api3 provides reliable, first-party oracle data directly to smart contracts, primarily through dAPIs (decentralized APIs) which are continuously updated data feeds. While these dAPIs serve a wide array of use cases, dApps occasionally require data in a format or derivation not directly offered by a base dAPI. For instance, a dApp might need an inverted price (e.g., USD/ETH from an ETH/USD dAPI), a value scaled to different decimal precision, or a data point derived from combining multiple existing dAPIs (e.g., BTC/ETH from a BTC/USD dAPI and an ETH/USD dAPI). |
| 5 | +> For general information about Api3 data feeds, dAPIs, and other services, end users are recommended to refer to the [official Api3 dApp documentation](https://docs.api3.org/dapps/). |
14 | 6 |
|
15 |
| -Manually implementing such logic within each dApp can be repetitive, error-prone, and gas-intensive. Furthermore, requiring a new, dedicated first-party oracle deployment for every minor data variation is not scalable. Data Feed Proxy Combinators address these challenges by providing **standardized and reusable smart contract solutions** for adapting data feeds on-chain. While a specific instance of a combinator proxy is typically deployed to serve a particular dApp's needs (often in conjunction with its dedicated underlying data feed proxy), these combinator contracts offer a common, audited approach to performing such transformations, promoting code reuse and reliability across the ecosystem. |
| 7 | +Api3 delivers reliable, first-party oracle data via dAPIs (continuously updated data feeds). However, dApps often require this data in formats or derivations not directly provided by a base dAPI, such as inverted prices (e.g., USD/ETH from ETH/USD), scaled values, or new feeds derived from combining multiple dAPIs (e.g., BTC/ETH from BTC/USD and ETH/USD). Data Feed Proxy Combinators address this as (soon-to-be) audited, standardized, and reusable smart contracts. These combinators operate on top of existing `IApi3ReaderProxy` contracts, enabling developers to combine them or transform their output to read data in different formats or derive new data feeds on-chain. This approach avoids repetitive, error-prone, and gas-intensive custom logic within individual dApps and the impracticality of deploying new oracles for minor data variations, thereby enhancing code reuse and reliability. |
| 8 | +Being documented, easily usable, and officially recommended by Api3, they offer a trusted and straightforward way for developers to implement these common data transformations. |
16 | 9 |
|
17 | 10 | ### Core Capabilities
|
18 | 11 |
|
19 |
| -These combinator contracts are designed to be modular and composable, typically taking the address(es) of underlying feed(s) and any necessary operational parameters (like scaling factors) in their constructors. They offer several key capabilities: |
20 |
| - |
21 |
| -- **Transformation:** Modify the value or metadata of a single underlying data feed. |
22 |
| - - **`InverseApi3ReaderProxyV1`**: Takes an underlying `IApi3ReaderProxyV1` (e.g., ETH/USD) and exposes an interface where `read()` returns the inverse of the underlying feed's value (e.g., `1 / (ETH/USD value)` to represent USD/ETH). |
23 |
| - - **`ScaledApi3FeedProxyV1`**: This contract reads from an underlying `IApi3ReaderProxyV1` and scales its value to a specified number of decimal places. However, it **exposes** the Chainlink `AggregatorV3Interface` (and `AggregatorV2V3Interface`). Its primary purpose is to make an Api3 data feed's value, adjusted to a different precision, consumable by systems expecting a Chainlink-compatible interface. |
24 |
| -- **Derivation/Combination:** Create a new logical data stream by performing operations on one or more underlying feeds. |
25 |
| - - **`ProductApi3ReaderProxyV1`**: Takes two underlying `IApi3ReaderProxy` instances (e.g., Feed A and Feed B). Its `read()` method returns the product of the values read from Feed A and Feed B. This contract itself implements `IApi3ReaderProxy`. Natspec would emphasize the importance of managing decimal places of the input feeds to ensure the product's decimal interpretation is correct, and potential overflow scenarios. |
26 |
| -- **Normalization/Adaptation:** Wrap data sources that may not strictly adhere to the standard `IApi3ReaderProxyV1` interface, making them compatible with systems expecting this interface. |
27 |
| - - **`NormalizedApi3ReaderProxyV1`**: This contract reads from an external data feed, typically one exposing a Chainlink-compatible `AggregatorV3Interface` (or `AggregatorV2V3Interface`). It then **exposes** the standard Api3 `IApi3ReaderProxy` interface. Its purpose is to allow dApps expecting an Api3 feed to consume data from sources like Chainlink feeds, often used as part of a migration strategy (see the Migrate from Chainlink guide). Its constructor would take the address of the external feed. Natspec would explain how it translates the external feed's data structure (e.g., `latestRoundData`) and timestamping (if available) into Api3's `(int224 value, uint32 timestamp)` format. |
28 |
| -- **Composability:** The output of one combinator proxy can often serve as the input for another. This allows developers to chain multiple combinators together to create complex data transformation pipelines on-chain. For example, one could take a base feed, use `ScaledApi3FeedProxyV1` to adjust its decimals, then feed the output into an `InverseApi3ReaderProxyV1`. |
29 |
| - - _Example 1 (Api3 to Api3):_ An `IApi3ReaderProxy` could be wrapped by `InverseApi3ReaderProxyV1` (outputting `IApi3ReaderProxy`), which is then wrapped by another `ProductApi3ReaderProxyV1` (also outputting `IApi3ReaderProxy`). |
30 |
| - - _Example 2 (Mixed Interfaces):_ An `IApi3ReaderProxy` could be wrapped by `ScaledApi3FeedProxyV1` (outputting `AggregatorV3Interface`). Conversely, a Chainlink feed (`AggregatorV3Interface`) could be wrapped by `NormalizedApi3ReaderProxyV1` (outputting `IApi3ReaderProxy`). This highlights the adapter nature of some combinators. |
31 |
| - |
32 |
| -A key design principle is that these combinator proxies either consume and expose the Api3 `IApi3ReaderProxy` interface (the standard way to read dAPIs), or act as adapters between `IApi3ReaderProxy` and other common data feed interfaces like Chainlink's `AggregatorV3Interface`. This ensures that dApps can integrate these combinators effectively, whether they are working purely within the Api3 ecosystem or bridging data from/to other oracle systems. |
33 |
| - |
34 |
| -### Benefits |
35 |
| - |
36 |
| -Utilizing Data Feed Proxy Combinators offers several advantages: |
37 |
| - |
38 |
| -- **Enhanced Flexibility:** Empowers dApp developers to tailor data consumption to their precise needs without altering their core logic significantly. |
39 |
| -- **Increased Efficiency:** Reduces the need for redundant on-chain calculations within individual dApps and avoids the operational overhead of requesting numerous slightly varied dAPIs from API providers. |
40 |
| -- **Improved Scalability:** Allows the Api3 ecosystem to serve a broader range of data requirements by leveraging existing data feeds in new ways. |
41 |
| -- **Standardization:** Provides a common set of tools for common data feed manipulations, promoting code reuse and reliability. |
42 |
| -- **Simplified Integration:** By adhering to standard interfaces, these combinators lower the barrier for dApps to access derived or transformed data. |
43 |
| - |
44 |
| -## Intended Use Cases |
45 |
| - |
46 |
| -Data Feed Proxy Combinators are particularly useful in scenarios such as: |
47 |
| - |
48 |
| -- **Accessing Inverse Feeds:** When a dApp requires a price quoted as `QUOTE/BASE` but the available oracle feed provides `BASE/QUOTE` (e.g., using `InverseApi3ReaderProxyV1`). |
49 |
| -- **Decimal Precision Adjustment:** Matching a data feed's precision to a dApp's internal numerical representation or the requirements of another protocol (e.g., using `ScaledApi3FeedProxyV1` to convert an 8-decimal feed to an 18-decimal representation). |
50 |
| -- **Calculating Derived Values:** |
51 |
| - - Cross-Rates: Deriving exchange rates like EUR/JPY from EUR/USD and USD/JPY feeds. This might involve using `InverseApi3ReaderProxyV1` on one feed and then `ProductApi3ReaderProxyV1` with the result and the other feed. |
52 |
| - - Other Products: Calculating values that are a product of two reported data points. |
53 |
| -- **Adapting External Data Sources:** Integrating data from non-standard on-chain sources (e.g., other oracle networks via `NormalizedApi3ReaderProxyV1`) into systems expecting an Api3-compatible feed interface. This is particularly relevant when migrating from other oracle providers or when a specific feed is only available through a non-Api3 interface. |
54 |
| -- **Building Complex Financial Instruments:** Creating structured products or derivatives whose values depend on mathematical combinations or transformations of underlying asset prices. |
55 |
| -- **Gas Optimization for Multiple Readers:** If multiple contracts need the same transformed version of a feed, deploying a single combinator proxy can be more gas-efficient than each contract performing the transformation independently. |
56 |
| - |
57 |
| -## Design Philosophy |
| 12 | +Data Feed Proxy Combinators provide modular and composable smart contracts for on-chain data feed adaptation. They typically take the address(es) of underlying feed(s) and operational parameters (like scaling factors) in their constructors. Key contract implementations include: |
58 | 13 |
|
59 |
| -The development of these combinators is guided by several principles: |
| 14 | +- **`InverseApi3ReaderProxyV1`**: Takes an underlying `IApi3ReaderProxy` (e.g., ETH/USD). Its `read()` method returns the inverse of the underlying feed's value (e.g., `1 / (ETH/USD value)` to represent USD/ETH), exposing an `IApi3ReaderProxy` interface. |
| 15 | +- **`ScaledApi3FeedProxyV1`**: Reads from an underlying `IApi3ReaderProxy`, scales its value to a specified number of decimal places, and exposes the Chainlink `AggregatorV3Interface` (and `AggregatorV2V3Interface`). This makes an Api3 data feed, with adjusted precision, consumable by systems expecting a Chainlink-compatible interface. |
| 16 | +- **`ProductApi3ReaderProxyV1`**: Takes two underlying `IApi3ReaderProxy` instances. Its `read()` method returns the product of their values, implementing the `IApi3ReaderProxy` interface. |
| 17 | +- **`NormalizedApi3ReaderProxyV1`**: Reads from an external data feed (typically Chainlink-compatible `AggregatorV3Interface`) and exposes the standard Api3 `IApi3ReaderProxy` interface. This allows dApps expecting an Api3 feed to consume data from other sources, useful for migration. |
60 | 18 |
|
61 |
| -- **Modularity:** Each contract aims to perform a specific, well-defined transformation or combination. |
62 |
| -- **Security:** The combinators are designed to be simple and robust. Their security relies on the correctness of their own logic and, crucially, on the security and reliability of the underlying Api3 data feeds they consume. They aim to introduce minimal additional trust assumptions. |
63 |
| -- **Gas Awareness:** While providing on-chain data manipulation, efforts are made to ensure the implementations are as gas-efficient as reasonably possible for their intended operations. |
64 |
| -- **Clarity and Reusability:** Contracts are written to be understandable and generic enough to be applied in a variety of dApp contexts, promoting best practices in data feed consumption. |
| 19 | +These combinators either consume and expose the Api3 `IApi3ReaderProxy` interface or act as adapters to/from other interfaces like Chainlink's `AggregatorV3Interface`. This facilitates integration within the Api3 ecosystem or when bridging with other oracle systems. The output of one combinator can often serve as input for another, enabling complex data transformation pipelines. |
65 | 20 |
|
66 | 21 | ## Further Information
|
67 | 22 |
|
68 |
| -For detailed, low-level documentation about the specific functionality, constructor arguments, public methods, and Natspec comments, please refer to the source code of the respective contracts within this repository. Understanding the underlying `IApi3ReaderProxy` interface (typically `interface IApi3ReaderProxy`) from the main `@api3/contracts` repository will also be beneficial. For more information on how dApps interact with Api3 data feeds, consult the Api3 dApp documentation. |
| 23 | +For detailed specifications of each combinator, including constructor arguments, public methods, and Natspec documentation, please consult the contract source code within this repository. Familiarity with the `IApi3ReaderProxy` interface from the `@api3/contracts` repository is also highly recommended for effective integration. |
0 commit comments