# Oracle Price Tick

StarkEx for perpetual trading uses external Oracle price feeds in order to take the most recent prices into account in the business logic. Here we describe the process that a new price goes through. The process starts when the application gets price updates signed by the price Oracles. Then the application aggregates the signed prices and sends them to StarkEx as an Oracle Price Tick request. StarkEx checks the validity of the request and finally includes the new prices in a batch.

 If you are interested in the soundness of the Oracle prices, we recommend reading up on the on-chain configuration. This contains further information about who is authorized to sign a new price and what the required number of signatures are.

## Step 1: The Application Collects Signatures on a Price

Oracle providers that are registered in the system (check this page for details regarding registration), sign on a price update of an `assetId.` This update is represented by the following tuple,`(price, time, name)`, where `price` represents the new price, `time` is the timestamp of the update and `name` is a unique identifier of the `assetId` and oracle identity. For more details on how to generate price feeds, read here.

The application aggregates these signatures, and sends to StarkEx an Oracle Price Tick transaction, that includes the following:

• The new `system_time`

• A list of `assetId` for which the price is updated.

• For each `assetId` in the list, it sends a list of `(price, time, name, sig)` as well as `current_price` that will be de-facto used by StarkEx for the next transactions.

## Step 2: Prices are Included in the Batch and StarkEx Verifies the Batch

StarkEx does not explicitly prove the validity of all Oracle signatures in all the Oracle Price Ticks, since it is not efficient. Instead, it uses a hybrid approach. StarkEx includes in the batch header, for each `assetId`, the entire quorum of signatures that attests to the minimal and maximal prices in a batch. For the rest of the prices, StarkEx only proves that they are between the minimal and maximal price.

 Since the application can already play with the order of transaction and/or mix and match different signatures from different legitimate oracle sources to create a variety of possible medians, this optimization doesn’t reduce the security of the system.

We proceed to describe two phases of batch verification. The first phase is performed on the full batch and the second phase is performed per an Oracle Price Tick transaction.

• The price is the median of the list $(price_1,\dots, price_n)$

• $n \geq \text{config\[assetId].quorum}$

• For each tuple$i \in \{1,...,n\}$

• $sig_i$is a valid signature with a unique public key $pk_i$from the list `config[assetId].keys` , on the tuple $(price_i,time_i, name_i)$

• $name_i$appears in the list `config[assetId].names`

• Each value in the list$(time_1,\dots, time_n)$ is in a `price_validity_period`-hours window. Furthermore, $\min(time_1,\dots, time_n)$is at least`batch_starting_time - price_validity_period` and $\max (time_1,\dots, time_n)$is at most `batch_end_time`.

### Phase 1: StarkEx Verifies the Batch’s Minimal and Maximal Price

For each `assetId` (including assets that didn’t receive an update in this batch), StarkEx verifies the `minimal_price` and `maximal_price`. This is done by verifying the following conditions for the Oracle Price Tick that attests to each of them. Bear in mind that an Oracle Price Tick contains a list of $n$ tuples$(price_i,time_i, name_i, sig_i)$.

• The price is the median of the list$(price_1,\dots, price_n)$

• $n \geq \text{config\[assetId].quorum}$

• For each tuple$i \in \{1,...,n\}$

• $sig_i$is a valid signature with a unique public key $pk_i$from the list `config[assetId].keys` , on the tuple $(price_i,time_i, name_i)$

• $name_i$appears in the list `config[assetId].names`

• Each value in the list$(time_1,\dots, time_n)$ is in a 24-hours window. Furthermore, $\min(time_1,\dots, time_n)$is at least one day less than`batch_starting_time` and $\max (time_1,\dots, time_n)$is at most `batch_end_time`.

### Phase 2: StarkEx Verifies the Validity of each Oracle Price Tick Separately

For each Oracle Price Tick in the batch, StarkEx verifies the following conditions:

• `system_time >= prev system_time`

• For every `assetId:`

• `current_price`is bigger than or equals the `minimal_price` of this batch

• `current_price`is smaller than or equals the `maximal_price` of this batch