An aggregator or data feed is what on-chain developers use when building smart contracts. A data feed is a collection of jobs that get aggregated to produce a single, deterministic result. Typically the first task in a job will fetch external data with subsequent tasks responsible for parsing the response and transforming the value into a single data type, like an integer or decimal.
When an oracle is assigned to process a data feed update, the oracle executes the defined jobs, computes the weighted median of the job responses, and publishes the result on-chain. If sufficient oracles respond, the on-chain program computes the final result as the median of the assigned oracle responses.
A Switchboard Function can also be used for the same effect with greater customization. You can have a single function route 500+ data feeds (See the PushOracle EVM contract for an example).
- Aggregator: Contains the data feed configuration, dictating how data feed updates get requested, updated, and resolved on-chain.
- Job Account: Stores the blueprints for how data is fetched off-chain for a particular data source.
- Permission Account: Permits a data feed to join an oracle queue.
- Lease Contract: Pre-funded escrow contract to reward oracles for their work.
- Crank: Optional, owned by the queue and allows a data feed to be updated at a regular interval.
- History Buffer: Optional, allows a feed to store the last N values.
An Aggregator Account stores a collection of Job Account public keys along with the hashes of the job definitions. This is to prevent malicious RPC nodes from providing incorrect task definitions to oracles before fulfillment.
A Job Account is a collection of Switchboard Tasks that get executed by an oracle sequentially. Each Job Account typically corresponds to a single data source. A data feed requires at least one job account and at most 16 job accounts. Switchboard Job Accounts can be used to source data from:
- HTTP endpoints, public or private
- On-Chain data from Solana, Ethereum, etc
- Anchor programs
- ... and more
A data feed can assign job weights to a job account which will be used when the oracle calculates the median across the job responses. This is useful to weight data sources by some metric such as liquidity or a reliability score.
It is strongly recommended to utilize job weights as not all data sources are created equally.
Currently the only way to set a job weight is to remove and re-add the job account to a feed.
Data Feed Composability
Data feeds may reference other data feeds and build upon each other. It is strongly recommended that you own any feed that you reference in case of downstream impacts out of your control. While anyone can extend another feeds lease, a lease owner can always withdraw any lease funds and prevent future updates.
As an example, you could construct the following feed definition:
- Create a Switchboard feed that sources SOL/USD prices from a variety of exchanges, each weighted by their 7d volume, along with a history buffer
- Create a Switchboard feed that uses an OracleTask to fetch the Pyth SOL/USD price every 10 seconds, along with a history buffer
- Create a Switchboard feed that uses an OracleTask to fetch the Chainlink SOL/USD price every 10 seconds, along with a history buffer
- Finally, create a Switchboard feed that calculates the 1min TWAP of each source above and returns the median of the results
This is just a small window into how Switchboard feeds can build on each other and let the downstream consumer configure their feeds to meet their own use cases.
Each data feed has a LeaseContract, which is a pre-funded escrow account to
reward oracles for fulfilling update request. The LeaseContract has a
lease.withdrawAuthority which is the only wallet allowed to
withdraw funds from the lease escrow. Any user is able to contribute to a
LeaseContract and keep the feed updating.
When a new openRound is successfully requested for a data feed, the user who
requested it is transferred
queue.reward tokens from the feeds LeaseContract.
This is to incentivize users and crank turners to keep feeds updating based on a
When a data feed result is accepted on-chain by a batch of oracles, the oracle
rewards, as specified by
queue.reward, are automatically deducted from the
lease.escrow and transferred to an
Update Request Cost
Each data feed update cost can be calculated by the following equation:
Tis the raw token amount in base units (Ex: lamports or satoshis)
+1is to reward the update requester for keeping the feed updating
numSuccessis the number of successful oracle responses, which will always be between
queue.rewardis the queue's set oracle reward
If an update round fails to receive
minOracleResults, only the update
requester receives funds from the lease escrow.
A feed can set an
aggregator.varianceThreshold to instruct an oracle to skip
reporting a value on-chain if the percentage change between the current result
aggregator.previousConfirmedRoundResult is not exceeded. This is a
cost saving tool to conserve lease cost during low volatility.
aggregator.forceReportPeriod is the compliment and instructs an oracle
to always report a result if
aggregator.forceReportPeriod seconds have elapsed
since the last successful confirmed round. This can be thought of as the maximum
allowable staleness for a feed.
The two settings above can greatly increase the lifespan of a feed's lease but also makes it difficult to estimate the remaining time on a lease.
The following highlights some basic maintenance you should employ when creating your own Switchboard feed.
- Monitor Lease Funds — you should monitor your feeds lease account for low balances. When a feed’s lease is emptied, it will no longer process new updates until it has enough to reward the oracles processing the update. We are working with a few web3 messaging services to enable wallet notifications when leases are low on funds.
- Monitor Crank Eviction — if a lease is emptied, it will also be evicted
from its crank. Switchboard feeds act like public utilities where anyone is
free to re-push it to a crank, as long as it doesn’t have
aggregator.disableCrankset to true.
- Monitor Data Sources — Sometimes APIs change or move. High availability feeds should have some basic routine health checks to ensure their on-chain data is updating as expected.
- Monitor Priority Fees - Solana data feeds may specify a priority fee configuration in order to push updates through during periods of congestion. You should monitor the average priority fee for the network and update as needed.