Skip to content

Liquidation edge cases#181

Open
mts1715 wants to merge 8 commits intomainfrom
taras/173-liquidation-edge-cases
Open

Liquidation edge cases#181
mts1715 wants to merge 8 commits intomainfrom
taras/173-liquidation-edge-cases

Conversation

@mts1715
Copy link
Contributor

@mts1715 mts1715 commented Feb 25, 2026

Closes: #173

Note: should be reviewed after merging #172
Some of proposed test in task weren't implemented because Flow doesn't have gas-price-based ordering at all.

Summary

Adds mainnet fork tests for liquidation edge cases: partial sequences, multi-collateral seizure, DEX liquidity failures, oracle-deviation circuit breaker, fee accrual over time, and bad debt handling.

Tests added (fork_liquidation_edge_cases.cdc)

  1. testPartialLiquidationSequences

Five positions with distinct collateral types (FLOW, USDF, USDC, WETH, WBTC), each borrowing MOET at health ≈ 1.1. After a FLOW price crash, only the FLOW position becomes unhealthy (health 0.95). A liquidator partially restores it across three sequential calls (seize 10 / repay 20 MOET each), stepping health through 0.967 → 0.985 → 1.005. A fourth call and a second liquidator's attempt both revert once the position is healthy. Verifies that positions backed by unaffected collateral are untouched.

  1. testLiquidateMultiCollateralChooseUSDC

A single position holds FLOW + USDC + WETH as collateral with USDF debt (health ≈ 1.109). After a FLOW crash ($1.00 → $0.75), the position drops to health ≈ 0.935. The liquidator selectively seizes USDC (seize 40 USDC, repay 55 USDF) while FLOW and WETH balances remain untouched. Validates that a liquidator can choose the optimal collateral without disturbing other assets.

  1. testDexLiquidityConstraints

A MockDexSwapper vault is seeded with only 50% of the required repayment tokens (23 USDF instead of 46). The batch DEX liquidation reverts atomically, leaving position state unchanged. After topping up the DEX vault to 53 USDF, the identical parameters succeed. Verifies that insufficient DEX liquidity causes a clean, state-preserving failure rather than a partial execution.

  1. testLiquidationSlippageConstraints

Governance tightens dexOracleDeviationBps from the default 300 bps to 200 bps. Two manual liquidation attempts use the same seize/repay amounts but different DEX price ratios:

Scenario 1 (priceRatio 0.7275, deviation ≈ 309 bps > 200 bps max) → reverts, position unchanged.
Scenario 2 (priceRatio 0.7425, deviation ≈ 101 bps < 200 bps max) → succeeds, post-health ≈ 1.036.
Validates the oracle-deviation guard that prevents liquidators from extracting value at stale DEX prices.

  1. testStabilityAndInsuranceFeeAccrual

Sets a 10% annual fixed interest rate on USDF with 10% stability fee and 10% insurance fee. An LP deposits 5000 USDF; a borrower takes 130 USDF against 200 FLOW. After Test.moveTime(by: ONE_YEAR), debt compounds to ≈ 143.67 USDF (continuous compounding: 130 × e^0.10). A liquidator then partially restores health. Fee collection is verified:

Stability fund receives ≈ 0.705 USDF (debitBalance 67 × (e^0.10 − 1) × 10%)
Insurance fund receives ≈ 0.705 MOET (swapped 1:1 via MockDex)
LP earns ≈ 416.435 USDF credit income (5000 × (e^0.08 − 1) — FixedRate applies creditRate to the full LP deposit, not just outstanding debt)

…dation - fork_multiple_positions_per_user.cdc covering three scenarios:

- Multiple positions with distinct collateral types (FLOW, USDF, USDC,
  WETH, WBTC) and isolation guarantees between them
- Cross-position effects through shared liquidity pools
- Batch liquidation of 4 positions (2 full, 2 partial) in a single tx
…eates

100 positions across three collateral types (50 USDF, 45 USDC, 5 WBTC),
crashes all collateral prices 40% simultaneously, and batch-liquidates all
positions via MockDexSwapper in chunks of 10 to stay within computation limits.
…ion-per-user-scenarios-testing

# Conflicts:
#	flow.json
- Partial liquidation sequences across multi-collateral positions
- Selective collateral seizure in multi-asset positions
- Atomic DEX liquidation failure on insufficient vault liquidity
- Oracle-deviation circuit breaker (slippage > dexOracleDeviationBps reverts)
- Stability and insurance fee accrual over 1 year with continuous compounding
- Bad debt handling: zombie position after complete collateral seizure
@mts1715 mts1715 requested a review from a team as a code owner February 25, 2026 19:48
@mts1715 mts1715 self-assigned this Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Liquidation Edge Cases

1 participant