Skip to content

Commit 9bb9545

Browse files
committed
fix more purger tests
1 parent d04fa48 commit 9bb9545

File tree

4 files changed

+138
-78
lines changed

4 files changed

+138
-78
lines changed

src/mock/flash_liquidator.cairo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub mod flash_liquidator {
134134
fn provider_assets() -> Span<u128> {
135135
let mut asset_amts: Array<u128> = array![20 * WAD_ONE, // 20 (Wad) - ETH
136136
100000000, // 1 (10 ** 8) - BTC
137-
];
137+
0, 0];
138138
asset_amts.span()
139139
}
140140
}

src/tests/common.cairo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,10 @@ pub fn fund_user(user: ContractAddress, mut yangs: Span<ContractAddress>, mut as
248248
match yangs.pop_front() {
249249
Option::Some(yang) => {
250250
let amt = *asset_amts.pop_front().unwrap();
251-
if amt.is_non_zero() {
252-
IMintableDispatcher { contract_address: *yang }.mint(user, amt.into());
251+
if amt.is_zero() {
252+
continue;
253253
}
254+
IMintableDispatcher { contract_address: *yang }.mint(user, amt.into());
254255
},
255256
Option::None => { break; }
256257
};

src/tests/purger/test_purger.cairo

Lines changed: 128 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -229,107 +229,162 @@ mod test_purger {
229229
//
230230
// For low thresholds (arbitraily defined as 2% or less), the trove's debt is set based on the
231231
// value instead. See inline comments for more details.
232-
#[test]
233-
fn test_preview_liquidate_parametrized() {
234-
let classes = Option::Some(purger_utils::declare_contracts());
235-
236-
let mut thresholds: Span<Ray> = purger_utils::interesting_thresholds_for_liquidation();
237-
238-
let default_trove_debt: Wad = (WAD_ONE * 1000).into();
239-
240-
// non-recovery mode
241-
let mut expected_max_close_amts: Span<Wad> = array![
232+
fn preview_liquidate_expected_max_close_amts() -> Span<Wad> {
233+
array![
242234
1_u128.into(), // 1 wei (0% threshold)
243235
13904898408200000000_u128.into(), // 13.904... (1% threshold)
244236
284822000000000000000_u128.into(), // 284.822 (70% threshold)
245-
//386997000000000000000_u128.into(), // 386.997 (80% threshold)
237+
386997000000000000000_u128.into(), // 386.997 (80% threshold)
246238
603509000000000000000_u128.into(), // 603.509 (90% threshold)
247239
908381000000000000000_u128.into(), // 908.381 (96% threshold)
248240
992098000000000000000_u128.into(), // 992.098 (97% threshold)
249-
default_trove_debt, // (99% threshold)
241+
(WAD_ONE * 1000).into(), // (99% threshold)
250242
]
251-
.span();
243+
.span()
244+
}
252245

253-
let mut expected_penalty: Span<Ray> = array![
246+
fn preview_liquidate_expected_penalties() -> Span<Ray> {
247+
array![
254248
(12 * RAY_PERCENT + RAY_PERCENT / 2).into(), // 3% (0% threshold)
255249
(3 * RAY_PERCENT).into(), // 3% (1% threshold)
256250
(3 * RAY_PERCENT).into(), // 3% (70% threshold)
257-
//(3 * RAY_PERCENT).into(), // 3% (80% threshold)
251+
(3 * RAY_PERCENT).into(), // 3% (80% threshold)
258252
(3 * RAY_PERCENT).into(), // 3% (90% threshold)
259253
(3 * RAY_PERCENT).into(), // 3% (96% threshold)
260254
(3 * RAY_PERCENT).into(), // 3% (97% threshold)
261255
10101000000000000000000000_u128.into(), // 1.0101% (99% threshold)
262256
]
263-
.span();
257+
.span()
258+
}
264259

265-
loop {
266-
match thresholds.pop_front() {
267-
Option::Some(threshold) => {
268-
let (shrine, abbot, seer, _, purger, yangs, gates) = purger_utils::purger_deploy(classes);
260+
fn test_preview_liquidate(threshold: Ray, expected_max_close_amt: Wad, expected_penalty: Ray,) {
261+
let classes = Option::Some(purger_utils::declare_contracts());
262+
let (shrine, abbot, seer, _, purger, yangs, gates) = purger_utils::purger_deploy(classes);
269263

270-
purger_utils::create_whale_trove(abbot, yangs, gates);
264+
let default_trove_debt: Wad = (WAD_ONE * 1000).into();
271265

272-
// If the threshold is below 2%, we set the trove's debt such that
273-
// we get the desired ltv for the trove from the get-go in order to
274-
// avoid overflow issues in `lower_prices_to_raise_trove_ltv`.
275-
//
276-
// This is because `lower_prices_to_raise_trove_ltv` is designed for
277-
// raising the trove's LTV to the given *higher* LTV,
278-
// not lowering it.
279-
//
280-
// NOTE: This 2% cut off is completely arbitrary and meant only for excluding
281-
// the two test cases in `interesting_thresholds_for_liquidation`: 0% and 1%.
282-
// If more low thresholds were added that were above 2% but below the
283-
// starting LTV of the trove, then this cutoff would need to be adjusted.
284-
let target_threshold_above_cutoff = *threshold > (RAY_PERCENT * 2).into();
285-
let trove_debt = if target_threshold_above_cutoff {
286-
default_trove_debt
287-
} else {
288-
let target_trove_yang_amts: Span<Wad> = array![
289-
purger_utils::TARGET_TROVE_ETH_DEPOSIT_AMT.into(),
290-
(purger_utils::TARGET_TROVE_WBTC_DEPOSIT_AMT * pow(10_u128, 10)).into(),
291-
Zero::zero(),
292-
Zero::zero(),
293-
]
294-
.span();
266+
purger_utils::create_whale_trove(abbot, yangs, gates);
295267

296-
let trove_value: Wad = purger_utils::get_sum_of_value(shrine, yangs, target_trove_yang_amts);
268+
// If the threshold is below 2%, we set the trove's debt such that
269+
// we get the desired ltv for the trove from the get-go in order to
270+
// avoid overflow issues in `lower_prices_to_raise_trove_ltv`.
271+
//
272+
// This is because `lower_prices_to_raise_trove_ltv` is designed for
273+
// raising the trove's LTV to the given *higher* LTV,
274+
// not lowering it.
275+
//
276+
// NOTE: This 2% cut off is completely arbitrary and meant only for excluding
277+
// the two test cases in `interesting_thresholds_for_liquidation`: 0% and 1%.
278+
// If more low thresholds were added that were above 2% but below the
279+
// starting LTV of the trove, then this cutoff would need to be adjusted.
280+
let target_threshold_above_cutoff = threshold > (RAY_PERCENT * 2).into();
281+
let trove_debt = if target_threshold_above_cutoff {
282+
default_trove_debt
283+
} else {
284+
let target_trove_yang_amts: Span<Wad> = array![
285+
purger_utils::TARGET_TROVE_ETH_DEPOSIT_AMT.into(),
286+
(purger_utils::TARGET_TROVE_WBTC_DEPOSIT_AMT * pow(10_u128, 10)).into(),
287+
Zero::zero(),
288+
Zero::zero(),
289+
]
290+
.span();
297291

298-
wadray::rmul_wr(trove_value, *threshold) + 1_u128.into()
299-
};
292+
let trove_value: Wad = purger_utils::get_sum_of_value(shrine, yangs, target_trove_yang_amts);
300293

301-
let target_trove: u64 = purger_utils::funded_healthy_trove(abbot, yangs, gates, trove_debt);
294+
wadray::rmul_wr(trove_value, threshold) + 1_u128.into()
295+
};
302296

303-
purger_utils::set_thresholds(shrine, yangs, *threshold);
297+
let target_trove: u64 = purger_utils::funded_healthy_trove(abbot, yangs, gates, trove_debt);
304298

305-
let target_trove_health: Health = shrine.get_trove_health(target_trove);
299+
purger_utils::set_thresholds(shrine, yangs, threshold);
306300

307-
if target_threshold_above_cutoff {
308-
purger_utils::lower_prices_to_raise_trove_ltv(
309-
shrine, seer, yangs, target_trove_health.value, target_trove_health.debt, *threshold
310-
);
311-
}
301+
let target_trove_health: Health = shrine.get_trove_health(target_trove);
312302

313-
let target_trove_updated_health: Health = shrine.get_trove_health(target_trove);
314-
purger_utils::assert_trove_is_liquidatable(
315-
shrine, purger, target_trove, target_trove_updated_health
316-
);
303+
if target_threshold_above_cutoff {
304+
purger_utils::lower_prices_to_raise_trove_ltv(
305+
shrine, seer, yangs, target_trove_health.value, target_trove_health.debt, threshold
306+
);
307+
}
317308

318-
let (penalty, max_close_amt) = purger
319-
.preview_liquidate(target_trove)
320-
.expect('Should be liquidatable');
309+
let target_trove_updated_health: Health = shrine.get_trove_health(target_trove);
310+
purger_utils::assert_trove_is_liquidatable(shrine, purger, target_trove, target_trove_updated_health);
321311

322-
let expected_penalty = *expected_penalty.pop_front().unwrap();
323-
common::assert_equalish(penalty, expected_penalty, (RAY_ONE / 10).into(), 'wrong penalty');
312+
let (penalty, max_close_amt) = purger.preview_liquidate(target_trove).expect('Should be liquidatable');
324313

325-
let expected_max_close_amt = *expected_max_close_amts.pop_front().unwrap();
326-
common::assert_equalish(
327-
max_close_amt, expected_max_close_amt, (WAD_ONE * 2).into(), 'wrong max close amt'
328-
);
329-
},
330-
Option::None => { break; },
331-
};
332-
};
314+
common::assert_equalish(penalty, expected_penalty, (RAY_ONE / 10).into(), 'wrong penalty');
315+
common::assert_equalish(max_close_amt, expected_max_close_amt, (WAD_ONE * 2).into(), 'wrong max close amt');
316+
}
317+
318+
#[test]
319+
fn test_preview_liquidate_parametrized_1() {
320+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(0);
321+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(0);
322+
let expected_penalty = *preview_liquidate_expected_penalties().at(0);
323+
324+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
325+
}
326+
327+
#[test]
328+
fn test_preview_liquidate_parametrized_2() {
329+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(1);
330+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(1);
331+
let expected_penalty = *preview_liquidate_expected_penalties().at(1);
332+
333+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
334+
}
335+
336+
#[test]
337+
fn test_preview_liquidate_parametrized_3() {
338+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(2);
339+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(2);
340+
let expected_penalty = *preview_liquidate_expected_penalties().at(2);
341+
342+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
343+
}
344+
345+
#[test]
346+
fn test_preview_liquidate_parametrized_4() {
347+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(3);
348+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(3);
349+
let expected_penalty = *preview_liquidate_expected_penalties().at(3);
350+
351+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
352+
}
353+
354+
#[test]
355+
fn test_preview_liquidate_parametrized_5() {
356+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(4);
357+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(4);
358+
let expected_penalty = *preview_liquidate_expected_penalties().at(4);
359+
360+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
361+
}
362+
363+
#[test]
364+
fn test_preview_liquidate_parametrized_6() {
365+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(5);
366+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(5);
367+
let expected_penalty = *preview_liquidate_expected_penalties().at(5);
368+
369+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
370+
}
371+
372+
#[test]
373+
fn test_preview_liquidate_parametrized_7() {
374+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(6);
375+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(6);
376+
let expected_penalty = *preview_liquidate_expected_penalties().at(6);
377+
378+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
379+
}
380+
381+
#[test]
382+
fn test_preview_liquidate_parametrized_8() {
383+
let threshold = *purger_utils::interesting_thresholds_for_liquidation().at(7);
384+
let expected_max_close_amt = *preview_liquidate_expected_max_close_amts().at(7);
385+
let expected_penalty = *preview_liquidate_expected_penalties().at(7);
386+
387+
test_preview_liquidate(threshold, expected_max_close_amt, expected_penalty);
333388
}
334389

335390
#[test]
@@ -599,7 +654,7 @@ mod test_purger {
599654
let searcher: ContractAddress = purger_utils::searcher();
600655
start_prank(CheatTarget::One(purger.contract_address), searcher);
601656
let freed_assets: Span<AssetBalance> = purger.liquidate(target_trove, BoundedInt::max(), searcher);
602-
657+
println!("after liquidate");
603658
// Check that LTV is close to safety margin
604659
let target_trove_after_health: Health = shrine.get_trove_health(target_trove);
605660

src/tests/purger/utils.cairo

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub mod purger_utils {
104104
Zero::zero(),
105105
RAY_PERCENT.into(),
106106
(70 * RAY_PERCENT).into(),
107-
//(80 * RAY_PERCENT).into(),
107+
(80 * RAY_PERCENT).into(),
108108
(90 * RAY_PERCENT).into(),
109109
(96 * RAY_PERCENT).into(),
110110
// theoretical upper bound beyond which a penalty is not guaranteed
@@ -694,8 +694,12 @@ pub mod purger_utils {
694694
loop {
695695
match yangs.pop_front() {
696696
Option::Some(yang) => {
697+
let amount = *amounts.pop_front().unwrap();
698+
if amount.is_zero() {
699+
continue;
700+
};
697701
let (yang_price, _, _) = shrine.get_current_yang_price(*yang);
698-
sum = sum + yang_price * *amounts.pop_front().unwrap();
702+
sum = sum + yang_price * amount;
699703
},
700704
Option::None => { break sum; }
701705
}

0 commit comments

Comments
 (0)