Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ FlowALP/

- `FungibleToken.Vault`: Standard token operations
- `DeFiActions.Sink/Source`: DeFi protocol composability
- Entitlements: `FlowALPv0.EParticipant`, `FlowALPv0.EPosition`, `FlowALPv0.EGovernance`, `FlowALPv0.ERebalance`
- Entitlements: `FlowALPModels.EParticipant`, `FlowALPModels.EPosition`, `FlowALPModels.EGovernance`, `FlowALPModels.ERebalance`

## 🛠️ Development

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ fun testRecursiveWithdrawSource() {
// In this test, the topUpSource behavior is adversarial: it attempts to re-enter
// the pool during the pull/deposit flow. We expect the transaction to fail.
let withdrawRes = executeTransaction(
"./transactions/flow-alp/pool-management/withdraw_from_position.cdc",
"./transactions/flow-alp/epositionadmin/withdraw_from_position.cdc",
[positionID, flowTokenIdentifier, 1500.0, true], // pullFromTopUpSource: true
userAccount
)
Expand Down
2 changes: 1 addition & 1 deletion cadence/tests/adversarial_type_spoofing_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fun testMaliciousSource() {

// withdraw 1337 Flow from the position
let withdrawRes = executeTransaction(
"./transactions/flow-alp/pool-management/withdraw_from_position.cdc",
"./transactions/flow-alp/epositionadmin/withdraw_from_position.cdc",
[1 as UInt64, flowTokenIdentifier, 1337.0, true],
hackerAccount
)
Expand Down
2 changes: 1 addition & 1 deletion cadence/tests/async_update_position_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fun testUpdatePosition() {
depositToPosition(signer: user, positionID: 0, amount: 600.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: false)

let updatePositionRes = _executeTransaction(
"./transactions/flow-alp/pool-management/async_update_position.cdc",
"./transactions/flow-alp/eimplementation/async_update_position.cdc",
[ 0 as UInt64 ],
PROTOCOL_ACCOUNT
)
Expand Down
810 changes: 778 additions & 32 deletions cadence/tests/cap_test.cdc

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions cadence/tests/insurance_swapper_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ access(all)
fun test_setInsuranceSwapper_wrongOutputType_fails() {
// try to set a swapper that doesn't output MOET (outputs FLOW_TOKEN_IDENTIFIER instead)
let res = _executeTransaction(
"./transactions/flow-alp/pool-governance/set_insurance_swapper_mock.cdc",
"./transactions/flow-alp/egovernance/set_insurance_swapper_mock.cdc",
[MOET_TOKEN_IDENTIFIER, 1.0, MOET_TOKEN_IDENTIFIER, FLOW_TOKEN_IDENTIFIER],
PROTOCOL_ACCOUNT
)
Expand All @@ -199,7 +199,7 @@ access(all)
fun test_setInsuranceSwapper_wrongInputType_fails() {
// try to set a swapper with wrong input type (FLOW_TOKEN_IDENTIFIER instead of MOET_TOKEN_IDENTIFIER)
let res = _executeTransaction(
"./transactions/flow-alp/pool-governance/set_insurance_swapper_mock.cdc",
"./transactions/flow-alp/egovernance/set_insurance_swapper_mock.cdc",
[MOET_TOKEN_IDENTIFIER, 1.0, FLOW_TOKEN_IDENTIFIER, MOET_TOKEN_IDENTIFIER],
PROTOCOL_ACCOUNT
)
Expand Down
6 changes: 3 additions & 3 deletions cadence/tests/liquidation_phase1_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ fun testManualLiquidation_repaymentVaultCollateralType() {
let repayAmount = debtBalance + 0.001
let seizeAmount = (repayAmount / newPrice) * 0.99
let liqRes = _executeTransaction(
"../tests/transactions/flow-alp/pool-management/manual_liquidation_chosen_vault.cdc",
"../tests/transactions/flow-alp/helpers/manual_liquidation_chosen_vault.cdc",
[pid, Type<@MOET.Vault>().identifier, FLOW_TOKEN_IDENTIFIER, FLOW_TOKEN_IDENTIFIER, seizeAmount, repayAmount],
liquidator
)
Expand Down Expand Up @@ -567,7 +567,7 @@ fun testManualLiquidation_repaymentVaultTypeMismatch() {
let repayAmount = debtBalance + 0.001
let seizeAmount = (repayAmount / newPrice) * 0.99
let liqRes = _executeTransaction(
"../tests/transactions/flow-alp/pool-management/manual_liquidation_chosen_vault.cdc",
"../tests/transactions/flow-alp/helpers/manual_liquidation_chosen_vault.cdc",
[pid, Type<@MOET.Vault>().identifier, MOCK_YIELD_TOKEN_IDENTIFIER, FLOW_TOKEN_IDENTIFIER, seizeAmount, repayAmount],
liquidator
)
Expand Down Expand Up @@ -622,7 +622,7 @@ fun testManualLiquidation_unsupportedDebtType() {
let repayAmount = debtBalance + 0.001
let seizeAmount = (repayAmount / newPrice) * 0.99
let liqRes = _executeTransaction(
"../tests/transactions/flow-alp/pool-management/manual_liquidation_chosen_vault.cdc",
"../tests/transactions/flow-alp/helpers/manual_liquidation_chosen_vault.cdc",
[pid, MOCK_YIELD_TOKEN_IDENTIFIER, MOCK_YIELD_TOKEN_IDENTIFIER, FLOW_TOKEN_IDENTIFIER, seizeAmount, repayAmount],
liquidator
)
Expand Down
8 changes: 8 additions & 0 deletions cadence/tests/pool_pause_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ fun setup() {
depositRate: 1_000_000.0,
depositCapacityCap: 1_000_000.0
)
// Grant PROTOCOL_ACCOUNT an EGovernance cap so setPoolPauseState (cap-based) works.
let grantResult = Test.executeTransaction(Test.Transaction(
code: Test.readFile("./transactions/flow-alp/setup/grant_egovernance_cap.cdc"),
authorizers: [PROTOCOL_ACCOUNT.address, PROTOCOL_ACCOUNT.address],
signers: [PROTOCOL_ACCOUNT],
arguments: []
))
Test.expect(grantResult, Test.beSucceeded())
snapshot = getCurrentBlockHeight()
}

Expand Down
4 changes: 2 additions & 2 deletions cadence/tests/position_lifecycle_unhappy_test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ fun testPositionLifecycleBelowMinimumDeposit() {
setMinimumTokenBalancePerPosition(signer: PROTOCOL_ACCOUNT, tokenTypeIdentifier: FLOW_TOKEN_IDENTIFIER, minimum: minimum)

// position id to use for tests
let positionId = 0 as UInt64
let positionId: UInt64 = 0

// user prep
let user = Test.createAccount()
setupMoetVault(user, beFailed: false)
mintFlow(to: user, amount: 1_000.0)
Test.expect(mintFlow(to: user, amount: 1_000.0), Test.beSucceeded())

// Grant beta access to user so they can create positions
grantBetaPoolParticipantAccess(PROTOCOL_ACCOUNT, user)
Expand Down
20 changes: 12 additions & 8 deletions cadence/tests/test_helpers.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ access(all)
fun grantBetaPoolParticipantAccess(_ admin: Test.TestAccount, _ grantee: Test.TestAccount) {
let signers = admin.address == grantee.address ? [admin] : [admin, grantee]
let betaTxn = Test.Transaction(
code: Test.readFile("./transactions/flow-alp/pool-management/03_grant_beta.cdc"),
code: Test.readFile("./transactions/flow-alp/setup/grant_beta_cap.cdc"),
authorizers: [admin.address, grantee.address],
signers: signers,
arguments: []
Expand Down Expand Up @@ -398,7 +398,7 @@ fun getIsLiquidatable(pid: UInt64): Bool {
access(all)
fun createAndStorePool(signer: Test.TestAccount, defaultTokenIdentifier: String, beFailed: Bool) {
let createRes = _executeTransaction(
"transactions/flow-alp/pool-factory/create_and_store_pool.cdc",
"./transactions/flow-alp/setup/create_and_store_pool.cdc",
[defaultTokenIdentifier],
signer
)
Expand Down Expand Up @@ -552,7 +552,7 @@ fun setPoolPauseState(
pause: Bool
): Test.TransactionResult {
return _executeTransaction(
"./transactions/flow-alp/pool-governance/set_pool_paused.cdc",
"./transactions/flow-alp/egovernance/set_pool_paused.cdc",
[pause],
signer
)
Expand Down Expand Up @@ -697,7 +697,7 @@ fun setInsuranceSwapper(
priceRatio: UFix64,
): Test.TransactionResult {
let res = _executeTransaction(
"./transactions/flow-alp/pool-governance/set_insurance_swapper_mock.cdc",
"./transactions/flow-alp/egovernance/set_insurance_swapper_mock.cdc",
[ tokenTypeIdentifier, priceRatio, tokenTypeIdentifier, MOET_TOKEN_IDENTIFIER],
signer
)
Expand All @@ -710,7 +710,7 @@ fun removeInsuranceSwapper(
tokenTypeIdentifier: String,
): Test.TransactionResult {
let res = _executeTransaction(
"./transactions/flow-alp/pool-governance/remove_insurance_swapper.cdc",
"./transactions/flow-alp/egovernance/remove_insurance_swapper.cdc",
[ tokenTypeIdentifier],
signer
)
Expand Down Expand Up @@ -1014,8 +1014,12 @@ fun getCreditBalanceForType(details: FlowALPModels.PositionDetails, vaultType: T
return 0.0
}

access(all) fun getLastPositionId(): UInt64 {
access(all)
fun getLastPositionId(): UInt64 {
var openEvents = Test.eventsOfType(Type<FlowALPEvents.Opened>())
let pid = (openEvents[openEvents.length - 1] as! FlowALPEvents.Opened).pid
return pid
if openEvents.length > 0 {
let pid = (openEvents[openEvents.length - 1] as! FlowALPEvents.Opened).pid
return pid
}
return 0
}
18 changes: 0 additions & 18 deletions cadence/tests/transactions/flow-alp/beta/publish_beta_cap.cdc

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import "FlowALPv0"
import "FlowALPModels"
import "FlowALPInterestRates"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.addSupportedToken.
/// Adds a token with a zero-rate interest curve (0% APY).
transaction(
tokenTypeIdentifier: String,
collateralFactor: UFix64,
borrowFactor: UFix64,
depositRate: UFix64,
depositCapacityCap: UFix64
) {
let tokenType: Type
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.addSupportedToken(
tokenType: self.tokenType,
collateralFactor: collateralFactor,
borrowFactor: borrowFactor,
interestCurve: FlowALPInterestRates.FixedCurve(yearlyRate: 0.0),
depositRate: depositRate,
depositCapacityCap: depositCapacityCap
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import "FlowALPv0"
import "FlowALPModels"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.collectInsurance.
transaction(tokenTypeIdentifier: String) {
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool
let tokenType: Type

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier: \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.collectInsurance(tokenType: self.tokenType)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import "FlowALPv0"
import "FlowALPModels"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.collectStability.
transaction(tokenTypeIdentifier: String) {
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool
let tokenType: Type

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier: \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.collectStability(tokenType: self.tokenType)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import "FlowALPv0"
import "FlowALPModels"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.setDepositLimitFraction.
transaction(
tokenTypeIdentifier: String,
fraction: UFix64
) {
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool
let tokenType: Type

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.setDepositLimitFraction(tokenType: self.tokenType, fraction: fraction)
}
}
24 changes: 24 additions & 0 deletions cadence/tests/transactions/flow-alp/egovernance/set_dex.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import "DeFiActions"
import "FlowALPv0"
import "FlowALPModels"
import "MockDexSwapper"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.borrowConfig,
/// enabling the governance holder to set the DEX via the config.
/// Uses MockDexSwapper.SwapperProvider as the DEX implementation.
transaction {
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool

prepare(signer: auth(BorrowValue) &Account) {
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.borrowConfig().setDex(MockDexSwapper.SwapperProvider())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import "FlowALPv0"
import "FlowALPModels"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.setInsuranceRate.
transaction(
tokenTypeIdentifier: String,
insuranceRate: UFix64
) {
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool
let tokenType: Type

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.setInsuranceRate(tokenType: self.tokenType, insuranceRate: insuranceRate)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import "FlowALPv0"
import "FlowALPModels"
import "FlowALPInterestRates"

/// TEST TRANSACTION - DO NOT USE IN PRODUCTION
///
/// Verifies that auth(EGovernance) &Pool grants access to Pool.setInterestCurve.
/// Sets a FixedCurve with the given yearly rate.
transaction(
tokenTypeIdentifier: String,
yearlyRate: UFix128
) {
let tokenType: Type
let pool: auth(FlowALPModels.EGovernance) &FlowALPv0.Pool

prepare(signer: auth(BorrowValue) &Account) {
self.tokenType = CompositeType(tokenTypeIdentifier)
?? panic("Invalid tokenTypeIdentifier \(tokenTypeIdentifier)")
let cap = signer.storage.borrow<&Capability<auth(FlowALPModels.EGovernance) &FlowALPv0.Pool>>(
from: FlowALPv0.PoolCapStoragePath
) ?? panic("No EGovernance cap found")
self.pool = cap.borrow() ?? panic("Could not borrow Pool from EGovernance cap")
}

execute {
self.pool.setInterestCurve(
tokenType: self.tokenType,
interestCurve: FlowALPInterestRates.FixedCurve(yearlyRate: yearlyRate)
)
}
}
Loading
Loading