-
Notifications
You must be signed in to change notification settings - Fork 2
Update Pool & Position creation (replaces #6) #10
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
sisyphusSmiling
merged 35 commits into
tracer-bullet
from
gio/refactor-pool-creation-updated
Jun 25, 2025
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
bf9fb2f
feat: Restore AlpenFlow implementation with supporting contracts
kgrgpg f30f481
fix: Add MOET and TidalPoolGovernance to flow.json for deployment
kgrgpg 50b93e3
remove DeFiBlocks interface definitions from TidalProtocol contract
sisyphusSmiling 2c59dc3
update InternalPosition.topUpSource to value field from reference
sisyphusSmiling 86c8507
fix PriceOracle conformance .price() calls
sisyphusSmiling e5ba670
Update cadence/contracts/TidalProtocol.cdc
sisyphusSmiling 9908038
Assign TokenState.lastUpdate as current block timestamp on init
sisyphusSmiling 0d6e43d
update error message
sisyphusSmiling 6f0594e
remove TidalGovernance contract
sisyphusSmiling aa4e4f5
add select contract, tranasction, script, and test changes from #6
sisyphusSmiling 9e475d0
update DeFiBlocks submodule to latest main
sisyphusSmiling d49bcc9
add new DFB dependencies to flow.json
sisyphusSmiling e9a5ec6
fix PositionSink/Source conflict with IdentifiableStruct.id()
sisyphusSmiling 5880b82
update PositionSource fields from access(all) to access(self)
sisyphusSmiling 49a8f5c
add check on FungibleToken defining contract conformance when token a…
sisyphusSmiling 430bb5b
remove unused methods from test_helpers.cdc
sisyphusSmiling eb474f7
remove redundant TidalProtocol position sink/source definitions
sisyphusSmiling 5626a48
remove comment notes
sisyphusSmiling ea9202f
fix insufficient funds on rebalance error by minting MOET instead of …
sisyphusSmiling 12b8e50
remove contract debug logs
sisyphusSmiling 214a6bd
add behavioral test cases for position creation & under/overcollatera…
sisyphusSmiling 2c17878
remove unused methods, structs & implement TODOs
sisyphusSmiling 3404c1a
protects against underflow on TokenState.updateCredit/DebitBalance
sisyphusSmiling 3c61191
restrict access on Position's privileged methods
sisyphusSmiling a71be40
update minor contract formatting
sisyphusSmiling 22bb4d4
update DeFiBlocks with latest changes merged to main
sisyphusSmiling 87d7d21
update DeFiBlocks to latest
sisyphusSmiling 953f8f3
Merge branch 'tracer-bullet' into gio/refactor-pool-creation-updated
sisyphusSmiling c44f9a1
fix MOET deposit logic
sisyphusSmiling 9257899
fix import syntax
sisyphusSmiling f9e1bfa
add initial protocol events (#13)
sisyphusSmiling 9030c5f
update position rebalance transaction comments
sisyphusSmiling f1e8e55
fix fundsAvailableAboveTargetHealthAfterDepositing when effectiveDebt…
sisyphusSmiling 9d788ec
Update contract comments & reorganize for readability (#12)
sisyphusSmiling 7dc24b4
Update .gitmodules
nialexsan 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 |
|---|---|---|
| @@ -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 4a5109 to a2dcbd
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
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,69 @@ | ||
| import "FungibleToken" | ||
|
|
||
| import "DFB" | ||
|
|
||
| /// | ||
| /// THIS CONTRACT IS A MOCK AND IS NOT INTENDED FOR USE IN PRODUCTION | ||
| /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| /// | ||
| access(all) contract MockOracle { | ||
|
|
||
| /// token price denominated in USD | ||
| access(self) let mockedPrices: {Type: UFix64} | ||
| /// the token type in which prices are denominated | ||
| access(self) let unitOfAccount: Type | ||
| /// bps up or down by which current price moves when bumpPrice is called | ||
| access(self) let bumpVariance: UInt16 | ||
|
|
||
| access(all) struct PriceOracle : DFB.PriceOracle { | ||
|
|
||
| /// Returns the asset type serving as the price basis - e.g. USD in FLOW/USD | ||
| access(all) view fun unitOfAccount(): Type { | ||
| return MockOracle.unitOfAccount | ||
| } | ||
|
|
||
| /// Returns the latest price data for a given asset denominated in unitOfAccount() | ||
| access(all) fun price(ofToken: Type): UFix64? { | ||
| if ofToken == self.unitOfAccount() { | ||
| return 1.0 | ||
| } | ||
| return MockOracle.mockedPrices[ofToken] | ||
| } | ||
| } | ||
|
|
||
| // resets the price of the token within 0-bumpVariance (bps) of the current price | ||
| // allows for mocked data to have variability | ||
| access(all) fun bumpPrice(forToken: Type) { | ||
| if forToken == self.unitOfAccount { | ||
| return | ||
| } | ||
| let current = self.mockedPrices[forToken] | ||
| ?? panic("MockOracle does not have a price set for token \(forToken.identifier)") | ||
| let sign = revertibleRandom<UInt8>(modulo: 2) // 0 - down | 1 - up | ||
| let variance = self.convertToBPS(revertibleRandom<UInt16>(modulo: self.bumpVariance)) // bps up or down | ||
| if sign == 0 { | ||
| self.mockedPrices[forToken] = current - (current * variance) | ||
| } else { | ||
| self.mockedPrices[forToken] = current + (current * variance) | ||
| } | ||
| } | ||
|
|
||
| access(all) fun setPrice(forToken: Type, price: UFix64) { | ||
| self.mockedPrices[forToken] = price | ||
| } | ||
|
|
||
| access(self) view fun convertToBPS(_ variance: UInt16): UFix64 { | ||
| var res = UFix64(variance) | ||
| for i in InclusiveRange(0, 3) { | ||
| res = res / 10.0 | ||
| } | ||
| return res | ||
| } | ||
|
|
||
| init(unitOfAccountIdentifier: String) { | ||
| self.mockedPrices = {} | ||
| // e.g. vault.getType().identifier == 'A.0ae53cb6e3f42a79.FlowToken.Vault' | ||
| self.unitOfAccount = CompositeType(unitOfAccountIdentifier) ?? panic("Invalid unitOfAccountIdentifier \(unitOfAccountIdentifier)") | ||
| self.bumpVariance = 100 // 0.1% variance | ||
| } | ||
| } |
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,56 @@ | ||
| import "FungibleToken" | ||
|
|
||
| import "DFB" | ||
| import "TidalProtocol" | ||
|
|
||
| /// THIS CONTRACT IS NOT SAFE FOR PRODUCTION - FOR TEST USE ONLY | ||
| /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| /// | ||
| /// A simple contract enabling the persistent storage of a Position similar to a pattern expected for platforms | ||
| /// building on top of TidalProtocol's lending protocol | ||
| /// | ||
| access(all) contract MockTidalProtocolConsumer { | ||
|
|
||
| /// Canonical path for where the wrapper is to be stored | ||
| access(all) let WrapperStoragePath: StoragePath | ||
|
|
||
| /// Opens a TidalProtocol Position and returns a PositionWrapper containing that new position | ||
| /// | ||
| access(all) | ||
| fun createPositionWrapper( | ||
| collateral: @{FungibleToken.Vault}, | ||
| issuanceSink: {DFB.Sink}, | ||
| repaymentSource: {DFB.Source}?, | ||
| pushToDrawDownSink: Bool | ||
| ): @PositionWrapper { | ||
| return <- create PositionWrapper( | ||
| position: TidalProtocol.openPosition( | ||
| collateral: <-collateral, | ||
| issuanceSink: issuanceSink, | ||
| repaymentSource: repaymentSource, | ||
| pushToDrawDownSink: pushToDrawDownSink | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| /// A simple resource encapsulating a TidalProtocol Position | ||
| access(all) resource PositionWrapper { | ||
|
|
||
| access(self) let position: TidalProtocol.Position | ||
|
|
||
| init(position: TidalProtocol.Position) { | ||
| self.position = position | ||
| } | ||
|
|
||
| /// NOT SAFE FOR PRODUCTION | ||
| /// | ||
| /// Returns a reference to the wrapped Position | ||
| access(all) fun borrowPosition(): &TidalProtocol.Position { | ||
| return &self.position | ||
| } | ||
| } | ||
|
|
||
| init() { | ||
| self.WrapperStoragePath = /storage/tidalProtocolPositionWrapper | ||
| } | ||
| } | ||
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,13 @@ | ||
| import "TidalProtocol" | ||
|
|
||
| access(all) | ||
| fun main(pid: UInt64, vaultIdentifier: String, pullFromTopUpSource: Bool): UFix64 { | ||
| let vaultType = CompositeType(vaultIdentifier) ?? panic("Invalid vaultIdentifier \(vaultIdentifier)") | ||
|
|
||
| let protocolAddress= Type<@TidalProtocol.Pool>().address! | ||
|
|
||
| let pool = getAccount(protocolAddress).capabilities.borrow<&TidalProtocol.Pool>(TidalProtocol.PoolPublicPath) | ||
| ?? panic("Could not find a configured TidalProtocol Pool in account \(protocolAddress) at path \(TidalProtocol.PoolPublicPath)") | ||
|
|
||
| return pool.availableBalance(pid: pid, type: vaultType, pullFromTopUpSource: pullFromTopUpSource) | ||
| } |
17 changes: 17 additions & 0 deletions
17
cadence/scripts/tidal-protocol/get_reserve_balance_for_type.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 |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import "TidalProtocol" | ||
|
|
||
| /// Returns the Pool's reserve balance for a given Vault type | ||
| /// | ||
| /// @param vaultIdentifier: The Type identifier (e.g. vault.getType().identifier) of the related token vault | ||
| /// | ||
| access(all) | ||
| fun main(vaultIdentifier: String): UFix64 { | ||
| let vaultType = CompositeType(vaultIdentifier) ?? panic("Invalid vaultIdentifier \(vaultIdentifier)") | ||
|
|
||
| let protocolAddress= Type<@TidalProtocol.Pool>().address! | ||
|
|
||
| let pool = getAccount(protocolAddress).capabilities.borrow<&TidalProtocol.Pool>(TidalProtocol.PoolPublicPath) | ||
| ?? panic("Could not find a configured TidalProtocol Pool in account \(protocolAddress) at path \(TidalProtocol.PoolPublicPath)") | ||
|
|
||
| return pool.reserveBalance(type: vaultType) | ||
| } |
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,9 @@ | ||
| import "TidalProtocol" | ||
|
|
||
| /// Returns whether there is a Pool stored in the provided account's address. This address would normally be the | ||
| /// TidalProtocol contract address | ||
| /// | ||
| access(all) | ||
| fun main(address: Address): Bool { | ||
| return getAccount(address).storage.type(at: TidalProtocol.PoolStoragePath) == Type<@TidalProtocol.Pool>() | ||
| } |
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,13 @@ | ||
| import "TidalProtocol" | ||
|
|
||
| /// Returns the position health for a given position id, reverting if the position does not exist | ||
| /// | ||
| /// @param pid: The Position ID | ||
| /// | ||
| access(all) | ||
| fun main(pid: UInt64): UFix64 { | ||
| let protocolAddress= Type<@TidalProtocol.Pool>().address! | ||
| return getAccount(protocolAddress).capabilities.borrow<&TidalProtocol.Pool>(TidalProtocol.PoolPublicPath) | ||
| ?.positionHealth(pid: pid) | ||
| ?? panic("Could not find a configured TidalProtocol Pool in account \(protocolAddress) at path \(TidalProtocol.PoolPublicPath)") | ||
| } |
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,8 @@ | ||
| import "FungibleToken" | ||
|
|
||
| /// Returns a account's balance of a FungibleToken Vault with public Capability published at the provided path | ||
| /// | ||
| access(all) | ||
| fun main(address: Address, vaultPublicPath: PublicPath): UFix64? { | ||
| return getAccount(address).capabilities.borrow<&{FungibleToken.Vault}>(vaultPublicPath)?.balance ?? nil | ||
| } |
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.
Why do we need a wrapper to enable persistent storage?
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 suppose we don't. I originally added it thinking we might use Capabilities on it only to later realize they weren't needed and that we can actually issue Capabilities on structs as well as resources.
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'll note this as part of the post-tracer refactor, so it can be removed in a subsequent PR. Leaving for now to avoid merge conflicts in #19