Skip to content

Price reporter daemon for the Tellor Layer oracle network

Notifications You must be signed in to change notification settings

tellor-io/layer-daemons

Repository files navigation

Daemon

Note: Daemon services code was adopted from dydx and reconfigured.

Task loops

PriceFetcher

  • Will query exchanges for prices once or multiple times based on wether the api supports single vs multi markets; ie wether an api needs to be queried for each pair individually or can return multiple pairs at once, See here for exchange details.

PriceEncoder

  • Will update cache with the queried prices and encode appropriately also make adjustments as necessary based on if adjustByMarket is defined.

Configuration

Exchange Config default

[[exchanges]]
ExchangeId = "Binance"  // exchange identifier
IntervalMs = 2500  // Delays between sending api requests
TimeoutMs = 3000  // Max timeout
MaxQueries = 1  // Max number of calls in a loop.

Defaults for exchange information can be found here

Market Pair defaults

Defaults for market pair can be found here

example:

[[market_params]]
ExchangeConfigJson = "{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"\\\"ETHBTC\\\"\"},{\"exchangeName\":\"Bitfinex\",\"ticker\":\"tETHBTC\",\"adjustByMarket\":\"BTC-USD\"}]}" // this is just an example to show how to use adjustByMarket.  you can use ETH-USD without adjustbymarket
Exponent = -6
Id = 2
MinExchanges = 1
MinPriceChangePpm = 1000
Pair = "ETH-BTC"
QueryData = "0000.."
type MarketParam struct {
    // Unique, sequentially-generated value.
    Id uint32
    // The human-readable name of the market pair (e.g. `BTC-USD`).
    Pair string
    // Static value. The exponent of the price.
    // For example if `Exponent == -5` then a `Value` of `1,000,000,000`
    // represents “$10,000`. Therefore `10 ^ Exponent` represents the smallest
    // price step (in dollars) that can be recorded.
    Exponent int32
    // The minimum number of exchanges that should be reporting a live price for
    // a price update to be considered valid.
    MinExchanges uint32
    // The minimum allowable change in `price` value that would cause a price
    // update on the network. Measured as `1e-6` (parts per million).
    MinPriceChangePpm uint32
    // A string of json that encodes the configuration for resolving the price
    // of this market on various exchanges.
    ExchangeConfigJson string
    // Query data is the market pair represention in layer
    QueryData string
}

Note: A price is valid by default up to 30 seconds; to change this to a different default edit the constants.MaxPriceAge

Also: Config files are written to homedir/.layer/config/. To change/add exchange details or market pairs edit the files pricefeed_exchange_config.toml or market_params.toml respectively.

Median Server

Median server was added for a way to query median values that were from an endpoint or cli. See usage here. All median values or median value given query data using the following commands respectively. layerd query oracle get-all-median-values layerd query oracle get-median-value <querydata>

How to add a market pair as defaults to be queried with existing APIs Exchange_Details?

const (
    BTCUSD_ID uint32 = 0
    ETHUSD_ID uint32 = 1
    TRBUSD_ID uint32 = 69
    NEWPAIR_ID uint32 = <unique-number>
)
exchange_common.TRBUSD_ID: {
        Id:                 exchange_common.TRBUSD_ID,
        Pair:               `"TRB-USD"`,
        Exponent:           -6,
        MinExchanges:       1,
        MinPriceChangePpm:  1000,
        ExchangeConfigJson: `{\"exchanges\":[{\"exchangeName\":\"Binance\",\"ticker\":\"\\\"TRBUSDT\\\"\"},{\"exchangeName\":\"Bybit\",\"ticker\":\"TRBUSDT\"},{\"exchangeName\":\"CoinbasePro\",\"ticker\":\"TRB-USD\"}]}`,
        QueryData:          `"00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706f745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003747262000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000"`,
    },

Price Guard

The Price Guard is a safety mechanism that prevents the reporter from submitting prices that deviate too significantly from the last reported price.

Flags

Flag Type Description Required (if enabled)
--price-guard-enabled bool Enables the price guard mechanism No
--price-guard-threshold float64 Maximum allowed percentage change (e.g., 0.5 = 50%). Submissions exceeding this change from the last reported price will be blocked. Yes
--price-guard-max-age duration Time after which a stored price is considered expired (e.g., "1h"). If the last price is expired, the new price is accepted regardless of deviation. Yes
--price-guard-update-on-blocked bool If true, updates the internal "last known price" to the new value even if submission was blocked. If false, keeps the old price as the baseline. Yes

Notes

  1. First Submission: Always allowed.
  2. Expired Price: If time since last update > max-age, the new price is accepted and becomes the new baseline.
  3. Deviation Check: Calculates percentage change: abs(new - old) / old.
    • If change > threshold: Submission is BLOCKED.
    • If change <= threshold: Submission is ALLOWED.
  4. Update on Blocked:
    • If true: A blocked price becomes the new baseline for future checks.
    • If false: The old price remains the baseline; future submissions must be within threshold of the old price.

About

Price reporter daemon for the Tellor Layer oracle network

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •