Skip to content

Commit 8621e16

Browse files
committed
Update tests.rs
1 parent cd1ba14 commit 8621e16

File tree

1 file changed

+112
-33
lines changed

1 file changed

+112
-33
lines changed

pallets/swap/src/pallet/tests.rs

Lines changed: 112 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,6 @@ fn test_swap_subtoken_disabled() {
19821982
});
19831983
}
19841984

1985-
/// V3 path: protocol + user positions exist, fees accrued, everything must be removed.
19861985
#[test]
19871986
fn test_liquidate_v3_removes_positions_ticks_and_state() {
19881987
new_test_ext().execute_with(|| {
@@ -1992,7 +1991,7 @@ fn test_liquidate_v3_removes_positions_ticks_and_state() {
19921991
assert_ok!(Pallet::<Test>::maybe_initialize_v3(netuid));
19931992
assert!(SwapV3Initialized::<Test>::get(netuid));
19941993

1995-
// Enable user LP (mock usually enables for 0..=100, but be explicit and consistent)
1994+
// Enable user LP
19961995
assert_ok!(Swap::toggle_user_liquidity(
19971996
RuntimeOrigin::root(),
19981997
netuid.into(),
@@ -2041,14 +2040,14 @@ fn test_liquidate_v3_removes_positions_ticks_and_state() {
20412040
assert!(Ticks::<Test>::get(netuid, TickIndex::MAX).is_some());
20422041
assert!(CurrentLiquidity::<Test>::get(netuid) > 0);
20432042

2044-
// There should be some bitmap words (active ticks) after adding a position.
20452043
let had_bitmap_words = TickIndexBitmapWords::<Test>::iter_prefix((netuid,))
20462044
.next()
20472045
.is_some();
20482046
assert!(had_bitmap_words);
20492047

2050-
// ACT: Liquidate & reset swap state
2048+
// ACT: users-only liquidation then protocol clear
20512049
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
2050+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
20522051

20532052
// ASSERT: positions cleared (both user and protocol)
20542053
assert_eq!(
@@ -2091,12 +2090,11 @@ fn test_liquidate_v3_removes_positions_ticks_and_state() {
20912090
});
20922091
}
20932092

2094-
/// V3 path with user liquidity disabled at teardown: must still remove all positions and clear state.
2093+
/// V3 path with user liquidity disabled at teardown:
2094+
/// must still remove positions and clear state (after protocol clear).
20952095
#[test]
20962096
fn test_liquidate_v3_with_user_liquidity_disabled() {
20972097
new_test_ext().execute_with(|| {
2098-
// Pick a netuid the mock treats as "disabled" by default (per your comment >100),
2099-
// then explicitly walk through enable -> add -> disable -> liquidate.
21002098
let netuid = NetUid::from(101);
21012099

21022100
assert_ok!(Pallet::<Test>::maybe_initialize_v3(netuid));
@@ -2125,15 +2123,16 @@ fn test_liquidate_v3_with_user_liquidity_disabled() {
21252123
)
21262124
.expect("add liquidity");
21272125

2128-
// Disable user LP *before* liquidation to validate that removal ignores this flag.
2126+
// Disable user LP *before* liquidation; removal must ignore this flag.
21292127
assert_ok!(Swap::toggle_user_liquidity(
21302128
RuntimeOrigin::root(),
21312129
netuid.into(),
21322130
false
21332131
));
21342132

2135-
// ACT
2133+
// Users-only dissolve, then clear protocol liquidity/state.
21362134
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
2135+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
21372136

21382137
// ASSERT: positions & ticks gone, state reset
21392138
assert_eq!(
@@ -2158,7 +2157,7 @@ fn test_liquidate_v3_with_user_liquidity_disabled() {
21582157
assert!(!FeeGlobalTao::<Test>::contains_key(netuid));
21592158
assert!(!FeeGlobalAlpha::<Test>::contains_key(netuid));
21602159

2161-
// `EnabledUserLiquidity` is removed by liquidation.
2160+
// `EnabledUserLiquidity` is removed by protocol clear stage.
21622161
assert!(!EnabledUserLiquidity::<Test>::contains_key(netuid));
21632162
});
21642163
}
@@ -2205,7 +2204,6 @@ fn test_liquidate_non_v3_uninitialized_ok_and_clears() {
22052204
});
22062205
}
22072206

2208-
/// Idempotency: calling liquidation twice is safe (both V3 and non‑V3 flavors).
22092207
#[test]
22102208
fn test_liquidate_idempotent() {
22112209
// V3 flavor
@@ -2230,11 +2228,14 @@ fn test_liquidate_idempotent() {
22302228
123_456_789
22312229
));
22322230

2233-
// 1st liquidation
2231+
// Users-only liquidations are idempotent.
22342232
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
2235-
// 2nd liquidation (no state left) — must still succeed
22362233
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
22372234

2235+
// Now clear protocol liquidity/state—also idempotent.
2236+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2237+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2238+
22382239
// State remains empty
22392240
assert!(
22402241
Positions::<Test>::iter_prefix_values((netuid, OK_COLDKEY_ACCOUNT_ID))
@@ -2254,7 +2255,7 @@ fn test_liquidate_idempotent() {
22542255
new_test_ext().execute_with(|| {
22552256
let netuid = NetUid::from(8);
22562257

2257-
// Never initialize V3
2258+
// Never initialize V3; both calls no-op and succeed.
22582259
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
22592260
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
22602261

@@ -2286,7 +2287,7 @@ fn liquidate_v3_refunds_user_funds_and_clears_state() {
22862287
));
22872288
assert_ok!(Pallet::<Test>::maybe_initialize_v3(netuid));
22882289

2289-
// Use distinct cold/hot to demonstrate alpha refund goes to (owner, owner).
2290+
// Use distinct cold/hot to demonstrate alpha refund/stake accounting.
22902291
let cold = OK_COLDKEY_ACCOUNT_ID;
22912292
let hot = OK_HOTKEY_ACCOUNT_ID;
22922293

@@ -2322,25 +2323,27 @@ fn liquidate_v3_refunds_user_funds_and_clears_state() {
23222323
<Test as Config>::BalanceOps::increase_provided_tao_reserve(netuid.into(), tao_taken);
23232324
<Test as Config>::BalanceOps::increase_provided_alpha_reserve(netuid.into(), alpha_taken);
23242325

2325-
// Liquidate everything on the subnet.
2326+
// Users‑only liquidation.
23262327
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
23272328

23282329
// Expect balances restored to BEFORE snapshots (no swaps ran -> zero fees).
2329-
// TAO: we withdrew 'need_tao' above and liquidation refunded it, so we should be back to 'tao_before'.
23302330
let tao_after = <Test as Config>::BalanceOps::tao_balance(&cold);
23312331
assert_eq!(tao_after, tao_before, "TAO principal must be refunded");
23322332

2333-
// ALPHA: refund is credited to (coldkey=cold, hotkey=cold). Compare totals across both ledgers.
2333+
// ALPHA totals conserved to owner (distribution may differ).
23342334
let alpha_after_hot =
23352335
<Test as Config>::BalanceOps::alpha_balance(netuid.into(), &cold, &hot);
23362336
let alpha_after_owner =
23372337
<Test as Config>::BalanceOps::alpha_balance(netuid.into(), &cold, &cold);
23382338
let alpha_after_total = alpha_after_hot + alpha_after_owner;
23392339
assert_eq!(
23402340
alpha_after_total, alpha_before_total,
2341-
"ALPHA principal must be refunded to the account (may be credited to (owner, owner))"
2341+
"ALPHA principal must be refunded/staked for the account (check totals)"
23422342
);
23432343

2344+
// Clear protocol liquidity and V3 state now.
2345+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2346+
23442347
// User position(s) are gone and all V3 state cleared.
23452348
assert_eq!(Pallet::<Test>::count_positions(netuid, &cold), 0);
23462349
assert!(Ticks::<Test>::iter_prefix(netuid).next().is_none());
@@ -2386,20 +2389,23 @@ fn refund_alpha_single_provider_exact() {
23862389
.expect("decrease ALPHA");
23872390
<Test as Config>::BalanceOps::increase_provided_alpha_reserve(netuid.into(), alpha_taken);
23882391

2389-
// --- Act: dissolve (calls refund_alpha inside).
2392+
// --- Act: users‑only dissolve.
23902393
assert_ok!(Pallet::<Test>::do_dissolve_all_liquidity_providers(netuid));
23912394

2392-
// --- Assert: refunded back to the owner (may credit to (cold,cold)).
2395+
// --- Assert: total α conserved to owner (may be staked to validator).
23932396
let alpha_after_hot =
23942397
<Test as Config>::BalanceOps::alpha_balance(netuid.into(), &cold, &hot);
23952398
let alpha_after_owner =
23962399
<Test as Config>::BalanceOps::alpha_balance(netuid.into(), &cold, &cold);
23972400
let alpha_after_total = alpha_after_hot + alpha_after_owner;
23982401
assert_eq!(
23992402
alpha_after_total, alpha_before_total,
2400-
"ALPHA principal must be conserved to the owner"
2403+
"ALPHA principal must be conserved to the account"
24012404
);
24022405

2406+
// Clear protocol liquidity and V3 state now.
2407+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2408+
24032409
// --- State is cleared.
24042410
assert!(Ticks::<Test>::iter_prefix(netuid).next().is_none());
24052411
assert_eq!(Pallet::<Test>::count_positions(netuid, &cold), 0);
@@ -2593,7 +2599,6 @@ fn test_dissolve_v3_green_path_refund_tao_stake_alpha_and_clear_state() {
25932599
<Test as Config>::BalanceOps::alpha_balance(netuid.into(), &cold, &validator_hotkey);
25942600

25952601
let alpha_before_total = if validator_hotkey == hot {
2596-
// Avoid double counting when validator == user's hotkey.
25972602
alpha_before_hot + alpha_before_owner
25982603
} else {
25992604
alpha_before_hot + alpha_before_owner + alpha_before_val
@@ -2635,13 +2640,10 @@ fn test_dissolve_v3_green_path_refund_tao_stake_alpha_and_clear_state() {
26352640
);
26362641

26372642
if validator_hotkey == hot {
2638-
// Net effect: user's hot ledger returns to its original balance.
26392643
assert_eq!(
26402644
alpha_after_hot, alpha_before_hot,
26412645
"When validator == hotkey, user's hot ledger must net back to its original balance"
26422646
);
2643-
2644-
// Totals without double-counting the same ledger.
26452647
let alpha_after_total = alpha_after_hot + alpha_after_owner;
26462648
assert_eq!(
26472649
alpha_after_total, alpha_before_total,
@@ -2659,23 +2661,22 @@ fn test_dissolve_v3_green_path_refund_tao_stake_alpha_and_clear_state() {
26592661

26602662
let hot_loss = alpha_before_hot - alpha_after_hot;
26612663
let val_gain = alpha_after_val - alpha_before_val;
2662-
26632664
assert_eq!(
26642665
val_gain, hot_loss,
26652666
"α that left the user's hot ledger must equal α credited to the validator ledger"
26662667
);
26672668

2668-
// Totals across distinct ledgers must be conserved.
26692669
let alpha_after_total = alpha_after_hot + alpha_after_owner + alpha_after_val;
26702670
assert_eq!(
26712671
alpha_after_total, alpha_before_total,
26722672
"Total α for the coldkey must be conserved"
26732673
);
26742674
}
26752675

2676-
// --- Assert: All positions (user + protocol) removed and V3 state cleared ---
2677-
let protocol_id = Pallet::<Test>::protocol_account_id();
2676+
// Now clear protocol liquidity & state and assert full reset.
2677+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
26782678

2679+
let protocol_id = Pallet::<Test>::protocol_account_id();
26792680
assert_eq!(Pallet::<Test>::count_positions(netuid, &cold), 0);
26802681
let prot_positions_after =
26812682
Positions::<Test>::iter_prefix_values((netuid, protocol_id)).collect::<Vec<_>>();
@@ -2684,7 +2685,6 @@ fn test_dissolve_v3_green_path_refund_tao_stake_alpha_and_clear_state() {
26842685
"protocol positions must be removed"
26852686
);
26862687

2687-
// Ticks / liquidity / price / flags cleared
26882688
assert!(Ticks::<Test>::iter_prefix(netuid).next().is_none());
26892689
assert!(Ticks::<Test>::get(netuid, TickIndex::MIN).is_none());
26902690
assert!(Ticks::<Test>::get(netuid, TickIndex::MAX).is_none());
@@ -2693,20 +2693,99 @@ fn test_dissolve_v3_green_path_refund_tao_stake_alpha_and_clear_state() {
26932693
assert!(!AlphaSqrtPrice::<Test>::contains_key(netuid));
26942694
assert!(!SwapV3Initialized::<Test>::contains_key(netuid));
26952695

2696-
// Fee globals cleared
26972696
assert!(!FeeGlobalTao::<Test>::contains_key(netuid));
26982697
assert!(!FeeGlobalAlpha::<Test>::contains_key(netuid));
26992698

2700-
// Active tick bitmap cleared
27012699
assert!(
27022700
TickIndexBitmapWords::<Test>::iter_prefix((netuid,))
27032701
.next()
27042702
.is_none(),
27052703
"active tick bitmap words must be cleared"
27062704
);
27072705

2706+
assert!(!FeeRate::<Test>::contains_key(netuid));
2707+
assert!(!EnabledUserLiquidity::<Test>::contains_key(netuid));
2708+
});
2709+
}
2710+
2711+
#[test]
2712+
fn test_clear_protocol_liquidity_green_path() {
2713+
new_test_ext().execute_with(|| {
2714+
// --- Arrange ---
2715+
let netuid = NetUid::from(55);
2716+
2717+
// Ensure the "user liquidity enabled" flag exists so we can verify it's removed later.
2718+
assert_ok!(Pallet::<Test>::toggle_user_liquidity(
2719+
RuntimeOrigin::root(),
2720+
netuid,
2721+
true
2722+
));
2723+
2724+
// Initialize V3 state; this should set price/tick flags and create a protocol position.
2725+
assert_ok!(Pallet::<Test>::maybe_initialize_v3(netuid));
2726+
assert!(
2727+
SwapV3Initialized::<Test>::get(netuid),
2728+
"V3 must be initialized"
2729+
);
2730+
2731+
// Sanity: protocol positions exist before clearing.
2732+
let protocol_id = Pallet::<Test>::protocol_account_id();
2733+
let prot_positions_before =
2734+
Positions::<Test>::iter_prefix_values((netuid, protocol_id)).collect::<Vec<_>>();
2735+
assert!(
2736+
!prot_positions_before.is_empty(),
2737+
"protocol positions should exist after V3 init"
2738+
);
2739+
2740+
// --- Act ---
2741+
// Green path: just clear protocol liquidity and wipe all V3 state.
2742+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2743+
2744+
// --- Assert: all protocol positions removed ---
2745+
let prot_positions_after =
2746+
Positions::<Test>::iter_prefix_values((netuid, protocol_id)).collect::<Vec<_>>();
2747+
assert!(
2748+
prot_positions_after.is_empty(),
2749+
"protocol positions must be removed by do_clear_protocol_liquidity"
2750+
);
2751+
2752+
// --- Assert: V3 data wiped (idempotent even if some maps were empty) ---
2753+
// Ticks / active tick bitmap
2754+
assert!(Ticks::<Test>::iter_prefix(netuid).next().is_none());
2755+
assert!(
2756+
TickIndexBitmapWords::<Test>::iter_prefix((netuid,))
2757+
.next()
2758+
.is_none(),
2759+
"active tick bitmap words must be cleared"
2760+
);
2761+
2762+
// Fee globals
2763+
assert!(!FeeGlobalTao::<Test>::contains_key(netuid));
2764+
assert!(!FeeGlobalAlpha::<Test>::contains_key(netuid));
2765+
2766+
// Price / tick / liquidity / flags
2767+
assert!(!AlphaSqrtPrice::<Test>::contains_key(netuid));
2768+
assert!(!CurrentTick::<Test>::contains_key(netuid));
2769+
assert!(!CurrentLiquidity::<Test>::contains_key(netuid));
2770+
assert!(!SwapV3Initialized::<Test>::contains_key(netuid));
2771+
27082772
// Knobs removed
27092773
assert!(!FeeRate::<Test>::contains_key(netuid));
27102774
assert!(!EnabledUserLiquidity::<Test>::contains_key(netuid));
2775+
2776+
// --- And it's idempotent ---
2777+
assert_ok!(Pallet::<Test>::do_clear_protocol_liquidity(netuid));
2778+
assert!(
2779+
Positions::<Test>::iter_prefix_values((netuid, protocol_id))
2780+
.next()
2781+
.is_none()
2782+
);
2783+
assert!(Ticks::<Test>::iter_prefix(netuid).next().is_none());
2784+
assert!(
2785+
TickIndexBitmapWords::<Test>::iter_prefix((netuid,))
2786+
.next()
2787+
.is_none()
2788+
);
2789+
assert!(!SwapV3Initialized::<Test>::contains_key(netuid));
27112790
});
27122791
}

0 commit comments

Comments
 (0)