From c469d2b15d11269603a9773050e8f174809e72e5 Mon Sep 17 00:00:00 2001 From: Dylan Paiton Date: Thu, 11 Jul 2024 13:32:23 -0700 Subject: [PATCH] Inclusive & valid random share reserve range; dynamic fuzz bugfix (#170) # Description - share adjustment (zeta) was using a non-inclusive range, but the requirement (`<=`) implies inclusive should be valid. - I tested this with the bounds (`share_adjustment = 0` and `share_adjustment = share_reserves - min_share_reserves - fixed!(10e18)`) and all tests passed with both extremes - note that I had to reduce the upper-bound by `fixed!(10e18)` for the tests to pass, which I guess means we were just getting lucky before. I made an issue for this: https://github.com/delvtech/hyperdrive-rs/issues/171 - dynamic fuzz is supposed to do 10x fuzz runs on new tests, but was 1x with `FAST_FUZZ_RUNS` - fix a check in an `open.rs` test where the allowable max bond amount was too low --- .github/workflows/dynamic_fuzz.yml | 2 +- crates/hyperdrive-math/src/lib.rs | 23 +++++++++++++---------- crates/hyperdrive-math/src/short/open.rs | 3 +-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/dynamic_fuzz.yml b/.github/workflows/dynamic_fuzz.yml index 4d28c66c..59c62973 100644 --- a/.github/workflows/dynamic_fuzz.yml +++ b/.github/workflows/dynamic_fuzz.yml @@ -57,7 +57,7 @@ jobs: echo "$new_tests" while IFS= read -r test; do echo "Running test: $test" - env HYPERDRIVE_SLOW_FUZZ_RUNS=500 HYPERDRIVE_FUZZ_RUNS=1000 HYPERDRIVE_FAST_FUZZ_RUNS=10000 cargo test --release $test -- + env HYPERDRIVE_SLOW_FUZZ_RUNS=500 HYPERDRIVE_FUZZ_RUNS=1000 HYPERDRIVE_FAST_FUZZ_RUNS=100000 cargo test --release $test -- done <<< "$new_tests" else echo "No new tests found." diff --git a/crates/hyperdrive-math/src/lib.rs b/crates/hyperdrive-math/src/lib.rs index effb566d..2bb925a8 100644 --- a/crates/hyperdrive-math/src/lib.rs +++ b/crates/hyperdrive-math/src/lib.rs @@ -30,7 +30,6 @@ impl Distribution for Standard { fn sample(&self, rng: &mut R) -> State { let one_day_in_seconds = 60 * 60 * 24; let one_hour_in_seconds = 60 * 60; - let config = PoolConfig { base_token: Address::zero(), vault_shares_token: Address::zero(), @@ -63,8 +62,6 @@ impl Distribution for Standard { governance_zombie: rng.gen_range(fixed!(0.0001e18)..=fixed!(0.2e18)).into(), }, }; - // We need the spot price to be less than or equal to 1, so we need to - // generate the bond reserves so that mu * z <= y let share_reserves = rng.gen_range(fixed!(1_000e18)..=fixed!(100_000_000e18)); let share_adjustment = { if rng.gen() { @@ -72,24 +69,30 @@ impl Distribution for Standard { } else { // We generate values that satisfy `z - zeta >= z_min`, // so `z - z_min >= zeta`. + // TODO: The upper bound had to be lowered to make tests pass; issue #171 I256::try_from(rng.gen_range( - fixed!(0)..(share_reserves - FixedPoint::from(config.minimum_share_reserves)), + fixed!(0) + ..=(share_reserves + - FixedPoint::from(config.minimum_share_reserves) + - fixed!(10e18)), )) .unwrap() } }; let effective_share_reserves = calculate_effective_share_reserves(share_reserves, share_adjustment).unwrap(); + // We need the spot price to be less than or equal to 1, so we need to + // generate the bond reserves so that mu * z <= y. + let bond_reserves = rng.gen_range( + effective_share_reserves * FixedPoint::from(config.initial_vault_share_price) + ..=fixed!(1_000_000_000e18), + ); + // Populate PoolInfo. let info = PoolInfo { share_reserves: share_reserves.into(), zombie_base_proceeds: fixed!(0).into(), zombie_share_reserves: fixed!(0).into(), - bond_reserves: rng - .gen_range( - effective_share_reserves * FixedPoint::from(config.initial_vault_share_price) - ..=fixed!(1_000_000_000e18), - ) - .into(), + bond_reserves: bond_reserves.into(), vault_share_price: rng.gen_range(fixed!(0.5e18)..=fixed!(2.5e18)).into(), longs_outstanding: rng.gen_range(fixed!(0)..=fixed!(100_000e18)).into(), shorts_outstanding: rng.gen_range(fixed!(0)..=fixed!(100_000e18)).into(), diff --git a/crates/hyperdrive-math/src/short/open.rs b/crates/hyperdrive-math/src/short/open.rs index 8fc1e708..4824077b 100644 --- a/crates/hyperdrive-math/src/short/open.rs +++ b/crates/hyperdrive-math/src/short/open.rs @@ -452,7 +452,6 @@ mod tests { I256::try_from(value).unwrap() } }; - let open_vault_share_price = rng.gen_range(fixed!(0)..=state.vault_share_price()); // We need to catch panics because of overflows. let max_bond_amount = match panic::catch_unwind(|| { state.calculate_absolute_max_short( @@ -467,7 +466,7 @@ mod tests { }, Err(_) => continue, // Max threw a panic. }; - if max_bond_amount == fixed!(0) { + if max_bond_amount < state.minimum_transaction_amount() + fixed!(1) { continue; } let bond_amount = rng.gen_range(state.minimum_transaction_amount()..=max_bond_amount);