Skip to content

Commit 1ab1f21

Browse files
committed
Add docs
1 parent f1af65a commit 1ab1f21

File tree

1 file changed

+269
-2
lines changed

1 file changed

+269
-2
lines changed

docs/ecosystem/defi-liquidity/band-oracle.md

Lines changed: 269 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,273 @@ sidebar_position: 6
1616
sidebar_label: Band Oracle
1717
---
1818

19-
# Band Oracle on Flow
19+
# Band Oracle with Cadence
2020

21-
[Band Protocol](https://bandprotocol.com/) is a cross-chain data oracle platform that aggregates and connects real-world data and APIs to smart contracts. Band Oracle on Flow provides secure, reliable, and decentralized price feeds for DeFi applications.
21+
The Band Protocol Oracle contract enables Flow blockchain applications to access real-time price data from the [Band Protocol Oracle network](https://faq.bandprotocol.com/). The oracle provides a comprehensive set of cryptocurrency and fiat currency price quotes from the Band Standard Dataset, making them available to any Cadence application, contract, or transaction.
22+
23+
## Contract Addresses
24+
25+
| Network | Address | Contract Browser |
26+
|---------|---------|------------------|
27+
| Testnet | `0x2c71de7af78d1adf` | [View Contract](https://contractbrowser.com/A.2c71de7af78d1adf.BandOracle) |
28+
| Mainnet | `0x9fb6606c300b5051` | [View Contract](https://contractbrowser.com/A.9fb6606c300b5051.BandOracle) |
29+
30+
## Supported Symbols
31+
32+
### Cryptocurrency Pairs (against USD)
33+
- **Major**: ETH, FLOW, USDC, USDT, WBTC, BNB, XRP, ADA, DOGE, POL (MATIC)
34+
- **Layer 1**: SOL, DOT, AVAX, ATOM, XLM, TRX, SUI
35+
- **DeFi**: AAVE, LINK, CRV, OP, UNI, SUSHI, CAKE, DYDX, 1INCH, BAT
36+
- **Others**: LTC, SHIB, DAI, FTM
37+
38+
### Fiat Currency Pairs (against USD)
39+
- **Asian**: KRW, INR, HKD, TWD, THB, JPY, MYR, PHP, CNY, SGD
40+
- **European**: PLN, CZK, EUR, GBP, CHF, RUB, SEK, TRY
41+
- **Americas**: BRL, CAD
42+
- **Oceanic**: AUD, NZD
43+
44+
## How It Works
45+
46+
### Architecture
47+
48+
The Band Oracle contract maintains a decentralized price feed system with three key components:
49+
50+
1. **Data Storage**: Price data is stored in a contract-level dictionary `symbolsRefData: {String: RefData}` where each symbol maps to its latest price information.
51+
52+
2. **Data Updates**: Authorized BandChain relayers continuously update price data from the Band Protocol network to keep prices current.
53+
54+
3. **Data Access**: Any user or contract can query the latest price data through public functions, enabling real-time price integrations.
55+
56+
### Data Structure
57+
58+
Price data is stored using the `RefData` struct:
59+
60+
```cadence
61+
pub struct RefData {
62+
// USD-rate, multiplied by 1e9
63+
pub var rate: UInt64
64+
// UNIX epoch when data was last resolved
65+
pub var timestamp: UInt64
66+
// BandChain request identifier for this data
67+
pub var requestID: UInt64
68+
}
69+
```
70+
71+
When querying prices, you receive a `ReferenceData` struct:
72+
73+
```cadence
74+
pub struct ReferenceData {
75+
// Rate as integer multiplied by 1e18
76+
pub var integerE18Rate: UInt256
77+
// Rate as a fixed-point decimal
78+
pub var fixedPointRate: UFix64
79+
// Timestamp of base symbol data
80+
pub var baseTimestamp: UInt64
81+
// Timestamp of quote symbol data
82+
pub var quoteTimestamp: UInt64
83+
}
84+
```
85+
86+
### Data Normalization
87+
88+
All price data is stored with a USD conversion rate. When you query for price conversions between two non-USD symbols, the contract derives the rate from their respective USD rates. For example, to get ETH/EUR, the contract calculates: `(ETH/USD) / (EUR/USD)`.
89+
90+
## Features
91+
92+
### Price Queries
93+
- Query any supported symbol pair in real-time
94+
- Get both integer (e18 precision) and fixed-point decimal rates
95+
- Access timestamp information to verify data freshness
96+
- Track BandChain request IDs for transparency
97+
98+
### Fee Structure
99+
- Configurable fee system for oracle usage (currently set to zero)
100+
- Fee collected in FLOW tokens
101+
- Query current fee using `BandOracle.getFee()`
102+
103+
### Event Monitoring
104+
The contract emits events to notify applications of updates:
105+
106+
```cadence
107+
// Emitted when symbol prices are updated
108+
pub event BandOracleSymbolsUpdated(
109+
symbols: [String],
110+
relayerID: UInt64,
111+
requestID: UInt64
112+
)
113+
114+
// Emitted when a symbol is removed
115+
pub event BandOracleSymbolRemoved(symbol: String)
116+
```
117+
118+
## Usage Guide
119+
120+
### Basic Price Query (Transaction)
121+
122+
To query price data from a transaction:
123+
124+
```cadence
125+
import "BandOracle"
126+
import "FlowToken"
127+
import "FungibleToken"
128+
129+
transaction(baseSymbol: String, quoteSymbol: String) {
130+
131+
let payment: @{FungibleToken.Vault}
132+
133+
prepare(acct: auth(BorrowValue) &Account) {
134+
// Borrow reference to user's FLOW vault
135+
let vaultRef = acct.storage.borrow<auth(FungibleToken.Withdraw) &FlowToken.Vault>(
136+
from: /storage/flowTokenVault
137+
) ?? panic("Cannot borrow reference to signer's FLOW vault")
138+
139+
// Withdraw payment for oracle fee
140+
self.payment <- vaultRef.withdraw(amount: BandOracle.getFee())
141+
}
142+
143+
execute {
144+
// Get reference data
145+
let priceData = BandOracle.getReferenceData(
146+
baseSymbol: baseSymbol,
147+
quoteSymbol: quoteSymbol,
148+
payment: <- self.payment
149+
)
150+
151+
log("Rate (fixed-point): ".concat(priceData.fixedPointRate.toString()))
152+
log("Rate (integer e18): ".concat(priceData.integerE18Rate.toString()))
153+
log("Base timestamp: ".concat(priceData.baseTimestamp.toString()))
154+
log("Quote timestamp: ".concat(priceData.quoteTimestamp.toString()))
155+
}
156+
}
157+
```
158+
159+
### Example: ETH/USD Price
160+
```cadence
161+
// Get ETH price in USD
162+
let priceData = BandOracle.getReferenceData(
163+
baseSymbol: "ETH",
164+
quoteSymbol: "USD",
165+
payment: <- flowPayment
166+
)
167+
// priceData.fixedPointRate contains ETH price in USD
168+
```
169+
170+
### Example: Cross-Currency Conversion
171+
```cadence
172+
// Get EUR price in JPY
173+
let priceData = BandOracle.getReferenceData(
174+
baseSymbol: "EUR",
175+
quoteSymbol: "JPY",
176+
payment: <- flowPayment
177+
)
178+
// priceData.fixedPointRate contains EUR/JPY exchange rate
179+
```
180+
181+
### Contract Integration
182+
183+
Here's how to integrate the oracle into your smart contract:
184+
185+
```cadence
186+
import "BandOracle"
187+
import "FlowToken"
188+
import "FungibleToken"
189+
190+
pub contract MyDeFiContract {
191+
192+
// Store a vault to pay for oracle fees
193+
access(self) let oracleFeeVault: @{FungibleToken.Vault}
194+
195+
pub fun getTokenPriceInUSD(tokenSymbol: String): UFix64 {
196+
// Withdraw payment for oracle
197+
let payment <- self.oracleFeeVault.withdraw(
198+
amount: BandOracle.getFee()
199+
)
200+
201+
// Query the oracle
202+
let priceData = BandOracle.getReferenceData(
203+
baseSymbol: tokenSymbol,
204+
quoteSymbol: "USD",
205+
payment: <- payment
206+
)
207+
208+
return priceData.fixedPointRate
209+
}
210+
211+
pub fun swapTokens(amount: UFix64, maxPrice: UFix64) {
212+
// Get current price
213+
let currentPrice = self.getTokenPriceInUSD(tokenSymbol: "ETH")
214+
215+
// Verify price is acceptable
216+
if currentPrice > maxPrice {
217+
panic("Price too high")
218+
}
219+
220+
// Proceed with swap logic...
221+
}
222+
223+
init() {
224+
// Initialize vault for oracle fees
225+
self.oracleFeeVault <- FlowToken.createEmptyVault(
226+
vaultType: Type<@FlowToken.Vault>()
227+
)
228+
}
229+
}
230+
```
231+
232+
## Best Practices
233+
234+
### 1. Listen for Price Updates
235+
236+
Monitor the `BandOracleSymbolsUpdated` event to keep your contract's stored prices up-to-date:
237+
238+
```cadence
239+
// Listen for this event in your application
240+
pub event BandOracleSymbolsUpdated(
241+
symbols: [String],
242+
relayerID: UInt64,
243+
requestID: UInt64
244+
)
245+
```
246+
247+
When you detect an update for symbols your dapp uses, trigger a transaction to refresh your stored prices.
248+
249+
250+
## Advanced Features
251+
252+
### Converting Between Number Formats
253+
254+
The contract provides a utility function to convert between integer and fixed-point representations:
255+
256+
```cadence
257+
// Convert e18 integer to fixed-point decimal
258+
let fixedPoint = BandOracle.e18ToFixedPoint(rate: integerE18Rate)
259+
```
260+
261+
### Fee Management
262+
263+
For contract administrators, the oracle supports dynamic fee configuration:
264+
265+
```cadence
266+
// Query current fee
267+
let currentFee = BandOracle.getFee()
268+
269+
// Fee can be updated by the fee collector (admin only)
270+
// feeCollector.setFee(fee: 0.001) // 0.001 FLOW per query
271+
```
272+
273+
## Resources
274+
275+
- [Band Protocol FAQ](https://faq.bandprotocol.com/)
276+
- [Band Standard Dataset](https://data.bandprotocol.com/)
277+
- [Flow Documentation](https://docs.onflow.org/)
278+
- [Cadence Language Reference](https://cadence-lang.org/)
279+
280+
## Support
281+
282+
For issues or questions about the Band Oracle on Flow:
283+
- Check the Band Protocol documentation
284+
- Engage with the Flow developer community
285+
286+
---
287+
288+
**Note**: The oracle currently charges no fees for usage, but this may change in the future. Always check `BandOracle.getFee()` before querying to ensure your contract has sufficient FLOW tokens allocated.

0 commit comments

Comments
 (0)