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

Drain pool by sandwiching matured shorts #426

Closed
Tracked by #424 ...
jalextowle opened this issue Jul 10, 2023 · 2 comments · Fixed by #537
Closed
Tracked by #424 ...

Drain pool by sandwiching matured shorts #426

jalextowle opened this issue Jul 10, 2023 · 2 comments · Fixed by #537
Assignees
Labels

Comments

@jalextowle
Copy link
Contributor

jalextowle commented Jul 10, 2023

Spearbit Issue: https://github.com/spearbit-audits/review-element/issues/68.

@jalextowle
Copy link
Contributor Author

jalextowle commented Jul 27, 2023

Idea

One way to prevent the short sandwich exploit is to design the pricing mechanism to be invariant under the closing of bonds at maturity. Since Hyperdrive decomposes trades into trades of newly minted bonds (the curve component) and trades of matured bonds (the flat component), holding the pricing mechanism invariant under the closing of bonds at maturity is equivalent to holding the pricing mechanism invariant under flat updates.\

Zeta Adjustment

Trading

To achieve the property of the pricing mechanism being invariant under flat updates, we modify the way that we account for the flat parts of trades. Currently, we call _updateLiquidity to apply a flat update to the reserves. This increases the share reserves and bond reserves such that the spot price doesn't change. Since k increases, the concavity also increases, which provides the necessary environment for a short sandwich. To avoid this behavior, we will maintain k as an invariant when we close positions. A naive approach would be to not change the share and bond reserves when a position is closed; however, this would result in the LPs needing to constantly withdraw and re-deposit their funds to ensure that they are providing liquidity with all of their capital. If we tracked all of updates to the share reserves on account of closing positions, we could continually re-invest the flat proceeds that LPs earn while also holding the YieldSpace curve invariant under closing positions.

When a long is closed, the flat component of the trade should be removed from the share reserves since the long is redeeming bonds 1:1 a at maturity. Since the LP is the owner of the bonds in the case of shorts, the flat component is added to the share reserves when shorts are closed. Let $\zeta$ be the sum of all shares that have been added to the share reserves when a short was closed or removed from the share reserves when a long was closed. If we assume that the bond reserves are not updated when positions are closed, then the following pricing model is invariant under flat updates:

$$ k = \tfrac{c}{\mu} \cdot (\mu \cdot (z - \zeta))^{1 - t_s} + y^{1 - t_s} $$

Suppose Bob closes a short at maturity of $\Delta y$ bonds. We update the share reserves $z_0$ to $z_1 = z_0 + \Delta y$. We also update $\zeta_0$ to $\zeta_1 = \zeta_0 + \Delta y$. $y$ is left unchanged, so $y_1 = y_0$. With this in mind, our value of $k$ becomes $k_1 = \tfrac{c}{\mu} \cdot (\mu \cdot (z_1 - \zeta_1))^{1 - t_s} + y_1^{1 - t_s}$. We have that $z_1 - \zeta_1 = (z_0 + \Delta y) - (\zeta_0 + \Delta y) = z_0 - \zeta_0$, and we also have that $y_1 = y_0$. Therefore, $k_1 = \tfrac{c}{\mu} \cdot (\mu \cdot (z_0 - \zeta_0))^{1 - t_s} + y_0^{1 - t_s} = k_0$. Since $k_0 = k_1$ and $(z_1 - \zeta_1, y_1) = (z_0 - \zeta_0, y_0)$, the flat update didn't change the price of executing a trade on the curve.

Similarly, if Bob closes a long at maturity of $\Delta y$ bonds, then the state is updated to $z_1 = z_0 - \Delta y$, $\zeta_1 = \zeta_0 - \Delta y$, and $y_1 = y_0$. Just as in the case of closing shorts, $z_1 - \zeta_1 = z_0 - \zeta_0$, so we have that $k_1 = k_0$. This also implies that $(z_1 - \zeta_1, y_1) = (z_0 - \zeta_0, y_0)$, so we can see that closing longs also holds our pricing mechanism invariant.

Adding and Removing Liquidity

Since the spot price formula changes to $p = (\tfrac{\mu \cdot (z - \zeta)}{y})^{\tau}$, we will need to change the calculation of the updated bond reserves. By holding the spot rate before and after adding or removing liquidity constant, we can calculate the updated bond reserves as:

$$ (\tfrac{\mu \cdot (z_0 - \zeta_0)}{y_0})^{\tau} = (\tfrac{\mu \cdot (z_1 - \zeta_1)}{y_1})^{\tau} \\ \implies \\ \tfrac{z_0 - \zeta_0}{y_0} = \tfrac{z_1 - \zeta_1}{y_1} \\ \implies \\ y_1 = y_0 \cdot \tfrac{z_1 - \zeta_1}{z_0 - \zeta_0} $$

We have $z_0$, $z_1$, $y_0$, and $\zeta_0$, but we haven't specified how $\zeta_1$ should be calculated. The naive approach would be to leave $\zeta$ unchanged when liquidity is added or removed. The problem with this approach is that we can run into situations where $z - \zeta < 0$ when liquidity is removed from the pool which locks the pool up and prevents trading. With this in mind, we hold the ratio of $z$ to $\zeta$ constant when liquidity is added or removed. The formula for the new $\zeta$ is:

$$ \tfrac{\zeta_0}{z_0} = \tfrac{\zeta_1}{z_1} \\ \implies \\ \zeta_1 = \zeta_0 \cdot \tfrac{z_1}{z_0} $$

Invariants

Well-defined Pricing

Most AMM invariants are only defined in the first quadrant of the $(z, y)$ plane. With this in mind, we need to enforce the invariant that $z - \zeta > 0$ to ensure that we can swap out our AMM invariant.

Negative Interest

The negative interest invariant doesn't change because we still can't quote prices above 1 base per bond. We'll need to update the check to use the new spot price calculation, but it's a minor change.

Solvency

To maintain the property that all longs can be closed instantaneously (this property will be removed when #13 is implemented), we need to enforce a strong form of the current solvency invariant:

$$ z - \zeta \geq \tfrac{y_l}{c} + z_{min} $$

Since $z - \zeta$ isn't change by flat trades, the a pool that is solvent will remain solvent after flat updates are applied.
The same logic shows that inventory will neither be improved or worsened by the closing of trades.

Examples

TODO: Write up an example with the short sandwich and show that it isn't profitable with a massive short on our curve. It would be good to work through all the math to make sure that it works as expected.

@jrhea
Copy link
Contributor

jrhea commented Jul 28, 2023

Here is a desmos that illustrates the issue we are fixing

https://www.desmos.com/calculator/iw9t3rw0fo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants