Skip to content

Commit d17383d

Browse files
committed
more parametrization for suspended yang test
1 parent ba8cd0a commit d17383d

File tree

1 file changed

+221
-115
lines changed

1 file changed

+221
-115
lines changed

src/tests/purger/test_purger.cairo

Lines changed: 221 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -3884,23 +3884,12 @@ mod test_purger {
38843884
}
38853885

38863886
fn test_liquidate_suspended_yang_threshold_near_zero(
3887-
starting_ltv: Ray, liquidate_via_absorption: bool, is_recovery_mode: bool
3887+
starting_ltv: Ray, liquidate_via_absorption: bool, is_recovery_mode: bool, desired_threshold: Ray
38883888
) {
38893889
let (shrine, abbot, seer, absorber, purger, yangs, gates) = purger_utils::purger_deploy_with_searcher(
38903890
purger_utils::SEARCHER_YIN.into(), Option::None
38913891
);
38923892

3893-
// We also parametrize the test with the desired threshold for liquidation
3894-
let mut desired_threshold_params: Span<Ray> = array![
3895-
RAY_PERCENT.into(),
3896-
(RAY_PERCENT / 4).into(),
3897-
// This is the smallest possible desired threshold that
3898-
// doesn't result in advancing the time enough to make
3899-
// the suspension permanent
3900-
(RAY_ONE + 1).into() / (RAY_ONE * shrine_contract::SUSPENSION_GRACE_PERIOD.into()).into(),
3901-
]
3902-
.span();
3903-
39043893
let eth: ContractAddress = *yangs[0];
39053894
let eth_gate: IGateDispatcher = *gates[0];
39063895
let eth_amt: u128 = WAD_ONE;
@@ -3925,149 +3914,266 @@ mod test_purger {
39253914
// the lowered threshold from suspension
39263915
purger_utils::create_whale_trove(abbot, yangs, gates);
39273916

3928-
loop {
3929-
match desired_threshold_params.pop_front() {
3930-
Option::Some(desired_threshold) => {
3931-
let (eth_price, _, _) = shrine.get_current_yang_price(eth);
3932-
let forge_amt: Wad = wadray::rmul_wr(eth_amt.into() * eth_price, starting_ltv);
3933-
let target_trove: u64 = common::open_trove_helper(
3934-
abbot,
3935-
target_user,
3936-
array![eth].span(),
3937-
array![eth_amt].span(),
3938-
array![eth_gate].span(),
3939-
forge_amt
3940-
);
3917+
let (eth_price, _, _) = shrine.get_current_yang_price(eth);
3918+
let forge_amt: Wad = wadray::rmul_wr(eth_amt.into() * eth_price, starting_ltv);
3919+
let target_trove: u64 = common::open_trove_helper(
3920+
abbot, target_user, array![eth].span(), array![eth_amt].span(), array![eth_gate].span(), forge_amt
3921+
);
39413922

3942-
// Suspend ETH
3943-
start_prank(CheatTarget::One(shrine.contract_address), shrine_utils::admin());
3944-
shrine.suspend_yang(eth);
3945-
stop_prank(CheatTarget::One(shrine.contract_address));
3923+
// Suspend ETH
3924+
start_prank(CheatTarget::One(shrine.contract_address), shrine_utils::admin());
3925+
shrine.suspend_yang(eth);
3926+
stop_prank(CheatTarget::One(shrine.contract_address));
39463927

3947-
// Advance the time stamp such that the ETH threshold falls to `desired_threshold`
3948-
let decrease_factor: Ray = *desired_threshold / eth_threshold;
3949-
let ts_diff: u64 = shrine_contract::SUSPENSION_GRACE_PERIOD
3950-
- scale_u128_by_ray(shrine_contract::SUSPENSION_GRACE_PERIOD.into(), decrease_factor)
3951-
.try_into()
3952-
.unwrap();
3928+
// Advance the time stamp such that the ETH threshold falls to `desired_threshold`
3929+
let decrease_factor: Ray = desired_threshold / eth_threshold;
3930+
let ts_diff: u64 = shrine_contract::SUSPENSION_GRACE_PERIOD
3931+
- scale_u128_by_ray(shrine_contract::SUSPENSION_GRACE_PERIOD.into(), decrease_factor).try_into().unwrap();
39533932

3954-
shrine_utils::advance_prices_periodically(shrine, yangs, ts_diff);
3933+
shrine_utils::advance_prices_periodically(shrine, yangs, ts_diff);
39553934

3956-
// Check that the threshold has decreased to the desired value
3957-
// The trove's threshold is equivalent to ETH's threshold since it
3958-
// has deposited only ETH.
3959-
let threshold_before_liquidation = shrine.get_trove_health(target_trove).threshold;
3935+
// Check that the threshold has decreased to the desired value
3936+
// The trove's threshold is equivalent to ETH's threshold since it
3937+
// has deposited only ETH.
3938+
let threshold_before_liquidation = shrine.get_trove_health(target_trove).threshold;
3939+
3940+
common::assert_equalish(
3941+
threshold_before_liquidation,
3942+
desired_threshold, // 0.0000001 = 10^-7 (ray). Precision
3943+
// is limited by the precision of timestamps,
3944+
// which is only in seconds
3945+
100000000000000000000_u128.into(),
3946+
'wrong eth threshold'
3947+
);
3948+
3949+
// We want to compare the yin balance of the liquidator
3950+
// before and after the liquidation. In the case of absorption
3951+
// we check the absorber's balance, and in the case of
3952+
// searcher liquidation we check the searcher's balance.
3953+
let before_liquidation_yin_balance: u256 = if liquidate_via_absorption {
3954+
yin_erc20.balance_of(absorber.contract_address)
3955+
} else {
3956+
yin_erc20.balance_of(searcher)
3957+
};
39603958

3961-
common::assert_equalish(
3962-
threshold_before_liquidation,
3963-
*desired_threshold,
3964-
// 0.0000001 = 10^-7 (ray). Precision
3965-
// is limited by the precision of timestamps,
3966-
// which is only in seconds
3967-
100000000000000000000_u128.into(),
3968-
'wrong eth threshold'
3969-
);
3959+
let in_recovery_mode: bool = shrine.is_recovery_mode();
3960+
if is_recovery_mode {
3961+
if !in_recovery_mode {
3962+
purger_utils::trigger_recovery_mode(shrine, seer, yangs, common::RecoveryModeSetupType::ExceedsBuffer);
3963+
}
3964+
} else {
3965+
assert(!in_recovery_mode, 'in recovery mode');
3966+
}
39703967

3971-
// We want to compare the yin balance of the liquidator
3972-
// before and after the liquidation. In the case of absorption
3973-
// we check the absorber's balance, and in the case of
3974-
// searcher liquidation we check the searcher's balance.
3975-
let before_liquidation_yin_balance: u256 = if liquidate_via_absorption {
3976-
yin_erc20.balance_of(absorber.contract_address)
3977-
} else {
3978-
yin_erc20.balance_of(searcher)
3979-
};
3968+
// Liquidate the trove
3969+
start_prank(CheatTarget::One(purger.contract_address), searcher);
39803970

3981-
let in_recovery_mode: bool = shrine.is_recovery_mode();
3982-
if is_recovery_mode {
3983-
if !in_recovery_mode {
3984-
purger_utils::trigger_recovery_mode(
3985-
shrine, seer, yangs, common::RecoveryModeSetupType::ExceedsBuffer
3986-
);
3987-
}
3988-
} else {
3989-
assert(!in_recovery_mode, 'in recovery mode');
3990-
}
3971+
if liquidate_via_absorption {
3972+
purger.absorb(target_trove);
3973+
} else {
3974+
// Get the updated debt with accrued interest
3975+
let before_liquidation_health: Health = shrine.get_trove_health(target_trove);
3976+
purger.liquidate(target_trove, before_liquidation_health.debt, searcher);
3977+
}
39913978

3992-
// Liquidate the trove
3993-
start_prank(CheatTarget::One(purger.contract_address), searcher);
3979+
// Sanity checks
3980+
let target_trove_after_health: Health = shrine.get_trove_health(target_trove);
39943981

3995-
if liquidate_via_absorption {
3996-
purger.absorb(target_trove);
3997-
} else {
3998-
// Get the updated debt with accrued interest
3999-
let before_liquidation_health: Health = shrine.get_trove_health(target_trove);
4000-
purger.liquidate(target_trove, before_liquidation_health.debt, searcher);
4001-
}
3982+
assert(target_trove_after_health.debt < forge_amt, 'trove not correctly liquidated');
40023983

4003-
// Sanity checks
4004-
let target_trove_after_health: Health = shrine.get_trove_health(target_trove);
3984+
// Checking that the liquidator's yin balance has decreased
3985+
// after liquidation
3986+
if liquidate_via_absorption {
3987+
assert(
3988+
yin_erc20.balance_of(absorber.contract_address) < before_liquidation_yin_balance,
3989+
'absorber yin not used'
3990+
);
3991+
} else {
3992+
assert(yin_erc20.balance_of(searcher) < before_liquidation_yin_balance, 'searcher yin not used');
3993+
}
3994+
}
40053995

4006-
assert(target_trove_after_health.debt < forge_amt, 'trove not correctly liquidated');
3996+
fn suspended_yang_desired_thresholds() -> Span<Ray> {
3997+
array![
3998+
RAY_PERCENT.into(),
3999+
(RAY_PERCENT / 4).into(),
4000+
// This is the smallest possible desired threshold that
4001+
// doesn't result in advancing the time enough to make
4002+
// the suspension permanent
4003+
(RAY_ONE + 1).into() / (RAY_ONE * shrine_contract::SUSPENSION_GRACE_PERIOD.into()).into(),
4004+
]
4005+
.span()
4006+
}
40074007

4008-
// Checking that the liquidator's yin balance has decreased
4009-
// after liquidation
4010-
if liquidate_via_absorption {
4011-
assert(
4012-
yin_erc20.balance_of(absorber.contract_address) < before_liquidation_yin_balance,
4013-
'absorber yin not used'
4014-
);
4015-
} else {
4016-
assert(
4017-
yin_erc20.balance_of(searcher) < before_liquidation_yin_balance, 'searcher yin not used'
4018-
);
4019-
}
4008+
#[test]
4009+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized1a() {
4010+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4011+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, true, desired_threshold);
4012+
}
40204013

4021-
start_prank(CheatTarget::One(shrine.contract_address), shrine_utils::admin());
4022-
shrine.unsuspend_yang(eth);
4023-
stop_prank(CheatTarget::One(shrine.contract_address));
4024-
},
4025-
Option::None => { break; }
4026-
}
4027-
};
4014+
#[test]
4015+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized1b() {
4016+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4017+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, true, desired_threshold);
40284018
}
40294019

40304020
#[test]
4031-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized1() {
4032-
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, true);
4021+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized1c() {
4022+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4023+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, true, desired_threshold);
40334024
}
40344025

40354026
#[test]
4036-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized2() {
4037-
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, true);
4027+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized2a() {
4028+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4029+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, true, desired_threshold);
40384030
}
40394031

40404032
#[test]
4041-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized3() {
4042-
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, false);
4033+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized2b() {
4034+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4035+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, true, desired_threshold);
40434036
}
40444037

40454038
#[test]
4046-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized4() {
4047-
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, false);
4039+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized2c() {
4040+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4041+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, true, desired_threshold);
4042+
}
4043+
4044+
#[test]
4045+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized3a() {
4046+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4047+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, false, desired_threshold);
4048+
}
4049+
4050+
#[test]
4051+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized3b() {
4052+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4053+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, false, desired_threshold);
4054+
}
4055+
4056+
#[test]
4057+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized3c() {
4058+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4059+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), true, false, desired_threshold);
4060+
}
4061+
4062+
#[test]
4063+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized4a() {
4064+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4065+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, false, desired_threshold);
4066+
}
4067+
4068+
#[test]
4069+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized4b() {
4070+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4071+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, false, desired_threshold);
4072+
}
4073+
4074+
#[test]
4075+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized4c() {
4076+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4077+
test_liquidate_suspended_yang_threshold_near_zero((50 * RAY_PERCENT).into(), false, false, desired_threshold);
40484078
}
40494079

40504080
// The minimum LTV for absorption at 1% threshold is approximately 1.097%, so it is rounded
40514081
// up to 1.1% for convenience to ensure the target trove is absorbable after adjusting the
40524082
// threshold to the desired value.
40534083
#[test]
4054-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized5() {
4055-
test_liquidate_suspended_yang_threshold_near_zero((RAY_PERCENT + RAY_PERCENT / 10).into(), true, true);
4084+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized5a() {
4085+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4086+
test_liquidate_suspended_yang_threshold_near_zero(
4087+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, true, desired_threshold
4088+
);
4089+
}
4090+
4091+
#[test]
4092+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized5b() {
4093+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4094+
test_liquidate_suspended_yang_threshold_near_zero(
4095+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, true, desired_threshold
4096+
);
4097+
}
4098+
4099+
#[test]
4100+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized5c() {
4101+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4102+
test_liquidate_suspended_yang_threshold_near_zero(
4103+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, true, desired_threshold
4104+
);
4105+
}
4106+
4107+
#[test]
4108+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized6a() {
4109+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4110+
test_liquidate_suspended_yang_threshold_near_zero(
4111+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, true, desired_threshold
4112+
);
40564113
}
40574114

40584115
#[test]
4059-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized6() {
4060-
test_liquidate_suspended_yang_threshold_near_zero((RAY_PERCENT + RAY_PERCENT / 10).into(), false, true);
4116+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized6b() {
4117+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4118+
test_liquidate_suspended_yang_threshold_near_zero(
4119+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, true, desired_threshold
4120+
);
40614121
}
40624122

40634123
#[test]
4064-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized7() {
4065-
test_liquidate_suspended_yang_threshold_near_zero((RAY_PERCENT + RAY_PERCENT / 10).into(), true, false);
4124+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized6c() {
4125+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4126+
test_liquidate_suspended_yang_threshold_near_zero(
4127+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, true, desired_threshold
4128+
);
40664129
}
40674130

40684131
#[test]
4069-
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized8() {
4070-
test_liquidate_suspended_yang_threshold_near_zero((RAY_PERCENT + RAY_PERCENT / 10).into(), false, false);
4132+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized7a() {
4133+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4134+
test_liquidate_suspended_yang_threshold_near_zero(
4135+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, false, desired_threshold
4136+
);
4137+
}
4138+
4139+
#[test]
4140+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized7b() {
4141+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4142+
test_liquidate_suspended_yang_threshold_near_zero(
4143+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, false, desired_threshold
4144+
);
4145+
}
4146+
4147+
#[test]
4148+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized7c() {
4149+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4150+
test_liquidate_suspended_yang_threshold_near_zero(
4151+
(RAY_PERCENT + RAY_PERCENT / 10).into(), true, false, desired_threshold
4152+
);
4153+
}
4154+
4155+
#[test]
4156+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized8a() {
4157+
let desired_threshold = *suspended_yang_desired_thresholds().at(0);
4158+
test_liquidate_suspended_yang_threshold_near_zero(
4159+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, false, desired_threshold
4160+
);
4161+
}
4162+
4163+
#[test]
4164+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized8b() {
4165+
let desired_threshold = *suspended_yang_desired_thresholds().at(1);
4166+
test_liquidate_suspended_yang_threshold_near_zero(
4167+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, false, desired_threshold
4168+
);
4169+
}
4170+
4171+
#[test]
4172+
fn test_liquidate_suspended_yang_threshold_near_zero_parametrized8c() {
4173+
let desired_threshold = *suspended_yang_desired_thresholds().at(2);
4174+
test_liquidate_suspended_yang_threshold_near_zero(
4175+
(RAY_PERCENT + RAY_PERCENT / 10).into(), false, false, desired_threshold
4176+
);
40714177
}
40724178

40734179
#[derive(Copy, Drop, PartialEq)]

0 commit comments

Comments
 (0)