diff --git a/.gitignore b/.gitignore index 169b409..5e40fb2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.pkey *.pem coverage.lcov -coverage.json \ No newline at end of file +coverage.json +imports/ \ No newline at end of file diff --git a/README.md b/README.md index 7e571a5..d7080b8 100644 --- a/README.md +++ b/README.md @@ -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: @@ -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 diff --git a/docs/BandOracle.md b/docs/BandOracle.md index 557c558..8a77e1c 100644 --- a/docs/BandOracle.md +++ b/docs/BandOracle.md @@ -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 @@ -34,7 +34,7 @@ https://docs.bandchain.org/ ### `OracleAdmin` ```cadence -pub resource interface OracleAdmin { +access(all) resource interface OracleAdmin { } ``` Resources @@ -47,7 +47,7 @@ Admin only operations. ### `DataUpdater` ```cadence -pub resource interface DataUpdater { +access(all) resource interface DataUpdater { } ``` Relayer operations. @@ -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 @@ -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. @@ -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 @@ -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}> } @@ -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. @@ -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 @@ -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. @@ -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 @@ -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. @@ -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. @@ -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. @@ -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. @@ -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 @@ -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. @@ -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 @@ -310,7 +324,11 @@ 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 +) ``` --- @@ -318,7 +336,7 @@ pub event BandOracleSymbolsUpdated(symbols: [String], relayerID: UInt64, request ### `BandOracleSymbolRemoved` ```cadence -pub event BandOracleSymbolRemoved(symbol: String) +access(all) event BandOracleSymbolRemoved(symbol: String) ``` --- diff --git a/docs/BandOracle_BandOracleAdmin.md b/docs/BandOracle_BandOracleAdmin.md index c6c158f..98a997d 100644 --- a/docs/BandOracle_BandOracleAdmin.md +++ b/docs/BandOracle_BandOracleAdmin.md @@ -1,7 +1,7 @@ # Resource `BandOracleAdmin` ```cadence -pub resource BandOracleAdmin { +access(all) resource BandOracleAdmin { } ``` @@ -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. @@ -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. @@ -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. @@ -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. @@ -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. diff --git a/docs/BandOracle_DataUpdater.md b/docs/BandOracle_DataUpdater.md index c1a87eb..3251046 100644 --- a/docs/BandOracle_DataUpdater.md +++ b/docs/BandOracle_DataUpdater.md @@ -1,7 +1,7 @@ # Resource Interface `DataUpdater` ```cadence -pub resource interface DataUpdater { +access(all) resource interface DataUpdater { } ``` @@ -11,7 +11,12 @@ Relayer operations. ### `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 +) ``` --- @@ -19,7 +24,12 @@ fun updateData(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: U ### `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 +) ``` --- diff --git a/docs/BandOracle_FeeCollector.md b/docs/BandOracle_FeeCollector.md index e940506..f2ee373 100644 --- a/docs/BandOracle_FeeCollector.md +++ b/docs/BandOracle_FeeCollector.md @@ -1,7 +1,7 @@ # Resource `FeeCollector` ```cadence -pub resource FeeCollector { +access(all) resource FeeCollector { } ``` @@ -11,7 +11,7 @@ The resource that allows the maintainer account to charge a fee for the use of t ### `setFee()` ```cadence -fun setFee(fee: UFix64) +access(all) fun setFee(fee: UFix64) ``` Sets the fee in Flow tokens for the oracle use. @@ -23,7 +23,7 @@ Parameters: ### `collectFees()` ```cadence -fun collectFees(): FungibleToken.Vault +access(all) fun collectFees(): FungibleToken.Vault ``` Extracts the fees from the contract's vault. diff --git a/docs/BandOracle_OracleAdmin.md b/docs/BandOracle_OracleAdmin.md index 3d4de28..94dcc3a 100644 --- a/docs/BandOracle_OracleAdmin.md +++ b/docs/BandOracle_OracleAdmin.md @@ -1,7 +1,7 @@ # Resource Interface `OracleAdmin` ```cadence -pub resource interface OracleAdmin { +access(all) resource interface OracleAdmin { } ``` @@ -9,10 +9,26 @@ Resources Admin only operations. ## Functions -### `getUpdaterCapabilityPathFromAddress()` +### `setRelayerCapabilityID()` ```cadence -fun getUpdaterCapabilityPathFromAddress(relayer: Address): PrivatePath +access(all) fun setRelayerCapabilityID(relayer: Address, capabilityID: UInt64) +``` + +--- + +### `removeRelayerCapabilityID()` + +```cadence +access(all) fun removeRelayerCapabilityID(relayer: Address) +``` + +--- + +### `getUpdaterCapabilityIDFromAddress()` + +```cadence +access(all) fun getUpdaterCapabilityIDFromAddress(relayer: Address): UInt64? ``` --- @@ -20,7 +36,7 @@ fun getUpdaterCapabilityPathFromAddress(relayer: Address): PrivatePath ### `removeSymbol()` ```cadence -fun removeSymbol(symbol: String) +access(all) fun removeSymbol(symbol: String) ``` --- @@ -28,7 +44,7 @@ fun removeSymbol(symbol: String) ### `createNewFeeCollector()` ```cadence -fun createNewFeeCollector(): BandOracle.FeeCollector +access(all) fun createNewFeeCollector(): BandOracle.FeeCollector ``` --- diff --git a/docs/BandOracle_RefData.md b/docs/BandOracle_RefData.md index 7c801c6..194bd59 100644 --- a/docs/BandOracle_RefData.md +++ b/docs/BandOracle_RefData.md @@ -1,13 +1,13 @@ # Struct `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 } ``` diff --git a/docs/BandOracle_ReferenceData.md b/docs/BandOracle_ReferenceData.md index b7d4c72..b69527e 100644 --- a/docs/BandOracle_ReferenceData.md +++ b/docs/BandOracle_ReferenceData.md @@ -1,15 +1,15 @@ # Struct `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 } ``` diff --git a/docs/BandOracle_Relay.md b/docs/BandOracle_Relay.md index 2016a36..3287505 100644 --- a/docs/BandOracle_Relay.md +++ b/docs/BandOracle_Relay.md @@ -1,7 +1,7 @@ # Resource `Relay` ```cadence -pub resource Relay { +access(all) resource Relay { priv let updaterCapability: Capability<&{DataUpdater}> } @@ -21,7 +21,7 @@ init(updaterCapability: Capability<&{DataUpdater}>) ### `relayRates()` ```cadence -fun relayRates(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64) +access(all) fun relayRates(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64) ``` Relay updated rates to the Oracle Admin @@ -35,7 +35,7 @@ Parameters: ### `forceRelayRates()` ```cadence -fun forceRelayRates(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64) +access(all) fun forceRelayRates(symbolsRates: {String: UInt64}, resolveTime: UInt64, requestID: UInt64) ``` Relay updated rates to the Oracle Admin forcing the update of the symbols even if the `resolveTime` is older than the last update. diff --git a/flow.json b/flow.json index 011409e..37bb8d1 100644 --- a/flow.json +++ b/flow.json @@ -14,6 +14,8 @@ "source": "testnet://9a0766d93b6608b7.Burner", "hash": "71af18e227984cd434a3ad00bb2f3618b76482842bae920ee55662c37c8bf331", "aliases": { + "emulator": "f8d6e0586b0a20c7", + "mainnet": "f233dcee88fe0abe", "testnet": "9a0766d93b6608b7" } }, @@ -23,47 +25,42 @@ "aliases": { "emulator": "0ae53cb6e3f42a79", "mainnet": "1654653399040a61", - "previewnet": "4445e7ad11568276", "testnet": "7e60df042a9c0868" } }, "FungibleToken": { "source": "testnet://9a0766d93b6608b7.FungibleToken", - "hash": "154d9000cc0b992664c1d315826a4bc47e744fbc7f2e99daf823e5101945042a", + "hash": "d84e41a86bd27806367b89c75a2a9570f7713480ab113cc214c4576466888958", "aliases": { "emulator": "ee82856bf20e2aa6", "mainnet": "f233dcee88fe0abe", - "previewnet": "a0225e7000ac82a9", "testnet": "9a0766d93b6608b7" } }, "FungibleTokenMetadataViews": { "source": "testnet://9a0766d93b6608b7.FungibleTokenMetadataViews", - "hash": "64ec97395c0a3958510ea663563f59d5a6beb7943d69b903db94c11d76be6296", + "hash": "085d02742eb50e6200cf2a4ad4551857313513afa7205c1e85f5966547a56df3", "aliases": { "emulator": "ee82856bf20e2aa6", "mainnet": "f233dcee88fe0abe", - "previewnet": "a0225e7000ac82a9", "testnet": "9a0766d93b6608b7" } }, "MetadataViews": { "source": "testnet://631e88ae7f1d7c20.MetadataViews", - "hash": "77e2c3c4afb855af657ecae6611a99acf47a102144c68f4663de42ae700adf5b", + "hash": "0b746cabba668c39de9dc47b94fc458f4119cbabb6883616e4a8750518310ccb", "aliases": { "emulator": "f8d6e0586b0a20c7", "mainnet": "1d7e57aa55817448", - "previewnet": "b6763b4399a888c8", "testnet": "631e88ae7f1d7c20" } }, "NonFungibleToken": { "source": "testnet://631e88ae7f1d7c20.NonFungibleToken", - "hash": "ea1b5fa55b6648064c77a6fd83084a3a0be2a6f4386b3b259c89e4f62ab8f6c0", + "hash": "ac40c5a3ec05884ae48cb52ebf680deebb21e8a0143cd7d9b1dc88b0f107e088", "aliases": { "emulator": "f8d6e0586b0a20c7", "mainnet": "1d7e57aa55817448", - "previewnet": "b6763b4399a888c8", "testnet": "631e88ae7f1d7c20" } }, @@ -73,7 +70,6 @@ "aliases": { "emulator": "f8d6e0586b0a20c7", "mainnet": "1d7e57aa55817448", - "previewnet": "b6763b4399a888c8", "testnet": "631e88ae7f1d7c20" } }