Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calc abs max short guess #202

Merged
merged 19 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

- uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2024-05-02
toolchain: nightly
override: true
components: rustfmt, clippy

Expand Down
2 changes: 1 addition & 1 deletion bindings/hyperdrivepy/src/hyperdrive_state_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl HyperdriveState {
}

pub fn calculate_spot_price(&self) -> PyResult<String> {
let result_fp = self.state.calculate_spot_price().map_err(|err| {
let result_fp = self.state.calculate_spot_price_down().map_err(|err| {
PyErr::new::<PyValueError, _>(format!("calculate_spot_price: {}", err))
})?;
let result = U256::from(result_fp).to_string();
Expand Down
19 changes: 12 additions & 7 deletions crates/hyperdrive-math/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,20 @@ impl State {
Self { config, info }
}

/// Calculates the pool's spot price.
pub fn calculate_spot_price(&self) -> Result<FixedPoint<U256>> {
YieldSpace::calculate_spot_price(self)
/// Calculates the pool's spot price, rounding down.
pub fn calculate_spot_price_down(&self) -> Result<FixedPoint<U256>> {
YieldSpace::calculate_spot_price_down(self)
}

/// Calculates the pool's spot price, rounding up.
pub fn calculate_spot_price_up(&self) -> Result<FixedPoint<U256>> {
YieldSpace::calculate_spot_price_up(self)
}

/// Calculate the pool's current spot (aka "fixed") rate.
pub fn calculate_spot_rate(&self) -> Result<FixedPoint<U256>> {
Ok(calculate_rate_given_fixed_price(
self.calculate_spot_price()?,
self.calculate_spot_price_down()?,
self.position_duration(),
))
}
Expand Down Expand Up @@ -364,8 +369,8 @@ mod tests {
state.info.shorts_outstanding = uint256!(0);
state.info.short_average_maturity_time = uint256!(0);
// Make sure we're still solvent
if state.calculate_spot_price()? < state.calculate_min_spot_price()?
|| state.calculate_spot_price()? > fixed!(1e18)
if state.calculate_spot_price_down()? < state.calculate_min_spot_price()?
|| state.calculate_spot_price_down()? > fixed!(1e18)
|| state.calculate_solvency().is_err()
{
continue;
Expand Down Expand Up @@ -403,7 +408,7 @@ mod tests {
new_state.info.share_reserves = target_share_reserves.into();
new_state.info.bond_reserves = target_bond_reserves.into();
if new_state.calculate_solvency().is_err()
|| new_state.calculate_spot_price()? > fixed!(1e18)
|| new_state.calculate_spot_price_down()? > fixed!(1e18)
{
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions crates/hyperdrive-math/src/long/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl State {
) -> Result<FixedPoint<U256>> {
let bond_amount = bond_amount.into();

let spot_price = self.calculate_spot_price()?;
let spot_price = self.calculate_spot_price_down()?;
if spot_price > fixed!(1e18) {
return Err(eyre!("Negative fixed interest!"));
}
Expand Down Expand Up @@ -231,7 +231,7 @@ mod tests {
// Ensure curve_fee is smaller than spot_price to avoid overflows
// on the hyperdrive valuation, as that'd mean having to pay a larger
// amount of fees than the current value of the long.
let spot_price = state.calculate_spot_price()?;
let spot_price = state.calculate_spot_price_down()?;
if state.curve_fee() * (fixed!(1e18) - spot_price) > spot_price {
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions crates/hyperdrive-math/src/long/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl State {
// NOTE: Round up to overestimate the curve fee.
Ok(self
.curve_fee()
.mul_up(fixed!(1e18).div_up(self.calculate_spot_price()?) - fixed!(1e18))
.mul_up(fixed!(1e18).div_up(self.calculate_spot_price_down()?) - fixed!(1e18))
.mul_up(base_amount))
}

Expand All @@ -43,7 +43,7 @@ impl State {
// NOTE: Round down to underestimate the governance curve fee.
Ok(curve_fee
.mul_down(self.governance_lp_fee())
.mul_down(self.calculate_spot_price()?))
.mul_down(self.calculate_spot_price_down()?))
}

/// Calculates the curve fee paid when closing longs for a given bond
Expand All @@ -69,7 +69,7 @@ impl State {
// NOTE: Round up to overestimate the curve fee.
Ok(self
.curve_fee()
.mul_up(fixed!(1e18) - self.calculate_spot_price()?)
.mul_up(fixed!(1e18) - self.calculate_spot_price_down()?)
.mul_up(bond_amount)
.mul_div_up(normalized_time_remaining, self.vault_share_price()))
}
Expand Down
13 changes: 7 additions & 6 deletions crates/hyperdrive-math/src/long/max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl State {
/ (fixed!(1e18)
+ self
.curve_fee()
.mul_up(fixed!(1e18).div_up(self.calculate_spot_price()?) - fixed!(1e18)))
.mul_up(fixed!(1e18).div_up(self.calculate_spot_price_down()?) - fixed!(1e18)))
.mul_up(fixed!(1e18) - self.flat_fee()))
}

Expand Down Expand Up @@ -208,7 +208,8 @@ impl State {
+ self
.curve_fee()
.mul_up(
fixed!(1e18).div_up(self.calculate_spot_price()?) - fixed!(1e18),
fixed!(1e18).div_up(self.calculate_spot_price_down()?)
- fixed!(1e18),
)
.mul_up(fixed!(1e18) - self.flat_fee()))
.div_up(fixed!(1e18) - self.flat_fee()))
Expand All @@ -226,7 +227,7 @@ impl State {
//
// y_t = inner * ((1 + curveFee * (1 / p_0 - 1) * (1 - flatFee)) / (1 - flatFee)) ** (1 / t_s)
let fee_adjustment = self.curve_fee()
* (fixed!(1e18) / self.calculate_spot_price()? - fixed!(1e18))
* (fixed!(1e18) / self.calculate_spot_price_down()? - fixed!(1e18))
* (fixed!(1e18) - self.flat_fee());
let target_bond_reserves = ((fixed!(1e18) + fee_adjustment)
/ (fixed!(1e18) - self.flat_fee()))
Expand Down Expand Up @@ -265,7 +266,7 @@ impl State {
) -> Result<FixedPoint<U256>> {
// Calculate an initial estimate of the max long by using the spot price as
// our conservative price.
let spot_price = self.calculate_spot_price()?;
let spot_price = self.calculate_spot_price_down()?;
let guess = self.max_long_estimate(spot_price, spot_price, checkpoint_exposure)?;

// We know that the spot price is 1 when the absolute max base amount is
Expand Down Expand Up @@ -426,7 +427,7 @@ impl State {
base_amount: FixedPoint<U256>,
) -> Result<FixedPoint<U256>> {
let derivative = self.calculate_open_long_derivative(base_amount)?;
let spot_price = self.calculate_spot_price()?;
let spot_price = self.calculate_spot_price_down()?;
Ok(
(derivative
+ self.governance_lp_fee() * self.curve_fee() * (fixed!(1e18) - spot_price)
Expand Down Expand Up @@ -485,7 +486,7 @@ mod tests {
state.info.share_adjustment,
)?
.into(),
state.calculate_spot_price()?.into(),
state.calculate_spot_price_down()?.into(),
)
.call()
.await
Expand Down
6 changes: 3 additions & 3 deletions crates/hyperdrive-math/src/long/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl State {

// Finish computing the derivative.
derivative -=
self.curve_fee() * ((fixed!(1e18) / self.calculate_spot_price()?) - fixed!(1e18));
self.curve_fee() * ((fixed!(1e18) / self.calculate_spot_price_down()?) - fixed!(1e18));

Ok(derivative)
}
Expand Down Expand Up @@ -155,7 +155,7 @@ impl State {
) -> Result<FixedPoint<U256>> {
let state =
self.calculate_pool_state_after_open_long(base_amount, maybe_bond_pool_delta)?;
state.calculate_spot_price()
state.calculate_spot_price_down()
}

/// Calculate the spot rate after a long has been opened.
Expand Down Expand Up @@ -336,7 +336,7 @@ mod tests {
// Verify that the predicted spot price is equal to the ending spot
// price. These won't be exactly equal because the vault share price
// increases between the prediction and opening the long.
let actual_spot_price = bob.get_state().await?.calculate_spot_price()?;
let actual_spot_price = bob.get_state().await?.calculate_spot_price_down()?;
let delta = if actual_spot_price > expected_spot_price {
actual_spot_price - expected_spot_price
} else {
Expand Down
6 changes: 3 additions & 3 deletions crates/hyperdrive-math/src/long/targeted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl State {
// g'(x) = \phi_g \phi_c (1 - p_0)
let gov_fee_derivative = self.governance_lp_fee()
* self.curve_fee()
* (fixed!(1e18) - self.calculate_spot_price()?);
* (fixed!(1e18) - self.calculate_spot_price_down()?);

// a(x) = mu * (z_{e,0} + 1/c (x - g(x))
let inner_numerator = self.mu()
Expand Down Expand Up @@ -401,7 +401,7 @@ impl State {
}
let share_delta = ending_share_reserves - self.share_reserves();
let fees = fixed!(1e18)
- (fixed!(1e18) - self.calculate_spot_price()?)
- (fixed!(1e18) - self.calculate_spot_price_down()?)
* self.curve_fee()
* self.governance_lp_fee();
let base_delta = self.vault_share_price().mul_div_down(share_delta, fees);
Expand Down Expand Up @@ -620,7 +620,7 @@ mod tests {

// Check that our resulting price is under the max
let current_state = alice.get_state().await?;
let spot_price_after_long = current_state.calculate_spot_price()?;
let spot_price_after_long = current_state.calculate_spot_price_down()?;
assert!(
max_spot_price_before_long > spot_price_after_long,
"Resulting price is greater than the max."
Expand Down
10 changes: 5 additions & 5 deletions crates/hyperdrive-math/src/short/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl State {
Ok(fixed!(1e18)
- self
.curve_fee()
.mul_up(fixed!(1e18) - self.calculate_spot_price()?))
.mul_up(fixed!(1e18) - self.calculate_spot_price_down()?))
}

/// Calculates the amount of shares the trader will receive after fees for closing a short
Expand Down Expand Up @@ -224,7 +224,7 @@ impl State {
let mut state: State = self.clone();
state.info.bond_reserves -= bond_reserves_delta.into();
state.info.share_reserves += share_curve_delta.into();
state.calculate_spot_price()?
state.calculate_spot_price_down()?
};
let max_spot_price = self.calculate_close_short_max_spot_price()?;
if short_curve_spot_price > max_spot_price {
Expand All @@ -244,7 +244,7 @@ impl State {
let mut state: State = self.clone();
state.info.bond_reserves -= bond_reserves_delta.into();
state.info.share_reserves += share_curve_delta_with_fees.into();
state.calculate_spot_price()?
state.calculate_spot_price_down()?
};
if share_curve_delta_with_fees_spot_price > fixed!(1e18) {
return Err(eyre!("InsufficientLiquidity: Negative Interest"));
Expand Down Expand Up @@ -293,7 +293,7 @@ impl State {
let open_vault_share_price = open_vault_share_price.into();
let close_vault_share_price = close_vault_share_price.into();

let spot_price = self.calculate_spot_price()?;
let spot_price = self.calculate_spot_price_down()?;
if spot_price > fixed!(1e18) {
return Err(eyre!("Negative fixed interest!"));
}
Expand Down Expand Up @@ -513,7 +513,7 @@ mod tests {
let state = rng.gen::<State>();
let result = state.calculate_close_short(
(state.config.minimum_transaction_amount - 10).into(),
state.calculate_spot_price()?,
state.calculate_spot_price_down()?,
state.vault_share_price(),
0.into(),
0.into(),
Expand Down
19 changes: 17 additions & 2 deletions crates/hyperdrive-math/src/short/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl State {
// NOTE: Round up to overestimate the curve fee.
Ok(self
.curve_fee()
.mul_up(fixed!(1e18) - self.calculate_spot_price()?)
.mul_up(fixed!(1e18) - self.calculate_spot_price_down()?)
.mul_up(bond_amount))
}

Expand All @@ -43,6 +43,21 @@ impl State {
Ok(curve_fee.mul_down(self.governance_lp_fee()))
}

/// Calculate the total fees to be removed from the short principal when
/// opening a short for a given bond amount.
pub fn calculate_open_short_total_fee_shares(
&self,
bond_amount: FixedPoint<U256>,
) -> Result<FixedPoint<U256>> {
let curve_fee_base = self.open_short_curve_fee(bond_amount)?;
let curve_fee_shares = curve_fee_base.div_up(self.vault_share_price());
let gov_curve_fee_shares = self
.open_short_governance_fee(bond_amount, Some(curve_fee_base))?
.div_up(self.vault_share_price());
let total_fee_shares = curve_fee_shares - gov_curve_fee_shares;
Ok(total_fee_shares)
}

/// Calculates the curve fee paid when opening shorts with a given bond
/// amount.
///
Expand All @@ -65,7 +80,7 @@ impl State {
// NOTE: Round up to overestimate the curve fee.
Ok(self
.curve_fee()
.mul_up(fixed!(1e18) - self.calculate_spot_price()?)
.mul_up(fixed!(1e18) - self.calculate_spot_price_down()?)
.mul_up(bond_amount)
.mul_div_up(normalized_time_remaining, self.vault_share_price()))
}
Expand Down
Loading
Loading