Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cadence/contracts/FlowALPv0.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,11 @@ access(all) contract FlowALPv0 {
)
}

/// Returns the IDs of all currently open positions in this pool
access(all) fun getPositionIDs(): [UInt64] {
Comment thread
illia-malachyn marked this conversation as resolved.
Outdated
Comment thread
nialexsan marked this conversation as resolved.
Outdated
return self.positions.keys
}

/// Returns the details of a given position as a PositionDetails external struct
access(all) fun getPositionDetails(pid: UInt64): PositionDetails {
if self.debugLogging {
Expand Down
16 changes: 8 additions & 8 deletions cadence/scripts/flow-alp/get_position_by_id.cdc
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Returns the details of a specific position by its ID.
import "FlowALPv0"

access(all) fun main(poolAddress: Address, positionID: UInt64): FlowALPv0.PositionDetails {
let account = getAccount(poolAddress)
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)")

let poolRef = account.capabilities
.borrow<&FlowALPv0.Pool>(FlowALPv0.PoolPublicPath)
?? panic("Could not borrow Pool reference from \(poolAddress)")

return poolRef.getPositionDetails(pid: positionID)
}
return pool.getPositionDetails(pid: positionID)
}
11 changes: 11 additions & 0 deletions cadence/scripts/flow-alp/get_position_ids.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Returns the IDs of all currently open positions in the pool.
import "FlowALPv0"

Comment thread
illia-malachyn marked this conversation as resolved.
access(all) fun main(): [UInt64] {
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.getPositionIDs()
}
102 changes: 102 additions & 0 deletions cadence/tests/get_position_ids_test.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import Test
import BlockchainHelpers

import "MOET"
import "FlowALPv0"
import "test_helpers.cdc"

// -----------------------------------------------------------------------------
// getPositionIDs Test
//
// Verifies that Pool.getPositionIDs() correctly reflects opened and closed
// positions via the get_position_ids.cdc script.
// -----------------------------------------------------------------------------

access(all) var snapshot: UInt64 = 0
Comment thread
illia-malachyn marked this conversation as resolved.
Outdated

access(all)
fun setup() {
deployContracts()
snapshot = getCurrentBlockHeight()
}

// =============================================================================
// Test: getPositionIDs tracks opens and closes correctly
// =============================================================================
access(all)
fun test_getPositionIDs_lifecycle() {
// --- 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)

// --- No positions yet ---
var ids = getPositionIDs()
Test.assertEqual(0, ids.length)

// --- Open position 0 (with borrow) ---
createPosition(signer: user, amount: 100.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: true)

ids = getPositionIDs()
Test.assertEqual(1, ids.length)
Test.assert(ids.contains(UInt64(0)), message: "Expected position 0 in IDs")

// --- Open position 1 (with borrow) ---
createPosition(signer: user, amount: 100.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: true)

ids = getPositionIDs()
Test.assertEqual(2, ids.length)
Test.assert(ids.contains(UInt64(0)), message: "Expected position 0 in IDs")
Test.assert(ids.contains(UInt64(1)), message: "Expected position 1 in IDs")

// --- Open position 2 (no borrow, so closing won't need MOET repay) ---
createPosition(signer: user, amount: 100.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: false)

ids = getPositionIDs()
Test.assertEqual(3, ids.length)
Test.assert(ids.contains(UInt64(2)), message: "Expected position 2 in IDs")

// --- Close position 2 (no debt, straightforward) ---
closePosition(user: user, positionID: 2)

ids = getPositionIDs()
Test.assertEqual(2, ids.length)
Test.assert(!ids.contains(UInt64(2)), message: "Position 2 should be removed after close")
Test.assert(ids.contains(UInt64(0)), message: "Position 0 should still exist")
Test.assert(ids.contains(UInt64(1)), message: "Position 1 should still exist")

// --- Close position 0 (has debt, repay needed) ---
closePosition(user: user, positionID: 0)

ids = getPositionIDs()
Test.assertEqual(1, ids.length)
Test.assert(!ids.contains(UInt64(0)), message: "Position 0 should be removed after close")
Test.assert(ids.contains(UInt64(1)), message: "Position 1 should still exist")

// --- Open position 3 (new position after some closures) ---
createPosition(signer: user, amount: 100.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: true)

ids = getPositionIDs()
Test.assertEqual(2, ids.length)
Test.assert(ids.contains(UInt64(1)), message: "Position 1 should still exist")
Test.assert(ids.contains(UInt64(3)), message: "Expected position 3 in IDs")

// --- Close remaining positions ---
closePosition(user: user, positionID: 1)
closePosition(user: user, positionID: 3)

ids = getPositionIDs()
Test.assertEqual(0, ids.length)
}
20 changes: 20 additions & 0 deletions cadence/tests/test_helpers.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,26 @@ fun withdrawReserve(
Test.expect(txRes, beFailed ? Test.beFailed() : Test.beSucceeded())
}

access(all)
fun getPositionIDs(): [UInt64] {
let res = _executeScript(
"../scripts/flow-alp/get_position_ids.cdc",
[]
)
Test.expect(res, Test.beSucceeded())
return res.returnValue as! [UInt64]
}

access(all)
fun closePosition(user: Test.TestAccount, positionID: UInt64) {
let res = _executeTransaction(
"../transactions/flow-alp/position/repay_and_close_position.cdc",
[positionID],
user
)
Test.expect(res, Test.beSucceeded())
}

/* --- Assertion Helpers --- */

access(all) fun equalWithinVariance(_ expected: AnyStruct, _ actual: AnyStruct): Bool {
Expand Down
Loading