Oracle operations on Liquid Collective report on consensus layer data
The Oracle holds a list of the Oracle Operators' members who are expected to periodically report Consensus Layer data. These addresses can be checked via an off-chain naive search request.
The Oracle contract is configured such that a representative subset of those Operators are required to report the same Consensus Layer (also referred to as Beacon Chain) data before the Oracle contract reports to the River contract.
The Oracle is set to report Consensus Layer data to the River contract at configurable Consensus Layer epochs. For each reporting epoch, the Oracle contract expects a quorum of Oracle Operators to report the identical Consensus Layer data before reporting to the River contract.
The Oracle contract is configurable so data is reported from a starting epoch and then for every epoch at a given interval.
In the current deployment, this interval is configured so consensus layer data is reported approximately every 24 hours.
The Oracle contract holds a configurable quorum value that indicates the minimum number of Oracle Operators that must report identical Consensus Layer data before reporting the data to the River contract.
At each reporting epoch, every Oracle Operator is expected to collect Consensus Layer data and report it to the Oracle contract through a transaction. The Oracle contract counts the reported consensus layer balance sum of Liquid Collective validators, the reported count of validators, and the number of similar reports from Oracle Operators, along with the count of report variants.
Any changes to the quorum, such as removing Oracle Operators from the members list, clears all of the reporting data for that epoch. Remaining Oracle Operators that had already submitted reports for that epoch would need to report again for the same epoch.
Once receiving a quorum of identical reports, the Oracle contract publishes the data to the River contract, at which point the River contract can compute and distribute network rewards.
The Oracle contract aims to report the following data to the River contract:
Epoch - The epoch for which the Consensus Layer data corresponds to.
Validators Count – The count of active Liquid Collective validators on the Consensus Layer (either in status active or active_ongoing). This is necessary so River can compute the number of validators in pending status that have been staked to on the Deposit Contract but are not yet active on the Consensus Layer.
Validators Balance – The total ETH balance of active Liquid Collective validators on the Consensus Layer.
The Oracle contract is responsible for performing certain sanity checks on the reported data, providing a layer of security to the protocol in case Oracle Operators behave maliciously.
First, the Oracle contract makes sure that the Oracle Operator's reported transactions are for the correct expected epoch.
Second, it makes sure that the validators' reported balances are coherent. In particular, the Oracle contract:
Forbids Oracle Operators from reporting earned rewards that would exceed some configurable upper bound of APY. This upper bound takes into account the APY delta between updates extrapolated on a yearly time frame.
Forbids Oracle Operators from reporting a balance that would have decreased more than some configurable lower bound of fees or penalties. This lower bound is based on the relative balance decrease.
The execution layer fees are taken into account in these sanity checks as they are the product of a Node Operator's work, just like consensus layer fees.
The Oracle contract receives reports from the Oracle Operators and updates the following data for the River contract:
Validators Count – The count of active Liquid Collective validators on the Consensus Layer (either in status active or posterior). This count is necessary to compute the count of Liquid Collective validators in pending status that have been funded and deposited to the Deposit Contract but are not yet active on the Consensus Layer.
Validators Balance – The total ETH balance of active Liquid Validators on the Consensus Layer.
Each time a new report is processed, if Liquid Collective's validators have collectively earned a positive network reward, then this network reward is distributed between parties involved in the Liquid Collective protocol by increasing the Conversion Rate for LsETH.
Operator running Oracle
Oracle Operators are responsible for periodically reporting consensus layer data to the Liquid Collective protocol.
In particular, they are responsible for reporting network rewards earned by validators on the consensus layer so those network rewards can be accounted for, accruing the value of the LsETH token (cToken) by increasing the Conversion Rate.
The Oracle smart contract is responsible for synchronizing Oracle Operators.
Oracle operators are responsible for periodically reporting consensus layer data to the execution layer.
In particular, they are responsible for reporting network rewards earned by validators on the consensus layer so those network rewards can be accounted for, accruing the value of the LsETH token (cToken) by increasing the Conversion Rate.
The Oracle smart contract is responsible for synchronizing Oracle operators. In particular it:
Lists the addresses of Oracle members that are expected to report
Sets the next target epoch to be reported by Oracle members
Expects a quorum of Oracle members to report the same data at the target epoch before forwarding it to the River contract
Oracle reports consist of:
The count of validators on the consensus layer
The total balance of those validators on the consensus layer
Oracle Operators interested in participating in the Oracle set should go through the following procedure:
One-Time Protocol Onboarding
Oracle Operator generates a wallet to be used as Operator members
Oracle member address gets approved on the Oracle smart contract
Ongoing Operations
Oracle Operator configures and runs the Oracle daemon in its infrastructure connecting self-managed Ethereum EL and CL clients
Oracle Operator makes sure that the Operator member account always has a sufficient ETH balance to pay for gas fees implied by report transactions
To facilitate operations, Oracle Operators are recommended to use the Oracle daemon which is an open-source application maintained by Liquid Collective. While the Oracle daemon is recommended, it is not mandatory, and Oracle Operators can opt-out of it and use their own preferred solution.
The Oracle daemon is a long-living application that:
Continuously listens for event logs emitted by the Operators Registry contract
Calls the Oracle contract to get the next target epoch to report
Exposes various metrics about the activity of the Oracle
When the target epoch to report is reached, it:
Collects consensus layer data for the target epoch
Generates a report from the collected data (validators count and total balance on the consensus layer)
Sends the report transaction to the Oracle contract
The Oracle daemon can optionally run in --dry-mode
in which case it does not send report transactions to the chain.
The Oracle daemon needs to be connected to:
Ethereum Execution Layer RPC endpoint
to listen for event logs emitted by the Operator registry contract (in particular events when validator keys get funded)
to aggregate all withdrawals data since the Shapella fork
to call the Oracle contract for the next epoch to report
Ethereum Consensus Layer HTTP endpoint
to query validator data
The Oracle Daemon also needs access to a private key for signing report transactions. This wallet corresponds to the oracle member address that has been approved on the oracle contract.
Since the Shapella fork, it has become necessary to retrieve withdrawals for all Liquid Collective validators. However, there is no available API for this task. One solution is to read all blocks, but this consumes a large number of requests. An alternative solution is to implement a stateful approach.
As a result, we have decided to introduce a new flag in the lceth CLI, --data-dir, which stores the state of withdrawals. The stored state encompasses all withdrawals and their corresponding blocks. (The estimated size of the storage is approximately 4 GB.)
A synced Execution Layer client with JSON-RPC endpoint enabled. All implementations are supported (Geth, Erigon, Besu, etc.)
A synced Consensus Layer client with API endpoint enabled. All implementations are supported (Prysm, Teku, Lighthouse, etc.)
The recommended installation is to use the public Docker image public.ecr.aws/alluvial/liquid-collective/lceth:latest
It is also possible to build the binary from sources and run it.
Sending an Oracle report uses about 100,000 gas for a regular report and ~300,000 gas when reaching the quorum.
Let's estimate how much in gas fees an Oracle Operator should pay per year, considering:
the protocol expects 1 report per day
the average gas price is 30 gwei
there are 5 oracle operators
the quorum is 3
all operators use an implementation which alternates submissions order
This means that each day there is a 2/5 probability of sending a regular report and a 1/5 probability of sending a report that reaches quorum:
(365 * 2/5 * 100000 + 365 * 1/5 * 300000) * 30 = 1 095 000 000 Gwei = 1.09 ETH / year
To generate such a wallet you can use the following command:
Once generated you should securely store the key file and password for later usage, as you will need it each time you will run the Oracle daemon.
Submit the Oracle member address to the administrator to get it approved on the Oracle contract members list.
Oracle has become stateful; be sure to choose an appropriate data directory using the --data-dir
flag.
In dry run the Oracle daemon collects data and generates reports but does not send transactions to the Oracle contract.
It is recommended to use dry run mode when:
You are not an Oracle Operator and you are only interested in collecting Oracle metrics data
You are an Oracle Operator and you want to first test in dry run before running in live mode
To run the oracle in dry-run mode, you can run:
In live mode, the daemon runs full capabilities and sends transactions to the chain for every epoch to be reported.
In live mode, you need the daemon to have access to the Oracle member wallet that will be used to sign report transactions.
Top up Oracle Operator account
Before starting the daemon you should make sure that the Oracle Operator account has been topped-up with ETH so it can pay for the gas fees for the report transactions.
After starting the daemon, an Oracle Operator should make sure that the Oracle member account always has a sufficient balance of ETH to send report transactions.
Oracle Operators are responsible for paying for the gas implied by the report transaction.
To run the daemon in live mode, you can run:
The Oracle service exposes a health endpoint that exposes routes for monitoring:
/live
Liveness endpoint
/ready
Readiness endpoint
/metrics
Prometheus metrics