Stable Price

The stable price serves as a safety mechanism that restricts a user's ability to enter risky positions when the oracle price is changing rapidly.

Usage

When determining if a user can open a new position, LEH computes the initial health. For this, it adds together the value of all assets and subtracts the value of all liabilities. To derive the value of assets and liabilities, prices are needed. The price of an asset is set to be the lesser of the oracle and stable price, while the value of liabilities is set to the larger of the oracle and stable price.

Effects

The concept relies on the assumption that, under normal circumstances, the stable price closely follows the oracle price. During significant price jumps, it temporarily reduces user leverage until it catches up. In the case of extreme price jumps, likely due to attacks, it becomes very slow in granting leverage based on the new values. This means attackers need to sustain their attack for longer periods, allowing users and operators more time to react.

For example, in its current default configuration (stable_growth_limit=290% per hour, delay_growth_limit=6% per hour), for an upwards price jump of:

  • 5%, it catches up in three minutes

  • 20%, it catches up in 13 minutes

  • 100%, it catches up to 178% of the starting price in one hour

  • 900%, it catches up to 178% in one hour and 727% in one day

Definition

The stable price is updated based on the oracle price. It's updated by a permissionless overwatcher instruction (TokenUpdateIndexAndRate) in arbitrary intervals, but not more often than once every ten seconds.

The stable price is updated in a way that attempts to track the oracle price while limiting the allowed rate of change. This allowed rate of change depends on the difference between the current stable price and the 24-hour delayed oracle price. It's largest if they are the same and decreases otherwise.

For full details, check stable_price.rs in the source code. The size of the update is roughly

stable_price * stable_growth_limit * dt * (delay_price / stable_price)^2

into the direction of the oracle price (if stable_price > delay_price, otherwise the quotient is inverted).

Last updated