delvtech/hyperdrive-rs

fix `calculate_spot_price_after_short`

Closed this issue · 2 comments

calculate_spot_price_after_short has an optional base_amount argument that does not behave correctly. Here's the test that fails:

python:

bond_amount = hyperdrive_read_interface.calc_max_short(budget=FixedPoint(1_000_000))
base_amount = hyperdrive_read_interface.calc_open_short(bond_amount)
price_with_default = hyperdrive_read_interface.calc_spot_price_after_short(bond_amount)
price_with_base_amount = hyperdrive_read_interface.calc_spot_price_after_short(bond_amount, base_amount)
assert (
    price_with_default == price_with_base_amount
), "`calc_spot_price_after_short` is not handling default base_amount correctly."

rust:

let bond_amount = rng.gen_range(state.minimum_transaction_amount()..=max_bond_amount);
let base_amount = match state.calculate_open_short(bond_amount, open_vault_share_price)
{
    Ok(base_amount) => Some(base_amount),
    Err(_) => continue,
};
let price_with_default = state.calculate_spot_price_after_short(bond_amount, None)?;
let price_with_base_amount =
    state.calculate_spot_price_after_short(bond_amount, base_amount)?;
assert_eq!(
    price_with_default, price_with_base_amount,
    "`calculate_spot_price_after_short` is not handling default base_amount correctly."
);

The problem is that the way we compute the delta shares applied to the pool share reserves before calculating the updated spot price is not done correctly. Unlike the calculate_spot_price_after_long flow, we can't simply call calculate_open_short to determine the share reserves delta. This is because the user is paying a different amount than what is applied to the pool itself (bc of fees).

Reopening, it seems this is still failing intermittently.

Fixed per @jrhea (#89 and #87)