-
Notifications
You must be signed in to change notification settings - Fork 0
Add Strategy composition & AutoBalancer management contracts #7
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
85 commits
Select commit
Hold shift + click to select a range
8e99b52
add initial Tidal contract & supporting scripts & transactions
sisyphusSmiling 7c754ee
update DFB to include PriceOracle interface
sisyphusSmiling 32d1f26
add initial USDA contract for use with MockOracle
sisyphusSmiling be1f7c4
add MockOracle contract & supporting txns & scripts
sisyphusSmiling 8dfb7de
remove unused import
sisyphusSmiling f538ddd
add MockSwapper contract
sisyphusSmiling 5270eb4
update MockSwapper to better represent sourcing liquidity from pools …
sisyphusSmiling 58bd454
update flow.json
sisyphusSmiling 3e7dddb
add MockSwapper.setLiquidityConnector transaction
sisyphusSmiling 07cc65e
update transaction comment
sisyphusSmiling 675e146
add MockSwapper to emulator deployment
sisyphusSmiling 1b5055b
add supporting USDA transactions
sisyphusSmiling dee1f14
update MockOracle to return 1.0 for unitOfAccount price
sisyphusSmiling bc24908
fix internal dependency pre-condition
sisyphusSmiling 60efc8d
Merge branch 'gio/mock-oracle' into gio/mock-amm
sisyphusSmiling d4efa70
add emulator setup script
sisyphusSmiling 535b231
Merge branch 'main' into gio/mock-amm
sisyphusSmiling c5fd5ef
update USDA initialization args
sisyphusSmiling 815f75f
update internal dependencies
sisyphusSmiling 987fd7d
remove Tidal.UniqueID definition in favor of DFB.UniqueIdentifier
sisyphusSmiling c62b6d0
update mocked PriceOracle to return optional on price()
sisyphusSmiling 1d14d05
update MockSwapper based on updated DFB interfaces
sisyphusSmiling 2e83803
add initial strategy framing
sisyphusSmiling 648141f
add initial strategy constructor contract
sisyphusSmiling 3800ff5
Merge branch 'main' into gio/add-strategy-factory
sisyphusSmiling 17e8219
update internal dependencies
sisyphusSmiling a2d335a
rename Tidal contract to TidalYield
sisyphusSmiling 8e87097
update TidalStrategies StrategyFactory & StrategyBuilder constructs
sisyphusSmiling c6f0bb5
rename TidalStrategies to TidalYieldFactory
sisyphusSmiling f91bb25
update contract comments
sisyphusSmiling b02a551
move mocke strategy components from TidalYieldFactory to MockStrategy
sisyphusSmiling 9057569
consolidate former Factory contract to TidalYield primary contract
sisyphusSmiling 7ef3e80
fix mock strategies
sisyphusSmiling c9dbc0a
fix flow.json config
sisyphusSmiling 71ab6f4
add TidalYieldAutoBalancers contract & update flow.json config
sisyphusSmiling 657e9b1
rename StrategyBuilder to StrategyComposer
sisyphusSmiling 7f6cac0
update initial TraceStrategy and TracerStrategyComposer
sisyphusSmiling c03b0c3
refactor Strategy from struct to resource
sisyphusSmiling 63733a4
update contract comments
sisyphusSmiling 5774e7e
update TidalYield interface conditions & defaults, update contract fo…
sisyphusSmiling 015f2eb
update contract comments
sisyphusSmiling e005eb2
remove redundant dependency DFBUtils
sisyphusSmiling 4716e79
add contract comments to TidalYield
sisyphusSmiling 11cf0de
add AutoBalancer cleanup on Strategy burn
sisyphusSmiling d9f35f4
refactor StrategyComposer from struct interface to resource interface
sisyphusSmiling 1fa0b7a
update comments & error messages
sisyphusSmiling 8218909
add StrategyComposerIssuer to contract init block
sisyphusSmiling e3e3bf8
rename cadence/transactions/tidal to cadence/transactions/tidal-yield
sisyphusSmiling 79d0ad6
rename scripts sub-directory
sisyphusSmiling 5aa2138
update MockStrategy contract construct names
sisyphusSmiling ac345cb
add TidalProtocol supporting txns & scripts
sisyphusSmiling c3abff2
add initial test and test helpers & update flow.json testing aliases
sisyphusSmiling 7aea0ad
add Cadence tests to github ci action
sisyphusSmiling dd29732
rename usda/ to moet/
sisyphusSmiling 1e75a4d
update setup_emulator.sh script
sisyphusSmiling 27a4c0a
remove Owner entitlement from TidalYield contract
sisyphusSmiling a585d98
fix MockStrategy getters
sisyphusSmiling e733ffd
add initial Tide management tests
sisyphusSmiling 374d8c7
fix createTide route caused by TracerStrategy composition errors
sisyphusSmiling fb72fb5
remove deprecated TidalYield.Owner entitlement usage
sisyphusSmiling e1471cf
update contract comments
sisyphusSmiling 235143b
update DeFiBlocks to latest
sisyphusSmiling 8932939
update get_balance script
sisyphusSmiling 0bea1a3
fix MockStrategy interface conformance
sisyphusSmiling bf62a2a
rename token-related transactions
sisyphusSmiling 3f47e72
add behavioral tests covering TracerStrategy
sisyphusSmiling 22d7d0d
update scripts
sisyphusSmiling 6268d2e
add AutoBalancer rebalance transaction
sisyphusSmiling 058bbe8
undo Tidal contract renaming
sisyphusSmiling 02f252c
rename Tidal to TidalYield
sisyphusSmiling e085da2
fix MOET deposit logic
sisyphusSmiling f960a01
fix YieldToken deposit logic
sisyphusSmiling fdbe1a2
update addStrategyComposer pre-condition
sisyphusSmiling 051302c
fix mock price getter script
sisyphusSmiling 6715204
update flow.json emulator aliases
sisyphusSmiling 662660a
add test user
nialexsan 6bf8ccf
add +x
nialexsan 77057b6
swap git module
nialexsan fe61688
Merge branch 'gio/add-strategy-factory' into gio/rename-tidal-contract
Kay-Zee 9f4d3f7
Merge pull request #8 from onflow/gio/rename-tidal-contract
Kay-Zee b7d182c
Revert "Rename Tidal to TidalYield" (#10)
sisyphusSmiling 4923b4c
update tidal protocol with events
nialexsan 34d2ecd
Add rebalance test
Kay-Zee 059cd1a
Update to latest defi blocks
Kay-Zee 8661eac
Make adjustment to allow closing the tide and retain the full collate…
Kay-Zee 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,33 @@ | ||
| name: CI | ||
|
|
||
| on: pull_request | ||
|
|
||
| jobs: | ||
| tests: | ||
| name: Flow CLI Tests | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.GH_PAT }} | ||
| submodules: "true" | ||
| - name: Set up Go | ||
| uses: actions/setup-go@v3 | ||
| with: | ||
| go-version: "1.23.x" | ||
| - uses: actions/cache@v4 | ||
| with: | ||
| path: ~/go/pkg/mod | ||
| key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-go- | ||
| - name: Install Flow CLI | ||
| run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" | ||
| - name: Flow CLI Version | ||
| run: flow version | ||
| - name: Update PATH | ||
| run: echo "/root/.local/bin" >> $GITHUB_PATH | ||
| - name: Install dependencies | ||
| run: flow deps install --skip-alias --skip-deployments | ||
| - name: Run tests | ||
| run: flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" ./cadence/tests/*_test.cdc |
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 |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| [submodule "DeFiBlocks"] | ||
| path = DeFiBlocks | ||
| url = https://github.com/onflow/DeFiBlocks | ||
| url = git@github.com:onflow/DeFiBlocks.git |
Submodule DeFiBlocks
updated
from 714652 to a2dcbd
Large diffs are not rendered by default.
Oops, something went wrong.
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,123 @@ | ||
| // standards | ||
| import "Burner" | ||
| import "FungibleToken" | ||
| // DeFiBlocks | ||
| import "DFB" | ||
|
|
||
| /// TidalYieldAutoBalancers | ||
| /// | ||
| /// This contract deals with the storage, retrieval and cleanup of DeFiBlocks AutoBalancers as they are used in | ||
| /// TidalYield defined Strategies. | ||
| /// | ||
| /// AutoBalancers are stored in contract account storage at paths derived by their related DFB.UniqueIdentifier.id | ||
| /// which identifies all DeFiBlocks components in the stack related to their composite Strategy. | ||
| /// | ||
| /// When a Tide and necessarily the related Strategy is closed & burned, the related AutoBalancer and its Capabilities | ||
| /// are destroyed and deleted | ||
| /// | ||
| access(all) contract TidalYieldAutoBalancers { | ||
|
|
||
| /// The path prefix used for StoragePath & PublicPath derivations | ||
| access(all) let pathPrefix: String | ||
|
|
||
| /* --- PUBLIC METHODS --- */ | ||
|
|
||
| /// Returns the path (StoragePath or PublicPath) at which an AutoBalancer is stored with the associated | ||
| /// UniqueIdentifier.id. | ||
| access(all) view fun deriveAutoBalancerPath(id: UInt64, storage: Bool): Path { | ||
| return storage ? StoragePath(identifier: "\(self.pathPrefix)\(id)")! : PublicPath(identifier: "\(self.pathPrefix)\(id)")! | ||
| } | ||
|
|
||
| /// Returns an unauthorized reference to an AutoBalancer with the given UniqueIdentifier.id value. If none is | ||
| /// configured, `nil` will be returned. | ||
| access(all) fun borrowAutoBalancer(id: UInt64): &DFB.AutoBalancer? { | ||
| let publicPath = self.deriveAutoBalancerPath(id: id, storage: false) as! PublicPath | ||
| return self.account.capabilities.borrow<&DFB.AutoBalancer>(publicPath) | ||
| } | ||
|
|
||
| /* --- INTERNAL METHODS --- */ | ||
|
|
||
| /// Configures a new AutoBalancer in storage, configures its public Capability, and sets its inner authorized | ||
| /// Capability. If an AutoBalancer is stored with an associated UniqueID value, the operation reverts. | ||
| access(account) fun _initNewAutoBalancer( | ||
| oracle: {DFB.PriceOracle}, | ||
| vaultType: Type, | ||
| lowerThreshold: UFix64, | ||
| upperThreshold: UFix64, | ||
| rebalanceSink: {DFB.Sink}?, | ||
| rebalanceSource: {DFB.Source}?, | ||
| uniqueID: DFB.UniqueIdentifier | ||
| ): auth(DFB.Auto, DFB.Set, DFB.Get, FungibleToken.Withdraw) &DFB.AutoBalancer { | ||
|
|
||
| // derive paths & prevent collision | ||
| let storagePath = self.deriveAutoBalancerPath(id: uniqueID.id, storage: true) as! StoragePath | ||
| let publicPath = self.deriveAutoBalancerPath(id: uniqueID.id, storage: false) as! PublicPath | ||
| var storedType = self.account.storage.type(at: storagePath) | ||
| var publishedCap = self.account.capabilities.exists(publicPath) | ||
| assert(storedType == nil, | ||
| message: "Storage collision when creating AutoBalancer for UniqueIdentifier.id \(uniqueID.id) at path \(storagePath)") | ||
| assert(!publishedCap, | ||
| message: "Published Capability collision found when publishing AutoBalancer for UniqueIdentifier.id \(uniqueID.id) at path \(publicPath)") | ||
|
|
||
| // create & save AutoBalancer | ||
| let autoBalancer <- DFB.createAutoBalancer( | ||
| oracle: oracle, | ||
| vaultType: vaultType, | ||
| lowerThreshold: lowerThreshold, | ||
| upperThreshold: upperThreshold, | ||
| rebalanceSink: rebalanceSink, | ||
| rebalanceSource: rebalanceSource, | ||
| uniqueID: uniqueID | ||
| ) | ||
| self.account.storage.save(<-autoBalancer, to: storagePath) | ||
| let autoBalancerRef = self._borrowAutoBalancer(uniqueID.id) | ||
|
|
||
| // issue & publish public capability | ||
| let publicCap = self.account.capabilities.storage.issue<&DFB.AutoBalancer>(storagePath) | ||
| self.account.capabilities.publish(publicCap, at: publicPath) | ||
|
|
||
| // issue private capability & set within AutoBalancer | ||
| let authorizedCap = self.account.capabilities.storage.issue<auth(FungibleToken.Withdraw) &DFB.AutoBalancer>(storagePath) | ||
| autoBalancerRef.setSelfCapability(authorizedCap) | ||
|
|
||
| // ensure proper configuration before closing | ||
| storedType = self.account.storage.type(at: storagePath) | ||
| publishedCap = self.account.capabilities.exists(publicPath) | ||
| assert(storedType == Type<@DFB.AutoBalancer>(), | ||
| message: "Error when configuring AutoBalancer for UniqueIdentifier.id \(uniqueID.id) at path \(storagePath)") | ||
| assert(publishedCap, | ||
| message: "Error when publishing AutoBalancer Capability for UniqueIdentifier.id \(uniqueID.id) at path \(publicPath)") | ||
| return autoBalancerRef | ||
| } | ||
|
|
||
| /// Returns an authorized reference on the AutoBalancer with the associated UniqueIdentifier.id. If none is found, | ||
| /// the operation reverts. | ||
| access(account) | ||
| fun _borrowAutoBalancer(_ id: UInt64): auth(DFB.Auto, DFB.Set, DFB.Get, FungibleToken.Withdraw) &DFB.AutoBalancer { | ||
| let storagePath = self.deriveAutoBalancerPath(id: id, storage: true) as! StoragePath | ||
| return self.account.storage.borrow<auth(DFB.Auto, DFB.Set, DFB.Get, FungibleToken.Withdraw) &DFB.AutoBalancer>( | ||
| from: storagePath | ||
| ) ?? panic("Could not borrow reference to AutoBalancer with UniqueIdentifier.id \(id) from StoragePath \(storagePath)") | ||
| } | ||
|
|
||
| /// Called by strategies defined in the TidalYield account which leverage account-hosted AutoBalancers when a | ||
| /// Strategy is burned | ||
| access(account) fun _cleanupAutoBalancer(id: UInt64) { | ||
| let storagePath = self.deriveAutoBalancerPath(id: id, storage: true) as! StoragePath | ||
| let publicPath = self.deriveAutoBalancerPath(id: id, storage: false) as! PublicPath | ||
| // unpublish the public AutoBalancer Capability | ||
| self.account.capabilities.unpublish(publicPath) | ||
| // delete any CapabilityControllers targetting the AutoBalancer | ||
| self.account.capabilities.storage.forEachController(forPath: storagePath, fun(_ controller: &StorageCapabilityController): Bool { | ||
| controller.delete() | ||
| return true | ||
| }) | ||
| // load & burn the AutoBalancer | ||
| let autoBalancer <-self.account.storage.load<@DFB.AutoBalancer>(from: storagePath) | ||
| Burner.burn(<-autoBalancer) | ||
| } | ||
|
|
||
| init() { | ||
| self.pathPrefix = "TidalYieldAutoBalancer_" | ||
| } | ||
| } | ||
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,210 @@ | ||
| // standards | ||
| import "FungibleToken" | ||
| import "FlowToken" | ||
| // DeFiBlocks | ||
| import "DFBUtils" | ||
| import "DFB" | ||
| import "SwapStack" | ||
| // Lending protocol | ||
| import "TidalProtocol" | ||
| // TidalYield platform | ||
| import "Tidal" | ||
| import "TidalYieldAutoBalancers" | ||
| // tokens | ||
| import "YieldToken" | ||
| import "MOET" | ||
| // mocks | ||
| import "MockOracle" | ||
| import "MockSwapper" | ||
|
|
||
| /// THIS CONTRACT IS A MOCK AND IS NOT INTENDED FOR USE IN PRODUCTION | ||
| /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| /// | ||
| /// TidalYieldStrategies | ||
| /// | ||
| /// This contract defines Strategies used in the TidalYield platform. | ||
| /// | ||
| /// A Strategy instance can be thought of as objects wrapping a stack of DeFiBlocks connectors wired together to | ||
| /// (optimally) generate some yield on initial deposits. Strategies can be simple such as swapping into a yield-bearing | ||
| /// asset (such as stFLOW) or more complex DeFiBlocks stacks. | ||
| /// | ||
| /// A StrategyComposer is tasked with the creation of a supported Strategy. It's within the stacking of DeFiBlocks | ||
| /// connectors that the true power of the components lies. | ||
| /// | ||
| access(all) contract TidalYieldStrategies { | ||
|
|
||
| /// Canonical StoragePath where the StrategyComposerIssuer should be stored | ||
| access(all) let IssuerStoragePath: StoragePath | ||
|
|
||
| /// This is the first Strategy implementation, wrapping a TidalProtocol Position along with its related Sink & | ||
| /// Source. While this object is a simple wrapper for the top-level collateralized position, the true magic of the | ||
| /// DeFiBlocks is in the stacking of the related connectors. This stacking logic can be found in the | ||
| /// TracerStrategyComposer construct. | ||
| access(all) resource TracerStrategy : Tidal.Strategy { | ||
| /// An optional identifier allowing protocols to identify stacked connector operations by defining a protocol- | ||
| /// specific Identifier to associated connectors on construction | ||
| access(contract) let uniqueID: DFB.UniqueIdentifier? | ||
| access(self) let position: TidalProtocol.Position | ||
| access(self) var sink: {DFB.Sink} | ||
| access(self) var source: {DFB.Source} | ||
|
|
||
| init(id: DFB.UniqueIdentifier, collateralType: Type, position: TidalProtocol.Position) { | ||
| self.uniqueID = id | ||
| self.position = position | ||
| self.sink = position.createSink(type: collateralType) | ||
| self.source = position.createSourceWithOptions(type: collateralType, pullFromTopUpSource: true) | ||
| } | ||
|
|
||
| // Inherited from Tidal.Strategy default implementation | ||
| // access(all) view fun isSupportedCollateralType(_ type: Type): Bool | ||
|
|
||
| access(all) view fun getSupportedCollateralTypes(): {Type: Bool} { | ||
| return { self.sink.getSinkType(): true } | ||
| } | ||
| /// Returns the amount available for withdrawal via the inner Source | ||
| access(all) fun availableBalance(ofToken: Type): UFix64 { | ||
| return ofToken == self.source.getSourceType() ? self.source.minimumAvailable() : 0.0 | ||
| } | ||
| /// Deposits up to the inner Sink's capacity from the provided authorized Vault reference | ||
| access(all) fun deposit(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { | ||
| self.sink.depositCapacity(from: from) | ||
| } | ||
| /// Withdraws up to the max amount, returning the withdrawn Vault. If the requested token type is unsupported, | ||
| /// an empty Vault is returned. | ||
| access(FungibleToken.Withdraw) fun withdraw(maxAmount: UFix64, ofToken: Type): @{FungibleToken.Vault} { | ||
| if ofToken != self.source.getSourceType() { | ||
| return <- DFBUtils.getEmptyVault(ofToken) | ||
| } | ||
| return <- self.source.withdrawAvailable(maxAmount: maxAmount) | ||
| } | ||
| /// Executed when a Strategy is burned, cleaning up the Strategy's stored AutoBalancer | ||
| access(contract) fun burnCallback() { | ||
| TidalYieldAutoBalancers._cleanupAutoBalancer(id: self.id()!) | ||
| } | ||
| } | ||
|
|
||
| /// This StrategyComposer builds a TracerStrategy | ||
| access(all) resource TracerStrategyComposer : Tidal.StrategyComposer { | ||
| /// Returns the Types of Strategies composed by this StrategyComposer | ||
| access(all) view fun getComposedStrategyTypes(): {Type: Bool} { | ||
| return { Type<@TracerStrategy>(): true } | ||
| } | ||
|
|
||
| /// Returns the Vault types which can be used to initialize a given Strategy | ||
| access(all) view fun getSupportedInitializationVaults(forStrategy: Type): {Type: Bool} { | ||
| return { Type<@FlowToken.Vault>(): true } | ||
| } | ||
|
|
||
| /// Returns the Vault types which can be deposited to a given Strategy instance if it was initialized with the | ||
| /// provided Vault type | ||
| access(all) view fun getSupportedInstanceVaults(forStrategy: Type, initializedWith: Type): {Type: Bool} { | ||
| return { Type<@FlowToken.Vault>(): true } | ||
| } | ||
|
|
||
| /// Composes a Strategy of the given type with the provided funds | ||
| access(all) fun createStrategy( | ||
| _ type: Type, | ||
| uniqueID: DFB.UniqueIdentifier, | ||
| withFunds: @{FungibleToken.Vault} | ||
| ): @{Tidal.Strategy} { | ||
| // this PriceOracle is mocked and will be shared by all components used in the TracerStrategy | ||
| let oracle = MockOracle.PriceOracle() | ||
|
|
||
| // assign token types | ||
| let collateralType = withFunds.getType() | ||
| let yieldTokenType = Type<@YieldToken.Vault>() | ||
| let moetTokenType = Type<@MOET.Vault>() | ||
| let flowTokenType = Type<@FlowToken.Vault>() | ||
|
|
||
| // configure and AutoBalancer for this stack | ||
| let autoBalancer = TidalYieldAutoBalancers._initNewAutoBalancer( | ||
| oracle: oracle, // used to determine value of deposits & when to rebalance | ||
| vaultType: yieldTokenType, // the type of Vault held by the AutoBalancer | ||
| lowerThreshold: 0.95, // set AutoBalancer to pull from rebalanceSource when balance is 5% below value of deposits | ||
| upperThreshold: 1.05, // set AutoBalancer to push to rebalanceSink when balance is 5% below value of deposits | ||
| rebalanceSink: nil, // nil on init - will be set once a PositionSink is available | ||
| rebalanceSource: nil, // nil on init - not set for TracerStrategy | ||
| uniqueID: uniqueID // identifies AutoBalancer as part of this Strategy | ||
| ) | ||
| // enables deposits of YieldToken to the AutoBalancer | ||
| let abaSink = autoBalancer.createBalancerSink() ?? panic("Could not retrieve Sink from AutoBalancer with id \(uniqueID.id)") | ||
| // enables withdrawals of YieldToken from the AutoBalancer | ||
| let abaSource = autoBalancer.createBalancerSource() ?? panic("Could not retrieve Sink from AutoBalancer with id \(uniqueID.id)") | ||
|
|
||
| // init MOET <> YIELD swappers | ||
| // | ||
| // MOET -> YieldToken | ||
| let moetToYieldSwapper = MockSwapper.Swapper( | ||
| inVault: moetTokenType, | ||
| outVault: yieldTokenType, | ||
| uniqueID: uniqueID | ||
| ) | ||
| // YieldToken -> MOET | ||
| let yieldToMoetSwapper = MockSwapper.Swapper( | ||
| inVault: yieldTokenType, | ||
| outVault: moetTokenType, | ||
| uniqueID: uniqueID | ||
| ) | ||
|
|
||
| // init SwapSink directing swapped funds to AutoBalancer | ||
| // | ||
| // Swaps provided MOET to YieldToken & deposits to the AutoBalancer | ||
| let abaSwapSink = SwapStack.SwapSink(swapper: moetToYieldSwapper, sink: abaSink, uniqueID: uniqueID) | ||
| // Swaps YieldToken & provides swapped MOET, sourcing YieldToken from the AutoBalancer | ||
| let abaSwapSource = SwapStack.SwapSource(swapper: yieldToMoetSwapper, source: abaSource, uniqueID: uniqueID) | ||
|
|
||
| // open a TidalProtocol position | ||
| let position = TidalProtocol.openPosition( | ||
| collateral: <-withFunds, | ||
| issuanceSink: abaSwapSink, | ||
| repaymentSource: abaSwapSource, | ||
| pushToDrawDownSink: true | ||
| ) | ||
| // get Sink & Source connectors relating to the new Position | ||
| let positionSink = position.createSinkWithOptions(type: collateralType, pushToDrawDownSink: true) | ||
| let positionSource = position.createSourceWithOptions(type: collateralType, pullFromTopUpSource: true) // TODO: may need to be false | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would it be false? |
||
|
|
||
| // init YieldToken -> FLOW Swapper | ||
| let yieldToFlowSwapper = MockSwapper.Swapper( | ||
| inVault: yieldTokenType, | ||
| outVault: flowTokenType, // TODO: before | ||
| uniqueID: uniqueID | ||
| ) | ||
| // allows for YieldToken to be deposited to the Position | ||
| let positionSwapSink = SwapStack.SwapSink(swapper: yieldToFlowSwapper, sink: positionSink, uniqueID: uniqueID) | ||
|
|
||
| // set the AutoBalancer's rebalance Sink which it will use to deposit overflown value, | ||
| // recollateralizing the position | ||
| autoBalancer.setSink(positionSwapSink) | ||
|
|
||
| return <-create TracerStrategy( | ||
| id: DFB.UniqueIdentifier(), | ||
| collateralType: collateralType, | ||
| position: position | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| /// This resource enables the issuance of StrategyComposers, thus safeguarding the issuance of Strategies which | ||
| /// may utilize resource consumption (i.e. account storage). Since TracerStrategy creation consumes account storage | ||
| /// via configured AutoBalancers | ||
| access(all) resource StrategyComposerIssuer : Tidal.StrategyComposerIssuer { | ||
| access(all) view fun getSupportedComposers(): {Type: Bool} { | ||
| return { Type<@TracerStrategyComposer>(): true } | ||
| } | ||
| access(all) fun issueComposer(_ type: Type): @{Tidal.StrategyComposer} { | ||
| switch type { | ||
| case Type<@TracerStrategyComposer>(): | ||
| return <- create TracerStrategyComposer() | ||
| default: | ||
| panic("Unsupported StrategyComposer requested: \(type.identifier)") | ||
| } | ||
| } | ||
| } | ||
|
|
||
| init() { | ||
| self.IssuerStoragePath = StoragePath(identifier: "TidalYieldStrategyComposerIssuer_\(self.account.address)")! | ||
|
|
||
| self.account.storage.save(<-create StrategyComposerIssuer(), to: self.IssuerStoragePath) | ||
| } | ||
| } | ||
Oops, something went wrong.
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.
Should it just return
nilinstead?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.
It could, though it would revert where called since it's required for write operations