@@ -229,107 +229,162 @@ mod test_purger {
229
229
//
230
230
// For low thresholds (arbitraily defined as 2% or less), the trove's debt is set based on the
231
231
// 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! [
242
234
1_u128 . into (), // 1 wei (0% threshold)
243
235
13904898408200000000_u128 . into (), // 13.904... (1% threshold)
244
236
284822000000000000000_u128 . into (), // 284.822 (70% threshold)
245
- // 386997000000000000000_u128.into(), // 386.997 (80% threshold)
237
+ 386997000000000000000_u128 . into (), // 386.997 (80% threshold)
246
238
603509000000000000000_u128 . into (), // 603.509 (90% threshold)
247
239
908381000000000000000_u128 . into (), // 908.381 (96% threshold)
248
240
992098000000000000000_u128 . into (), // 992.098 (97% threshold)
249
- default_trove_debt , // (99% threshold)
241
+ ( WAD_ONE * 1000 ) . into () , // (99% threshold)
250
242
]
251
- . span ();
243
+ . span ()
244
+ }
252
245
253
- let mut expected_penalty : Span <Ray > = array! [
246
+ fn preview_liquidate_expected_penalties () -> Span <Ray > {
247
+ array! [
254
248
(12 * RAY_PERCENT + RAY_PERCENT / 2 ). into (), // 3% (0% threshold)
255
249
(3 * RAY_PERCENT ). into (), // 3% (1% threshold)
256
250
(3 * RAY_PERCENT ). into (), // 3% (70% threshold)
257
- // (3 * RAY_PERCENT).into(), // 3% (80% threshold)
251
+ (3 * RAY_PERCENT ). into (), // 3% (80% threshold)
258
252
(3 * RAY_PERCENT ). into (), // 3% (90% threshold)
259
253
(3 * RAY_PERCENT ). into (), // 3% (96% threshold)
260
254
(3 * RAY_PERCENT ). into (), // 3% (97% threshold)
261
255
10101000000000000000000000_u128 . into (), // 1.0101% (99% threshold)
262
256
]
263
- . span ();
257
+ . span ()
258
+ }
264
259
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 );
269
263
270
- purger_utils :: create_whale_trove ( abbot , yangs , gates );
264
+ let default_trove_debt : Wad = ( WAD_ONE * 1000 ) . into ( );
271
265
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 );
295
267
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 ();
297
291
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 );
300
293
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
+ };
302
296
303
- purger_utils :: set_thresholds ( shrine , yangs , * threshold );
297
+ let target_trove : u64 = purger_utils :: funded_healthy_trove ( abbot , yangs , gates , trove_debt );
304
298
305
- let target_trove_health : Health = shrine . get_trove_health ( target_trove );
299
+ purger_utils :: set_thresholds ( shrine , yangs , threshold );
306
300
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 );
312
302
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
+ }
317
308
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 );
321
311
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' );
324
313
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 );
333
388
}
334
389
335
390
#[test]
@@ -599,7 +654,7 @@ mod test_purger {
599
654
let searcher : ContractAddress = purger_utils :: searcher ();
600
655
start_prank (CheatTarget :: One (purger . contract_address), searcher );
601
656
let freed_assets : Span <AssetBalance > = purger . liquidate (target_trove , BoundedInt :: max (), searcher );
602
-
657
+ println! ( " after liquidate " );
603
658
// Check that LTV is close to safety margin
604
659
let target_trove_after_health : Health = shrine . get_trove_health (target_trove );
605
660
0 commit comments