Skip to content

Commit 3d93806

Browse files
committed
remove testDexLiquidityConstraints because it requires automated liquidation (not manual liquidation) which is not yet implemented
1 parent b035740 commit 3d93806

1 file changed

Lines changed: 8 additions & 81 deletions

File tree

cadence/tests/fork_liquidation_edge_cases.cdc

Lines changed: 8 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -464,87 +464,14 @@ fun testLiquidateMultiCollateralChooseUSDC() {
464464
// Scenario 1: DEX vault funded with 23 USDF (50% of 46 needed) -> liquidation reverts
465465
// Scenario 2: top up to 53 USDF (>=46) -> liquidation succeeds
466466
// =============================================================================
467-
access(all)
468-
fun testDexLiquidityConstraints() {
469-
safeReset()
470-
471-
// USDF liquidity provider
472-
let lpUser = Test.createAccount()
473-
transferTokensWithSetup(tokenIdentifier: MAINNET_USDF_TOKEN_ID, from: MAINNET_USDF_HOLDER, to: lpUser, amount: 5000.0)
474-
createPosition(admin: MAINNET_PROTOCOL_ACCOUNT, signer: lpUser, amount: 5000.0, vaultStoragePath: MAINNET_USDF_STORAGE_PATH, pushToDrawDownSink: false)
475-
476-
// Borrower: 200 FLOW @ $1.00 (CF=0.80), borrow 130 USDF
477-
// health = 200*1.0*0.80 / 130 = 160/130 ≈ 1.2308 (healthy)
478-
let user = Test.createAccount()
479-
var res = setupGenericVault(user, vaultIdentifier: MAINNET_USDF_TOKEN_ID)
480-
Test.expect(res, Test.beSucceeded())
481-
transferFlowTokens(to: user, amount: 200.0)
482-
createPosition(admin: MAINNET_PROTOCOL_ACCOUNT, signer: user, amount: 200.0, vaultStoragePath: FLOW_VAULT_STORAGE_PATH, pushToDrawDownSink: false)
483-
let pid = getLastPositionId()
484-
borrowFromPosition(signer: user, positionId: pid,
485-
tokenTypeIdentifier: MAINNET_USDF_TOKEN_ID, vaultStoragePath: MAINNET_USDF_STORAGE_PATH,
486-
amount: 130.0, beFailed: false)
487-
488-
let initialHealth = getPositionHealth(pid: pid, beFailed: false)
489-
Test.assert(initialHealth > 1.0, message: "Position should start healthy")
490-
491-
// FLOW crash: $1.00 -> $0.75; health = 120/130 ≈ 0.9231 (unhealthy)
492-
setMockOraclePrice(signer: MAINNET_PROTOCOL_ACCOUNT, forTokenIdentifier: MAINNET_FLOW_TOKEN_ID, price: 0.75)
493-
let crashedHealth = getPositionHealth(pid: pid, beFailed: false)
494-
Test.assert(crashedHealth < 1.0, message: "Position must be unhealthy after FLOW crash")
495-
496-
// Configure MockDexSwapper for FLOW -> USDF at price ratio 0.75.
497-
// DEX vault 23 USDF — 50% of the 46 required for repayment.
498-
transferTokensWithSetup(tokenIdentifier: MAINNET_USDF_TOKEN_ID, from: MAINNET_USDF_HOLDER, to: MAINNET_PROTOCOL_ACCOUNT, amount: 23.0)
499-
setMockDexPriceForPair(
500-
signer: MAINNET_PROTOCOL_ACCOUNT,
501-
inVaultIdentifier: MAINNET_FLOW_TOKEN_ID,
502-
outVaultIdentifier: MAINNET_USDF_TOKEN_ID,
503-
vaultSourceStoragePath: MAINNET_USDF_STORAGE_PATH,
504-
priceRatio: 0.75
505-
)
506-
507-
// Scenario 1: DEX has only 23 USDF, needs 46 — liquidation must revert atomically
508-
let failRes = liquidateViaMockDex(
509-
signer: MAINNET_PROTOCOL_ACCOUNT,
510-
pid: pid,
511-
debtVaultIdentifier: MAINNET_USDF_TOKEN_ID,
512-
seizeVaultIdentifier: MAINNET_FLOW_TOKEN_ID,
513-
seizeAmount: 55.0,
514-
repayAmount: 46.0,
515-
)
516-
Test.expect(failRes, Test.beFailed())
517-
518-
let healthAfterFail = getPositionHealth(pid: pid, beFailed: false)
519-
Test.assert(healthAfterFail < 1.0, message: "Position must remain unhealthy after failed DEX liquidation")
520-
521-
let detailsAfterFail = getPositionDetails(pid: pid, beFailed: false)
522-
Test.assertEqual(200.0, getCreditBalanceForType(details: detailsAfterFail, vaultType: CompositeType(MAINNET_FLOW_TOKEN_ID)!))
523-
Test.assertEqual(130.0, getDebitBalanceForType(details: detailsAfterFail, vaultType: CompositeType(MAINNET_USDF_TOKEN_ID)!))
524-
525-
// Scenario 2: top up DEX vault (+30 USDF, total 53 >= 46) — liquidation succeeds
526-
transferFungibleTokens(tokenIdentifier: MAINNET_USDF_TOKEN_ID, from: MAINNET_USDF_HOLDER, to: MAINNET_PROTOCOL_ACCOUNT, amount: 30.0)
527-
528-
let successRes = liquidateViaMockDex(
529-
signer: MAINNET_PROTOCOL_ACCOUNT,
530-
pid: pid,
531-
debtVaultIdentifier: MAINNET_USDF_TOKEN_ID,
532-
seizeVaultIdentifier: MAINNET_FLOW_TOKEN_ID,
533-
seizeAmount: 55.0,
534-
repayAmount: 46.0,
535-
)
536-
Test.expect(successRes, Test.beSucceeded())
537-
538-
// post-health = (200-55)*0.75*0.80 / (130-46) = 87/84 ≈ 1.036 (within 1.05 target)
539-
let postHealth = getPositionHealth(pid: pid, beFailed: false)
540-
Test.assert(postHealth > 1.0 && postHealth <= 1.05, message: "Position must be healthy after liquidation and not exceed liquidationTargetHF (1.05)")
541-
Test.assert(postHealth > crashedHealth)
542-
543-
// Verify seizure: 55 FLOW seized, 46 USDF repaid
544-
let detailsAfterLiq = getPositionDetails(pid: pid, beFailed: false)
545-
Test.assertEqual(145.0, getCreditBalanceForType(details: detailsAfterLiq, vaultType: CompositeType(MAINNET_FLOW_TOKEN_ID)!)) // 200 - 55 = 145
546-
Test.assertEqual(84.0, getDebitBalanceForType(details: detailsAfterLiq, vaultType: CompositeType(MAINNET_USDF_TOKEN_ID)!)) // 130 - 46 = 84
547-
}
467+
// access(all) fun testDexLiquidityConstraints()
468+
//
469+
// TODO: DEX Liquidity Constraints test should be implemented once automated liquidation
470+
// is in place. The relevant scenario is: a DEX vault is underfunded relative to the
471+
// debt repayment required, causing an automated liquidation to fail atomically, after
472+
// which topping up the DEX vault allows the same liquidation to succeed. This can only
473+
// be meaningfully tested when FlowALP itself invokes the DEX as part of its liquidation
474+
// code path, rather than the caller supplying pre-swapped funds via manualLiquidation.
548475

549476
// =============================================================================
550477
// Stability and Insurance Fee Accrual — fees not collected for liquidated funds

0 commit comments

Comments
 (0)