-
Notifications
You must be signed in to change notification settings - Fork 3
Add initial PriceOracle & PriceData interfaces & implementation in BandOracleAdapters #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
102 commits
Select commit
Hold shift + click to select a range
d4fb9e7
initial commit
sisyphusSmiling ac892ac
update .gitignore
sisyphusSmiling 7a0e8c3
remove internal check on path in IncrementSwapStack
sisyphusSmiling 408c303
add initial tests & test helpers
sisyphusSmiling e439cad
update .gitignore
sisyphusSmiling 8adf987
update README & add Makefile
sisyphusSmiling b40fcab
remove Stack resource
sisyphusSmiling 4897e73
remove unused scripts & transactions
sisyphusSmiling 06bc07d
update Source interface
sisyphusSmiling bf5773e
update VaultSource implementation & simplify capacity limits
sisyphusSmiling d28f501
remove non-interface helpers & remove reverting conditionals
sisyphusSmiling ed20566
update SwapSink init parameters & field assignment
sisyphusSmiling f6bad6c
update SwapSink.minimumCapacity() calculation
sisyphusSmiling 1c07071
add contract documentation comments
sisyphusSmiling 77ca5f8
fix FungibleTokenStack deposit & withdraw conditions
sisyphusSmiling 50c78e7
fix & simplify SwapSink.depositCapacity
sisyphusSmiling b3e850f
add entitlement to Source.withdrawAvailable
sisyphusSmiling fdcdf54
add checks to FungibleTokenStack connectors
sisyphusSmiling 9dee7f1
add SwapSource connector to IncrementSwapStack
sisyphusSmiling 631d15b
add type check on SwapSink.depositCapacity
sisyphusSmiling 42731c3
update SwapSource to check balance of vault returned from inner Source
sisyphusSmiling 1a83d8f
fix FungibleTokenStack connector init pre-condition check
sisyphusSmiling 5a2260b
add example VaultSourceAndSink combination connector for consideration
sisyphusSmiling d1fb33f
update VaultSink & VaultSource min & max balance init params as optional
sisyphusSmiling 2087295
add Cadence test suite to ci workflows
sisyphusSmiling 2677c7f
update FungibleTokenStack struct init named parameters
sisyphusSmiling c4511e5
add initial draft of DeFiAdapters
sisyphusSmiling 5a5523c
update DeFiAdapters with quote getters
sisyphusSmiling f9fc8c5
add DeFiAdapters to config
sisyphusSmiling 62e9f95
rename IncrementSwapStack & generalize using DeFiAdapters struct inte…
sisyphusSmiling f32c9b2
create IncrementFi contract & define SwapAdapter
sisyphusSmiling 2361b72
restructure repo
sisyphusSmiling a20c651
update contract comment formatting
sisyphusSmiling c3943ce
update dependencies
sisyphusSmiling 9a58a1a
add script to hex encode Cadence contract with dynamic testing imports
sisyphusSmiling d9c5d95
update hexify script to accept network argument
sisyphusSmiling 1923997
add test environment setup for IncrementFi contracts
sisyphusSmiling 0596074
add initial IncrementFiAdapters tests
sisyphusSmiling 476cc8f
update interface comments
sisyphusSmiling 7d6f74a
add dependencies
sisyphusSmiling fb12cc0
add initial EVM router getAmounts queries
sisyphusSmiling 8721f2c
add additional vm bridge dependencies
sisyphusSmiling 1789969
expose helper for retrieving a new empty Vault
sisyphusSmiling 6853773
add first run at EVM swapExactTokensForTokens in adapter
sisyphusSmiling 5b3afe3
init forge
sisyphusSmiling ecc129e
update forge foundry.toml
sisyphusSmiling 0db00e5
move forge-std to canonical forge lib at solidity/lib
sisyphusSmiling 1fc2925
add uniswapV2 dependencies
sisyphusSmiling 040c170
move forge script dir
sisyphusSmiling 5744192
update .gitignore
sisyphusSmiling 5ff927d
remove forge template files
sisyphusSmiling eae69a9
add openzeppelin dependencies
sisyphusSmiling 17341fa
add BasicERC20 for testing
sisyphusSmiling 8239c90
add initial EVM test helpers
sisyphusSmiling 3227568
add initial EVMStackFiAdapters test w/ uniswapV2 deployment
sisyphusSmiling 3340ff4
add vm bridge dependencies
sisyphusSmiling e7d41a7
add vm bridge test setup
sisyphusSmiling fa4ebca
Merge branch 'gio/prototype' into gio/swap-adapter
sisyphusSmiling 8550fcd
Merge branch 'gio/swap-adapter' into gio/add-increment-tests
sisyphusSmiling 9d7b1e0
Merge branch 'gio/add-increment-tests' into gio/evm-swap-adapter
sisyphusSmiling f7b2662
add Swapper struct interface
sisyphusSmiling 683cfe8
update Swapper interface
sisyphusSmiling a1241a6
refactor IncrementFiAdapters to use new Swapper interface
sisyphusSmiling e7cb9b0
refactor SwapStack Source & Sink to use new Swapper interface
sisyphusSmiling 69c20f8
remove DeFiAdapters contract
sisyphusSmiling 1ee5f37
rename StackFiInterfaces to DFB & update dependents
sisyphusSmiling 5e48d32
update DFB Swapper to return a Quote instead of a single value on amo…
sisyphusSmiling 417bfa8
update SwapStack in conformance with updated Swapper interface
sisyphusSmiling 9442655
update flow.json
sisyphusSmiling 67fe495
add pre-conditions to DFB.Swapper interface methods
sisyphusSmiling fb54d5d
update IncrementFiAdapters in conformance with new Swapper interface
sisyphusSmiling de7d5e9
add interface-level events to DFB
sisyphusSmiling cbd2a1c
update Sources & Sinks in conformance with updated DFB interfaces
sisyphusSmiling 09a1c59
fix Swapper conformance in IncrementFiAdapters.Swapper
sisyphusSmiling a790cd6
Merge branch 'gio/swap-adapter' into gio/add-increment-tests
sisyphusSmiling c7d0bde
update IncrementFiAdapters tests
sisyphusSmiling b9f4c9b
fix test filename typo
sisyphusSmiling 24ed80a
Merge branch 'gio/add-increment-tests' into gio/evm-swap-adapter
sisyphusSmiling ef7d374
rename EVMStackFiAdapters to DeFiBlocksEVMAdapters
sisyphusSmiling 5811def
remove unused import
sisyphusSmiling a795d62
refactor DeFiBlocksEVMAdapters for new Swapper interface
sisyphusSmiling 195c88f
rename EVMStackFiAdapters_test to DeFiBlocksEVMAdapters_test
sisyphusSmiling 6eef279
update code comments
sisyphusSmiling bdd62f4
fix solidity formatting
sisyphusSmiling c97a40a
remove unused forge test command from ci
sisyphusSmiling 590211f
Merge pull request #2 from onflow/gio/swap-adapter
sisyphusSmiling 7c7d2fa
fix DeFiBlocksEVMAdapters Swapper by adding approve() call before swa…
sisyphusSmiling a1b218b
update code comments
sisyphusSmiling 1b626e0
remove unused dependency
sisyphusSmiling fced438
add initial PriceOracle DFB interface
sisyphusSmiling 61efd70
add BandOracle dependencies for initial PriceOracle implementation
sisyphusSmiling 832bb74
update DFB.PriceOracle interface
sisyphusSmiling 811848f
add PriceOracle implementation adapting BandProtocol
sisyphusSmiling 61e6a17
simplify PriceOracle interface
sisyphusSmiling 89cff82
update BandOracleAdapters in conformance with new PriceOracle interface
sisyphusSmiling db530a1
remove unused import
sisyphusSmiling 979a833
Merge branch 'main' into gio/evm-swap-adapter
sisyphusSmiling 09a743e
update contract comments
sisyphusSmiling 6034c40
refactor DeFiBlocksEVMAdapters to reduce unnecessary UInt256-UFix64 c…
sisyphusSmiling 53a4a55
Merge branch 'gio/evm-swap-adapter' into gio/add-oracle
sisyphusSmiling ad1ccea
update PriceOracle.price return type
sisyphusSmiling 9bfdc52
Merge branch 'main' into gio/add-oracle
sisyphusSmiling File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| import "Burner" | ||
| import "FungibleToken" | ||
| import "FlowToken" | ||
| import "BandOracle" | ||
|
|
||
| import "DFB" | ||
|
|
||
| /// BandOracleAdapters | ||
| /// | ||
| /// This contract adapts BandOracle's price data oracle contracts for use as a DeFiBlocks PriceOracle connector | ||
| /// | ||
| access(all) contract BandOracleAdapters { | ||
|
|
||
| /// Mapping of asset Types to BandOracle symbols | ||
| access(all) let assetSymbols: {Type: String} | ||
| /// StoragePath for the SymbolUpdater tasked with adding Type:SYMBOL pairs | ||
| access(self) let SymbolUpdaterStoragePath: StoragePath | ||
|
|
||
| /* EVENTS */ | ||
| /// Emitted when a Type:SYMBOL pair is added via the SymbolUpdater resource | ||
| access(all) event SymbolAdded(symbol: String, asset: String) | ||
|
|
||
| /* CONSTRUCTS */ | ||
|
|
||
| // PriceOracle | ||
| // | ||
| /// An adapter for BandOracle as an implementation of the DeFiBlocks PriceOracle interface | ||
| access(all) struct PriceOracle : DFB.PriceOracle { | ||
| /// The token type serving as the price basis - e.g. USD in FLOW/USD | ||
| access(self) let quote: Type | ||
| /// A Source providing the FlowToken necessary for BandOracle price data requests | ||
| access(self) let feeSource: {DFB.Source} | ||
| /// The amount of seconds beyond which a price is considered stale and a price() call reverts | ||
| access(self) let staleThreshold: UInt64? | ||
|
|
||
| init(unitOfAccount: Type, staleThreshold: UInt64?, feeSource: {DFB.Source}) { | ||
| pre { | ||
| feeSource.getSourceType() == Type<@FlowToken.Vault>(): | ||
| "Invalid feeSource - given Source must provide FlowToken Vault, but provides \(feeSource.getSourceType().identifier)" | ||
| unitOfAccount.getType().isSubtype(of: Type<@{FungibleToken.Vault}>()): | ||
| "Invalid unitOfAccount - \(unitOfAccount.identifier) is not a FungibleToken.Vault implementation" | ||
| BandOracleAdapters.assetSymbols[unitOfAccount] != nil: | ||
| "Could not find a BandOracle symbol assigned to unitOfAccount \(unitOfAccount.identifier)" | ||
| } | ||
| self.feeSource = feeSource | ||
| self.quote = unitOfAccount | ||
| self.staleThreshold = staleThreshold | ||
| } | ||
|
|
||
| /// Returns the asset type serving as the price basis - e.g. USD in FLOW/USD | ||
| access(all) view fun unitOfAccount(): Type { | ||
| return self.quote | ||
| } | ||
|
|
||
| /// Returns the latest price data for a given asset denominated in unitOfAccount(). Since BandOracle requests | ||
| /// are paid, this implementation reverts if price data has gone stale | ||
| access(all) fun price(ofToken: Type): UFix64? { | ||
| // lookup the symbols | ||
| let baseSymbol = BandOracleAdapters.assetSymbols[ofToken] | ||
| ?? panic("Base asset type \(ofToken.identifier) does not have an assigned symbol") | ||
| let quoteSymbol = BandOracleAdapters.assetSymbols[self.unitOfAccount()]! | ||
| // withdraw the oracle fee & get the price data from BandOracle | ||
| let fee <- self.feeSource.withdrawAvailable(maxAmount: BandOracle.getFee()) | ||
| let priceData = BandOracle.getReferenceData(baseSymbol: baseSymbol, quoteSymbol: quoteSymbol, payment: <-fee) | ||
|
|
||
| // check price data has not gone stale based on last updated timestamp | ||
| let now = UInt64(getCurrentBlock().timestamp) | ||
| if self.staleThreshold != nil { | ||
| assert(now < priceData.baseTimestamp + self.staleThreshold!, | ||
| message: "Price data's base timestamp \(priceData.baseTimestamp) exceeds the staleThreshold " | ||
| .concat("\(priceData.baseTimestamp + self.staleThreshold!) at current timestamp \(now)")) | ||
| assert(now < priceData.quoteTimestamp + self.staleThreshold!, | ||
| message: "Price data's quote timestamp \(priceData.quoteTimestamp) exceeds the staleThreshold " | ||
| .concat("\(priceData.quoteTimestamp + self.staleThreshold!) at current timestamp \(now)")) | ||
| } | ||
|
|
||
| return priceData.fixedPointRate | ||
| } | ||
| } | ||
|
|
||
| // SymbolUpdater | ||
| // | ||
| /// Resource enabling the addition of new Type:SYMBOL pairings as they are supported by BandOracle's price oracle | ||
| access(all) resource SymbolUpdater { | ||
| /// Adds a Type:SYMBOL pairing to the contract's mapping. Reverts if the asset Type is already assigned a symbol | ||
| access(all) fun addSymbol(_ symbol: String, forAsset: Type) { | ||
| pre { | ||
| BandOracleAdapters.assetSymbols[forAsset] == nil: | ||
| "Asset \(forAsset.identifier) is already assigned symbol \(BandOracleAdapters.assetSymbols[forAsset]!)" | ||
| } | ||
| BandOracleAdapters.assetSymbols[forAsset] = symbol | ||
|
|
||
| emit SymbolAdded(symbol: symbol, asset: forAsset.identifier) | ||
| } | ||
| } | ||
|
|
||
| init() { | ||
| self.assetSymbols = { | ||
| Type<@FlowToken.Vault>(): "FLOW" | ||
| } | ||
| self.SymbolUpdaterStoragePath = StoragePath(identifier: "BandOracleAdapterSymbolUpdater_\(self.account.address)")! | ||
| self.account.storage.save(<-create SymbolUpdater(), to: self.SymbolUpdaterStoragePath) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import Test | ||
| import BlockchainHelpers | ||
| import "test_helpers.cdc" | ||
|
|
||
| access(all) let serviceAccount = Test.serviceAccount() | ||
|
|
||
| access(all) fun setup() { | ||
| var err = Test.deployContract( | ||
| name: "DFB", | ||
| path: "../contracts/interfaces/DFB.cdc", | ||
| arguments: [], | ||
| ) | ||
| Test.expect(err, Test.beNil()) | ||
| err = Test.deployContract( | ||
| name: "BandOracle", | ||
| path: "../../imports/6801a6222ebf784a/BandOracle.cdc", | ||
| arguments: [], | ||
| ) | ||
| Test.expect(err, Test.beNil()) | ||
| err = Test.deployContract( | ||
| name: "BandOracleAdapters", | ||
| path: "../contracts/adapters/BandOracleAdapters.cdc", | ||
| arguments: [], | ||
| ) | ||
| Test.expect(err, Test.beNil()) | ||
| } | ||
|
|
||
| access(all) fun testSetupSuccess() { | ||
| log("BandOracleAdapters deployment success") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would we represent USD here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking we would use a stablecoin. For example, a
PriceOraclewhereunitOfAccount() == Type<@USDCFlow.Vault>()would denominate all prices in USDCFlow which for the most part can be considered equivalent to USD.The big assumption of course is that the price for any stablecoin is exactly par for USD which isn't always the case. That said, there's not a type that can be used exactly as USD so all prices served by this
PriceOraclewould always be relative to some other token type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, though using
USDCFlowis probably risky, since the Flow foundation basically gave up on it in favor of the other bridged USDC representations. Probably better to rely on those. We should talk to Zach or someone to get an idea of which on will be the most stable