Do not use it in Production, testnet only.
This AVS aggregates price feed data from trusted on-chain oracle networks and allows other contracts to consume this aggregated price feed data.
Feed name / Symbol | Sources |
---|---|
BTC/USD | chainlink, dia |
ETH/USD | chainlink, dia |
Chainlink Feeds:
- ETH/USD : https://sepolia.etherscan.io/address/0x694AA1769357215DE4FAC081bf1f309aDC325306
- BTC/USD : https://sepolia.etherscan.io/address/0x5fb1616F78dA7aFC9FF79e0371741a747D2a7F22
Dia Feed:
This AVS demos the use of the EigenShift
package we built to allow operators to act as aggergators on task.
The EigenShift protocol is used to manage the automatic and trustless rotation of operators acting as task Aggregators.
Here's how it is integrated:
-
Leader Election (Aggregator assignment) and Task Submission: The protocol utilizes Raft to elect a new leader for each task. Every 15 seconds, a task is generated by the current leader operator, and a new operator is elected as the leader upon task submission.
-
Operator Setup: The operators are configured to automatically register and join the existing cluster of operators on startup, ensuring they can participate in the consensus protocol.
This ensures a robust, decentralized process for task aggregation in the AVS.
You can learn more about the EigenShift
package here.
The Price Oracle AVS keeps price aggregated feeds up to date by using the EigenShift protocol to rotate operators who act as task generators and aggregators.
The EigenShift protocol ensures there can only ever be 1 operator acting as the aggregator of a given task.
The current leader operator (acting as the generator and aggregator) requests task responses from other operators, gathers the price data (via bls signatures), and then submits the aggregated result on-chain. If the task is successfully submitted the current lead operator triggers a new election so that another operator becomes the aggregator for the next task.
This occurs every 15 seconds, ensuring continuous and decentralized price feed updates. Another contract can read the aggregate prices from the task manager by querying the stored price data that was last submitted by the elected Aggregator, ensuring access to up-to-date and reliable price information.
You can see a demo of this AVS running here: https://www.loom.com/share/05c799bb76784857947ee651b40b47fb
We expose a method to fetch the latest aggregated price for a given feed. Current supported feeeds are ETH/USD
and BTC/USD
. If there has not been a feed update within the last 30 blocks the data is considered stale. You can call:
IPriceAggregatorTaskManager.AggregatedPrice memory data = IPriceAggregatorTaskManager.fetchLatestAggregatedPrice(feedName)
Where AggregatedPrice
looks like:
struct AggregatedPrice {
uint32 price;
uint8 decimals;
uint32 lastBlockUpdated;
uint32 lastUpdatedTaskId; // Can be used to looks up submitted task data such as number of source used, number of operators submitted, etc
}
You will need foundry, zap-pretty, golang, and docker to run the examples below, and geth
curl -L https://foundry.paradigm.xyz | bash
foundryup
brew install ethereum
brew install maoueh/tap/zap-pretty
brew install jq
You will also need to install docker, and build the contracts:
make build-contracts
Before running these scripts ensure you create a .env
file that looks like the following.
SEPOLIA_RPC= #rpc endpoint must be an archival node rpc
We fork of sepolia testnet to ensure our local anvil node has access to testnet data feeds.
Start anvil in a separate terminal and run:
make deploy-all-to-anvil-and-save-state && make bindings && make start-anvil-chain-with-el-and-avs-deployed
The above command starts a local anvil chain from a saved state with eigenlayer and price-oracle already deployed (but no operator registered).
In order to have a task consensus this AVS requires at least 3 operators to be running.
Each operator must run in a stand alone terminal, so to run three operators run each of these commands in a seperate terminal:
make start-operator-1
make start-operator-2
make start-operator-3
Every 15 seconds a new task is generated by the operator which is the current leader. A new operator is elected leader on each aggregate task submission.
โ ๏ธ It takes a few minutes for an operator to start the first time