Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
*.pkey
*.pem
coverage.lcov
coverage.json
coverage.json
imports/
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Band Oracle Contract
The Cadence smart contract enabling integration of the Band Protocol Oracle network. The oracle network presently offers the full set of [price quotes](https://data.bandprotocol.com/) from the Band Standard Dataset. These are available for any Cadence applications, contracts or transactions to use and presently charges no fees.
The Cadence smart contract enabling integration of the Band Protocol Oracle network. The oracle network presently offers
the full set of [price quotes](https://data.bandprotocol.com/) from the Band Standard Dataset. These are available for
any Cadence applications, contracts or transactions to use and presently charges no fees.

Currently supported cryptocurrency token pairs are:

Expand Down Expand Up @@ -29,27 +31,41 @@ To learn more about Band Protocol please refer to: https://faq.bandprotocol.com/
|[BandOracle](contracts/BandOracle.cdc)|[]()|[0x9fb6606c300b5051](https://contractbrowser.com/A.9fb6606c300b5051.BandOracle)|

## How it works?
The contract keeps a record of symbols and the corresponding financial price data for them. While financial data are only updated by authorized BandChain relayers, they can be queried via a script by any user or application on the Flow blockchain.
The contract keeps a record of symbols and the corresponding financial price data for them. While financial data are
only updated by authorized BandChain relayers, they can be queried via a script by any user or application on the Flow
blockchain.

### Storing the data
Market for each symbol is stored on a dictionary as a contract level field `access(contract) let symbolsRefData: {String: RefData}`. The `RefData` structs stores the following information:
Market for each symbol is stored on a dictionary as a contract level field `access(contract) let symbolsRefData:
{String: RefData}`. The `RefData` structs stores the following information:
```cadence
pub struct RefData {
access(all) struct RefData {
// USD-rate, multiplied by 1e9.
pub var rate: UInt64
access(all) var rate: UInt64
// UNIX epoch when data is last resolved.
pub var timestamp: UInt64
access(all) var timestamp: UInt64
// BandChain request identifier for this data.
pub var requestID: UInt64
access(all) var requestID: UInt64
}
```
This struct provides the caller with the data received from the oracle network for the symbol in question. Keep in mind that all data is normalized and stored using a USD conversion rate, meaning that conversions into other symbols will derive from that.
This struct provides the caller with the data received from the oracle network for the symbol in question. Keep in mind
that all data is normalized and stored using a USD conversion rate, meaning that conversions into other symbols will
derive from that.

### Updating the data
The account where the contract is deployed will be granted an `OracleAdmin` resource. This resource can create `DataUpdater` resources and publish a `{&RelayUpdate}` capability to them. An authorized account - belonging to a relayer - can claim said capability at the time of creating a `Relay` resource. This resource will grant the ability to call the `updateData` method that will call contract function `access(contract) fun updateRefData (symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64)` which in turn updates the `symbolsRefData` dictionary.

The account where the contract is deployed will be granted an `OracleAdmin` resource. This resource can create
`DataUpdater` resources and publish a `{&RelayUpdate}` capability to them. An authorized account - belonging to a
relayer - can claim said capability at the time of creating a `Relay` resource. This resource will grant the ability to
call the `updateData` method that will call contract function `access(contract) fun updateRefData (symbolsRates:
{String: UInt64}, resolveTime: UInt64, requestID: UInt64)` which in turn updates the `symbolsRefData` dictionary.

### Querying the data
When invoking the public function `pub fun getReferenceData (baseSymbol: String, quoteSymbol: String): RefData?` calling contracts or scripts would be provided the price corresponding to `quoteSymbol` in the `baseSymbol` currency. If there are no entries registered for either the base or quote symbols the function will return `nil`.

When invoking the public function `access(all) fun getReferenceData(baseSymbol: String, quoteSymbol: String, payment:
@{FungibleToken.Vault}): RefData?` where `payment` contains the balance of `BandOracle.getFee()`. Callers are provided
the price corresponding to `quoteSymbol` in the `baseSymbol` currency. If there are no entries registered for either the
base or quote symbols the function will return `nil`.

### Fees

Expand Down
86 changes: 52 additions & 34 deletions docs/BandOracle.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Contract `BandOracle`

```cadence
pub contract BandOracle {
access(all) contract BandOracle {

pub let OracleAdminStoragePath: StoragePath
access(all) let OracleAdminStoragePath: StoragePath

pub let OracleAdminPrivatePath: PrivatePath
access(all) let OracleAdminPrivatePath: PrivatePath

pub let RelayStoragePath: StoragePath
access(all) let RelayStoragePath: StoragePath

pub let RelayPrivatePath: PrivatePath
access(all) let RelayPrivatePath: PrivatePath

pub let FeeCollectorStoragePath: StoragePath
access(all) let FeeCollectorStoragePath: StoragePath

access(contract) let dataUpdaterPrivateBasePath: String

access(contract) let symbolsRefData: {String: RefData}

pub let e18: UInt256
access(all) let e18: UInt256

pub let e9: UInt256
access(all) let e9: UInt256

access(contract) let payments: FungibleToken.Vault

Expand All @@ -34,7 +34,7 @@ https://docs.bandchain.org/
### `OracleAdmin`

```cadence
pub resource interface OracleAdmin {
access(all) resource interface OracleAdmin {
}
```
Resources
Expand All @@ -47,7 +47,7 @@ Admin only operations.
### `DataUpdater`

```cadence
pub resource interface DataUpdater {
access(all) resource interface DataUpdater {
}
```
Relayer operations.
Expand All @@ -60,13 +60,13 @@ Relayer operations.
### `RefData`

```cadence
pub struct RefData {
access(all) struct RefData {

pub var rate: UInt64
access(all) var rate: UInt64

pub var timestamp: UInt64
access(all) var timestamp: UInt64

pub var requestID: UInt64
access(all) var requestID: UInt64
}
```
Structs
Expand All @@ -79,15 +79,15 @@ Structure for storing any symbol USD-rate.
### `ReferenceData`

```cadence
pub struct ReferenceData {
access(all) struct ReferenceData {

pub var integerE18Rate: UInt256
access(all) var integerE18Rate: UInt256

pub var fixedPointRate: UFix64
access(all) var fixedPointRate: UFix64

pub var baseTimestamp: UInt64
access(all) var baseTimestamp: UInt64

pub var quoteTimestamp: UInt64
access(all) var quoteTimestamp: UInt64
}
```
Structure for consuming data as quote / base symbols.
Expand All @@ -99,7 +99,7 @@ Structure for consuming data as quote / base symbols.
### `BandOracleAdmin`

```cadence
pub resource BandOracleAdmin {
access(all) resource BandOracleAdmin {
}
```
The `BandOracleAdmin` will be created on the contract deployment, and will allow
Expand All @@ -112,7 +112,7 @@ the own admin to manage the oracle and the relayers to update prices on it.
### `Relay`

```cadence
pub resource Relay {
access(all) resource Relay {

priv let updaterCapability: Capability<&{DataUpdater}>
}
Expand All @@ -126,7 +126,7 @@ The resource that will allow an account to make quote updates
### `FeeCollector`

```cadence
pub resource FeeCollector {
access(all) resource FeeCollector {
}
```
The resource that allows the maintainer account to charge a fee for the use of the oracle.
Expand All @@ -139,7 +139,12 @@ The resource that allows the maintainer account to charge a fee for the use of t
### `updateRefData()`

```cadence
fun updateRefData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
access(contract) fun updateRefData(
symbolsRates: {String: UInt64},
resolveTime: UInt64,
requestID: UInt64,
relayerID: UInt64
)
```
Functions
Aux access(contract) functions
Expand All @@ -156,7 +161,12 @@ Parameters:
### `forceUpdateRefData()`

```cadence
fun forceUpdateRefData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
access(contract) fun forceUpdateRefData(
symbolsRates: {String: UInt64},
resolveTime: UInt64,
requestID: UInt64,
relayerID: UInt64
)
```
Auxiliary private function for the `OracleAdmin` to force update the rates.

Expand All @@ -171,7 +181,7 @@ Parameters:
### `removeSymbol()`

```cadence
fun removeSymbol(symbol: String)
access(contract) fun removeSymbol(symbol: String)
```
Auxiliary private function for removing a stored symbol

Expand All @@ -183,7 +193,7 @@ Parameters:
### `_getRefData()`

```cadence
fun _getRefData(symbol: String): RefData?
access(contract) fun _getRefData(symbol: String): RefData?
```
Auxiliary private function for checking and retrieving data for a given symbol.

Expand All @@ -197,7 +207,7 @@ Returns: Optional `RefData` struct if there is any quote stored for the requeste
### `calculateReferenceData()`

```cadence
fun calculateReferenceData(baseRefData: RefData, quoteRefData: RefData): ReferenceData
access(contract) fun calculateReferenceData(baseRefData: RefData, quoteRefData: RefData): ReferenceData
```
Private function that calculates the reference data between two base and quote symbols.

Expand All @@ -224,7 +234,7 @@ Parameters:
### `collectFees()`

```cadence
fun collectFees(): FungibleToken.Vault
access(all) fun collectFees(): FungibleToken.Vault
```
Private method for the `FeeCollector` to be able to collect the fees from the contract vault.

Expand All @@ -235,7 +245,7 @@ Returns: A flow token vault with the collected fees so far.
### `createRelay()`

```cadence
fun createRelay(updaterCapability: Capability<&{DataUpdater}>): Relay
access(all) fun createRelay(updaterCapability: Capability<&{DataUpdater}>): Relay
```
Public access functions.
Public method for creating a relay and become a relayer.
Expand All @@ -250,7 +260,7 @@ Returns: The new relay resource.
### `getUpdaterCapabilityNameFromAddress()`

```cadence
fun getUpdaterCapabilityNameFromAddress(relayer: Address): String
access(all) view fun getUpdaterCapabilityNameFromAddress(relayer: Address): String
```
Auxiliary method to ensure that the formation of the capability name that
identifies data updater capability for relayers is done in a uniform way
Expand All @@ -277,7 +287,11 @@ Returns: The fee to be charged for every request made to the oracle.
### `getReferenceData()`

```cadence
fun getReferenceData(baseSymbol: String, quoteSymbol: String, payment: FungibleToken.Vault): ReferenceData
access(all) fun getReferenceData(
baseSymbol: String,
quoteSymbol: String,
payment: @{FungibleToken.Vault}
): ReferenceData
```
The entry point for consumers to query the oracle in exchange of a fee.

Expand All @@ -293,7 +307,7 @@ Returns: The `ReferenceData` containing the requested data.
### `e18ToFixedPoint()`

```cadence
fun e18ToFixedPoint(rate: UInt256): UFix64
access(all) view fun e18ToFixedPoint(rate: UInt256): UFix64
```
Turn scientific notation numbers as `UInt256` multiplied by e8 into `UFix64`
fixed point numbers. Exceptionally large integer rates may lose some precision
Expand All @@ -310,15 +324,19 @@ Returns: The symbol rate as a decimal.
### `BandOracleSymbolsUpdated`

```cadence
pub event BandOracleSymbolsUpdated(symbols: [String], relayerID: UInt64, requestID: UInt64)
access(all) event BandOracleSymbolsUpdated(
symbols: [String],
relayerID: UInt64,
requestID: UInt64
)
```

---

### `BandOracleSymbolRemoved`

```cadence
pub event BandOracleSymbolRemoved(symbol: String)
access(all) event BandOracleSymbolRemoved(symbol: String)
```

---
12 changes: 6 additions & 6 deletions docs/BandOracle_BandOracleAdmin.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Resource `BandOracleAdmin`

```cadence
pub resource BandOracleAdmin {
access(all) resource BandOracleAdmin {
}
```

Expand All @@ -17,7 +17,7 @@ Implemented Interfaces:
### `getUpdaterCapabilityPathFromAddress()`

```cadence
fun getUpdaterCapabilityPathFromAddress(relayer: Address): PrivatePath
access(all) fun getUpdaterCapabilityPathFromAddress(relayer: Address): PrivatePath
```
Auxiliary method to ensure that the formation of the capability path that
identifies relayers is done in a uniform way.
Expand All @@ -30,7 +30,7 @@ Parameters:
### `removeSymbol()`

```cadence
fun removeSymbol(symbol: String)
access(all) fun removeSymbol(symbol: String)
```
Removes a symbol and its quotes from the contract storage.

Expand All @@ -42,7 +42,7 @@ Parameters:
### `updateData()`

```cadence
fun updateData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
access(all) fun updateData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
```
Relayers can call this method to update rates.

Expand All @@ -57,7 +57,7 @@ Parameters:
### `forceUpdateData()`

```cadence
fun forceUpdateData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
access(all) fun forceUpdateData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64, relayerID: UInt64)
```
Relayers can call this method to force update rates.

Expand All @@ -72,7 +72,7 @@ Parameters:
### `createNewFeeCollector()`

```cadence
fun createNewFeeCollector(): FeeCollector
access(all) fun createNewFeeCollector(): FeeCollector
```
Creates a fee collector, meant to be called once after contract deployment
for storing the resource on the maintainer's account.
Expand Down
Loading