diff --git a/FlowActions b/FlowActions index 2953e7d6..b9c308a8 160000 --- a/FlowActions +++ b/FlowActions @@ -1 +1 @@ -Subproject commit 2953e7d69d6c1573bcff207bda1ff5aa4d7f905d +Subproject commit b9c308a801df618e78d48c02ea4bc06b5f5dcbc9 diff --git a/cadence/contracts/FlowALPv0.cdc b/cadence/contracts/FlowALPv0.cdc index 4e427e20..c53b2c44 100644 --- a/cadence/contracts/FlowALPv0.cdc +++ b/cadence/contracts/FlowALPv0.cdc @@ -1927,7 +1927,6 @@ access(all) contract FlowALPv0 { ) return PositionDetails( - id: pid, balances: balances, poolDefaultToken: self.defaultToken, defaultTokenAvailableBalance: defaultTokenAvailable, @@ -1935,21 +1934,6 @@ access(all) contract FlowALPv0 { ) } - /// Returns the details of a given position, or nil if the position does not exist. - /// This is the non-panicking variant of getPositionDetails. - access(all) fun tryGetPositionDetails(pid: UInt64): PositionDetails? { - if self.debugLogging { - log(" [CONTRACT] tryGetPositionDetails(pid: \(pid))") - } - - if self._tryBorrowPosition(pid: pid) == nil { - return nil - } - - return self.getPositionDetails(pid: pid) - } - - /// Any external party can perform a manual liquidation on a position under the following circumstances: /// - the position has health < 1 /// - the liquidation price offered is better than what is available on a DEX @@ -4095,14 +4079,9 @@ access(all) contract FlowALPv0 { } } - /// Returns an authorized reference to the requested InternalPosition, or nil if it does not exist. - access(self) view fun _tryBorrowPosition(pid: UInt64): (auth(EImplementation) &InternalPosition)? { - return &self.positions[pid] as auth(EImplementation) &InternalPosition? - } - - /// Returns an authorized reference to the requested InternalPosition or panics if the position does not exist. + /// Returns an authorized reference to the requested InternalPosition or `nil` if the position does not exist access(self) view fun _borrowPosition(pid: UInt64): auth(EImplementation) &InternalPosition { - return self._tryBorrowPosition(pid: pid) + return &self.positions[pid] as auth(EImplementation) &InternalPosition? ?? panic("Invalid position ID \(pid) - could not find an InternalPosition with the requested ID in the Pool") } @@ -4783,9 +4762,6 @@ access(all) contract FlowALPv0 { /// This structure is NOT used internally. access(all) struct PositionDetails { - /// The unique identifier of the position - access(all) let id: UInt64 - /// Balance details about each Vault Type deposited to the related Position access(all) let balances: [PositionBalance] @@ -4799,13 +4775,11 @@ access(all) contract FlowALPv0 { access(all) let health: UFix128 init( - id: UInt64, balances: [PositionBalance], poolDefaultToken: Type, defaultTokenAvailableBalance: UFix64, health: UFix128 ) { - self.id = id self.balances = balances self.poolDefaultToken = poolDefaultToken self.defaultTokenAvailableBalance = defaultTokenAvailableBalance diff --git a/cadence/scripts/flow-alp/get_positions_by_ids.cdc b/cadence/scripts/flow-alp/get_positions_by_ids.cdc index 5a1651c5..ce4ca48f 100644 --- a/cadence/scripts/flow-alp/get_positions_by_ids.cdc +++ b/cadence/scripts/flow-alp/get_positions_by_ids.cdc @@ -1,6 +1,4 @@ // Returns the details of multiple positions by their IDs. -// Positions that no longer exist (e.g., closed between fetching IDs and executing this script) -// are silently skipped. import "FlowALPv0" access(all) fun main(positionIDs: [UInt64]): [FlowALPv0.PositionDetails] { @@ -11,9 +9,7 @@ access(all) fun main(positionIDs: [UInt64]): [FlowALPv0.PositionDetails] { let details: [FlowALPv0.PositionDetails] = [] for id in positionIDs { - if let detail = pool.tryGetPositionDetails(pid: id) { - details.append(detail) - } + details.append(pool.getPositionDetails(pid: id)) } return details } diff --git a/cadence/scripts/flow-alp/try_get_position_details.cdc b/cadence/scripts/flow-alp/try_get_position_details.cdc deleted file mode 100644 index f8b96807..00000000 --- a/cadence/scripts/flow-alp/try_get_position_details.cdc +++ /dev/null @@ -1,11 +0,0 @@ -// Returns the details of a position by its ID, or nil if the position does not exist. -import "FlowALPv0" - -access(all) fun main(positionID: UInt64): FlowALPv0.PositionDetails? { - let protocolAddress = Type<@FlowALPv0.Pool>().address! - let account = getAccount(protocolAddress) - let pool = account.capabilities.borrow<&FlowALPv0.Pool>(FlowALPv0.PoolPublicPath) - ?? panic("Could not find Pool at path \(FlowALPv0.PoolPublicPath)") - - return pool.tryGetPositionDetails(pid: positionID) -} diff --git a/cadence/tests/get_positions_by_ids_test.cdc b/cadence/tests/get_positions_by_ids_test.cdc index cb2b8ef5..4648f3bc 100644 --- a/cadence/tests/get_positions_by_ids_test.cdc +++ b/cadence/tests/get_positions_by_ids_test.cdc @@ -65,20 +65,4 @@ fun test_getPositionsByIDs() { let singleDetails = getPositionsByIDs(positionIDs: [UInt64(0)]) Test.assertEqual(1, singleDetails.length) Test.assertEqual(details0.health, singleDetails[0].health) - - // --- Closed positions are silently skipped --- - // Close position 1, then request both IDs — should only return position 0 - closePosition(user: user, positionID: 1) - let afterClose = getPositionsByIDs(positionIDs: [UInt64(0), UInt64(1)]) - Test.assertEqual(1, afterClose.length) - Test.assertEqual(details0.health, afterClose[0].health) - - // --- All IDs closed/invalid returns empty array --- - closePosition(user: user, positionID: 0) - let allClosed = getPositionsByIDs(positionIDs: [UInt64(0), UInt64(1)]) - Test.assertEqual(0, allClosed.length) - - // --- Non-existent IDs are skipped --- - let nonExistent = getPositionsByIDs(positionIDs: [UInt64(999), UInt64(1000)]) - Test.assertEqual(0, nonExistent.length) } diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc index 3a2ac830..6afe0cfa 100644 --- a/cadence/tests/test_helpers.cdc +++ b/cadence/tests/test_helpers.cdc @@ -810,16 +810,6 @@ fun getPositionsByIDs(positionIDs: [UInt64]): [FlowALPv0.PositionDetails] { return res.returnValue as! [FlowALPv0.PositionDetails] } -access(all) -fun tryGetPositionDetails(pid: UInt64): FlowALPv0.PositionDetails? { - let res = _executeScript( - "../scripts/flow-alp/try_get_position_details.cdc", - [pid] - ) - Test.expect(res, Test.beSucceeded()) - return res.returnValue as! FlowALPv0.PositionDetails? -} - access(all) fun closePosition(user: Test.TestAccount, positionID: UInt64) { let res = _executeTransaction( diff --git a/cadence/tests/try_get_position_details_test.cdc b/cadence/tests/try_get_position_details_test.cdc deleted file mode 100644 index 4ba896fe..00000000 --- a/cadence/tests/try_get_position_details_test.cdc +++ /dev/null @@ -1,66 +0,0 @@ -import Test -import BlockchainHelpers - -import "MOET" -import "FlowALPv0" -import "test_helpers.cdc" - -// ----------------------------------------------------------------------------- -// tryGetPositionDetails Test -// -// Verifies that Pool.tryGetPositionDetails() returns position details for -// existing positions and nil for non-existent or closed positions. -// ----------------------------------------------------------------------------- - -access(all) -fun setup() { - deployContracts() -} - -// ============================================================================= -// Test: tryGetPositionDetails returns details for open positions and nil otherwise -// ============================================================================= -access(all) -fun test_tryGetPositionDetails() { - // --- Setup --- - setMockOraclePrice(signer: PROTOCOL_ACCOUNT, forTokenIdentifier: FLOW_TOKEN_IDENTIFIER, price: 1.0) - - createAndStorePool(signer: PROTOCOL_ACCOUNT, defaultTokenIdentifier: MOET_TOKEN_IDENTIFIER, beFailed: false) - addSupportedTokenZeroRateCurve( - signer: PROTOCOL_ACCOUNT, - tokenTypeIdentifier: FLOW_TOKEN_IDENTIFIER, - collateralFactor: 0.8, - borrowFactor: 1.0, - depositRate: 1_000_000.0, - depositCapacityCap: 1_000_000.0 - ) - - let user = Test.createAccount() - setupMoetVault(user, beFailed: false) - mintFlow(to: user, amount: 10_000.0) - - // --- Non-existent position returns nil --- - let nonExistent = tryGetPositionDetails(pid: 0) - Test.assertEqual(nil, nonExistent) - - // --- Open a position --- - createPosition(signer: user, amount: 100.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: false) - - // --- Existing position returns details --- - let details = tryGetPositionDetails(pid: 0) - Test.assert(details != nil, message: "Expected non-nil details for open position") - - // --- Result matches getPositionDetails --- - let expected = getPositionDetails(pid: 0, beFailed: false) - Test.assertEqual(expected.health, details!.health) - Test.assertEqual(expected.balances.length, details!.balances.length) - - // --- Still nil for non-existent ID --- - let stillNil = tryGetPositionDetails(pid: 999) - Test.assertEqual(nil, stillNil) - - // --- Close the position, should return nil --- - closePosition(user: user, positionID: 0) - let afterClose = tryGetPositionDetails(pid: 0) - Test.assertEqual(nil, afterClose) -}