Skip to content

Inconsistency between checks on the effective share reserves and calculateMaxSell #677

@jalextowle

Description

@jalextowle

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:

// 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 {
        initialize(alice, 0.02e18, 100e18);

        // 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);

        // Log the effective share reserves.
        console.log(
            "Effective share reserves: %s",
            HyperdriveMath.calculateEffectiveShareReserves(
                hyperdrive.getPoolInfo().shareReserves,
                hyperdrive.getPoolInfo().shareAdjustment
            ).toString(18)
        );

        // Alice opens a small short.
        openShort(alice, 1e18);

        // Log the effective share reserves.
        console.log(
            "Effective share reserves: %s",
            HyperdriveMath.calculateEffectiveShareReserves(
                hyperdrive.getPoolInfo().shareReserves,
                hyperdrive.getPoolInfo().shareAdjustment
            ).toString(18)
        );
    }
}

This produces the following logs:

  Minimum share reserves: 1.000000000000000000
  Effective share reserves: 1.000000000000000108
  Effective share reserves: 0.238507056401543382

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 in YieldSpaceMath, and it results in the trading curve looking different when $\zeta > 0$ versus when $\zeta \leq 0$ because some of the curve is accessible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions