Closed jalextowle closed 10 months ago
After some golfing, I was able to get the effective share reserves down to 2 wei. This is the test:
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;
import { console2 as console } from "forge-std/console2.sol";
import { HyperdriveMath } from "contracts/src/libraries/HyperdriveMath.sol";
import { HyperdriveTest } from "test/utils/HyperdriveTest.sol";
import { HyperdriveUtils } from "test/utils/HyperdriveUtils.sol";
import { Lib } from "test/utils/Lib.sol";
contract ExampleTest is HyperdriveTest {
using HyperdriveUtils for *;
using Lib for *;
function test_example() external {
// Alice initializes the pool.
initialize(alice, 0.02e18, 10e18);
// Bob adds liquidity.
uint256 lpShares = addLiquidity(bob, 1_000_000_000e18);
// Log the minimum share reserves.
console.log(
"Minimum share reserves: %s",
hyperdrive.getPoolConfig().minimumShareReserves.toString(18)
);
// Bob opens a max short.
openShort(bob, hyperdrive.calculateMaxShort());
// The term passes.
advanceTime(POSITION_DURATION, 0);
// Bob opens a max short.
openShort(bob, 2.746469942e18);
// Log the effective share reserves.
console.log(
"Effective share reserves: %s",
HyperdriveMath.calculateEffectiveShareReserves(
hyperdrive.getPoolInfo().shareReserves,
hyperdrive.getPoolInfo().shareAdjustment
).toString(18)
);
// Bob removes his liquidity.
removeLiquidity(bob, lpShares);
// Log the effective share reserves.
console.log(
"Effective share reserves: %s",
HyperdriveMath.calculateEffectiveShareReserves(
hyperdrive.getPoolInfo().shareReserves,
hyperdrive.getPoolInfo().shareAdjustment
).toString(18)
);
}
}
and it produces the following output:
Minimum share reserves: 1.000000000000000000
Effective share reserves: 0.000000000118733682
Effective share reserves: 0.000000000000000002
Now that I know the value can get quite close to 0 with only a few trades, it makes me wonder if this is really okay.
After playing around with the more severe example, I can't open a long or add liquidity. All of the other operations decrease the effective share reserves, so the pool is locked up.
Revisiting this we have the following tension:
LPMath.sol
.With this in mind, I'd like to come up with a simple "middle path" that prevents pathological behavior without enforcing the $z - \zeta \geq z_{min}$ check in the LP flow. Before I can do this, I need to play around with the system in its new state to see how bad the situation is when the effective share reserves are small.
This was addressed by #726.
Overview
It's currently possible for the effective share reserves to drop below $z_{min}$. Here's a test based on 6a4edcf4 that successfully drops the effective share reserves below the minimum share reserves:
This produces the following logs:
Allowing $z - \zeta$ to fall below $z_{min}$ is what we want in cases when $\zeta > 0$ because it ensures that LP's can remove all of the pool's liquidity above the minimum share reserves. On the other hand, this logic conflicts with the implementation of
calculateMaxSell
inYieldSpaceMath
, and it results in the trading curve looking different when $\zeta > 0$ versus when $\zeta \leq 0$ because some of the curve is accessible.