Skip to content

Commit

Permalink
refactor(settlement): move CloseMarket -> admin.go
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Oct 24, 2023
1 parent b3dab6b commit 15e06c4
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 136 deletions.
31 changes: 31 additions & 0 deletions x/perp/v2/keeper/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,34 @@ func (k admin) CreateMarket(

return nil
}

// CloseMarket closes the market. From now on, no new position can be opened on
// this market or closed. Only the open positions can be settled by calling
// SettlePosition.
func (k admin) CloseMarket(ctx sdk.Context, pair asset.Pair) (err error) {
market, err := k.GetMarket(ctx, pair)
if err != nil {
return err
}
if !market.Enabled {
return types.ErrMarketNotEnabled
}

amm, err := k.GetAMM(ctx, pair)
if err != nil {
return err
}

settlementPrice, _, err := amm.ComputeSettlementPrice()
if err != nil {
return
}

amm.SettlementPrice = settlementPrice
market.Enabled = false

k.SaveAMM(ctx, amm)
k.SaveMarket(ctx, market)

return nil
}
110 changes: 110 additions & 0 deletions x/perp/v2/keeper/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper_test

import (
"testing"
"time"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -15,6 +16,10 @@ import (
"github.com/NibiruChain/nibiru/x/common/testutil/testapp"
"github.com/NibiruChain/nibiru/x/perp/v2/keeper"
"github.com/NibiruChain/nibiru/x/perp/v2/types"

. "github.com/NibiruChain/nibiru/x/common/testutil/action"
. "github.com/NibiruChain/nibiru/x/perp/v2/integration/action"
. "github.com/NibiruChain/nibiru/x/perp/v2/integration/assertion"
)

func TestAdmin_WithdrawFromInsuranceFund(t *testing.T) {
Expand Down Expand Up @@ -160,3 +165,108 @@ func TestCreateMarket(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint64(2), market.Version)
}

func TestCloseMarket(t *testing.T) {
pairBtcUsdc := asset.Registry.Pair(denoms.BTC, denoms.NUSD)
startTime := time.Now()
alice := testutil.AccAddress()

tc := TestCases{
TC("market can be disabled").
Given(
CreateCustomMarket(pairBtcUsdc, WithEnabled(true)),
SetBlockTime(startTime),
MarketShouldBeEqual(
pairBtcUsdc,
Market_EnableShouldBeEqualTo(true),
),
).
When(
CloseMarket(pairBtcUsdc),
).
Then(
MarketShouldBeEqual(
pairBtcUsdc,
Market_EnableShouldBeEqualTo(false),
),
),
TC("cannot open position on disabled market").
Given(
CreateCustomMarket(
pairBtcUsdc,
WithEnabled(true),
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
),
SetBlockNumber(1),
SetBlockTime(startTime),

FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))),
).
When(
CloseMarket(pairBtcUsdc),
).
Then(
MarketOrderFails(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
types.ErrMarketNotEnabled,
),
),
TC("cannot close position on disabled market").When(
CreateCustomMarket(
pairBtcUsdc,
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
WithEnabled(true),
),
SetBlockNumber(1),
SetBlockTime(startTime),
FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))),
MarketOrder(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
),
).When(
CloseMarket(pairBtcUsdc),
CloseMarketShouldFail(pairBtcUsdc),
CloseMarketShouldFail("random:pair"),
).Then(
ClosePositionFails(alice, pairBtcUsdc, types.ErrMarketNotEnabled),
),
TC("cannot partial close position on disabled market").When(
CreateCustomMarket(
pairBtcUsdc,
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
WithEnabled(true),
),
SetBlockNumber(1),
SetBlockTime(startTime),
FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))),
MarketOrder(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
),
).When(
CloseMarket(pairBtcUsdc),
AMMShouldBeEqual(pairBtcUsdc, AMM_SettlementPriceShoulBeEqual(sdk.MustNewDecFromStr("1.1"))),
).Then(
PartialCloseFails(alice, pairBtcUsdc, sdk.NewDec(5_000), types.ErrMarketNotEnabled),
),
}

NewTestSuite(t).WithTestCases(tc...).Run()
}
31 changes: 0 additions & 31 deletions x/perp/v2/keeper/settlement.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,6 @@ import (
"github.com/NibiruChain/nibiru/x/perp/v2/types"
)

// CloseMarket closes the market. From now on, no new position can be opened on
// this market or closed. Only the open positions can be settled by calling
// SettlePosition.
func (k admin) CloseMarket(ctx sdk.Context, pair asset.Pair) (err error) {
market, err := k.GetMarket(ctx, pair)
if err != nil {
return err
}
if !market.Enabled {
return types.ErrMarketNotEnabled
}

amm, err := k.GetAMM(ctx, pair)
if err != nil {
return err
}

settlementPrice, _, err := amm.ComputeSettlementPrice()
if err != nil {
return
}

amm.SettlementPrice = settlementPrice
market.Enabled = false

k.SaveAMM(ctx, amm)
k.SaveMarket(ctx, market)

return nil
}

// SettlePosition settles a position and transfer the margin and funding payments to the trader.
func (k Keeper) SettlePosition(ctx sdk.Context, pair asset.Pair, version uint64, traderAddr sdk.AccAddress) (resp *types.PositionResp, err error) {
market, err := k.GetMarketByPairAndVersion(ctx, pair, version)
Expand Down
105 changes: 0 additions & 105 deletions x/perp/v2/keeper/settlement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,111 +16,6 @@ import (
"github.com/NibiruChain/nibiru/x/perp/v2/types"
)

func TestDisableMarket(t *testing.T) {
pairBtcUsdc := asset.Registry.Pair(denoms.BTC, denoms.NUSD)
startTime := time.Now()
alice := testutil.AccAddress()

tc := TestCases{
TC("market can be disabled").
Given(
CreateCustomMarket(pairBtcUsdc, WithEnabled(true)),
SetBlockTime(startTime),
MarketShouldBeEqual(
pairBtcUsdc,
Market_EnableShouldBeEqualTo(true),
),
).
When(
CloseMarket(pairBtcUsdc),
).
Then(
MarketShouldBeEqual(
pairBtcUsdc,
Market_EnableShouldBeEqualTo(false),
),
),
TC("cannot open position on disabled market").
Given(
CreateCustomMarket(
pairBtcUsdc,
WithEnabled(true),
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
),
SetBlockNumber(1),
SetBlockTime(startTime),

FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))),
).
When(
CloseMarket(pairBtcUsdc),
).
Then(
MarketOrderFails(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
types.ErrMarketNotEnabled,
),
),
TC("cannot close position on disabled market").When(
CreateCustomMarket(
pairBtcUsdc,
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
WithEnabled(true),
),
SetBlockNumber(1),
SetBlockTime(startTime),
FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))),
MarketOrder(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
),
).When(
CloseMarket(pairBtcUsdc),
CloseMarketShouldFail(pairBtcUsdc),
CloseMarketShouldFail("random:pair"),
).Then(
ClosePositionFails(alice, pairBtcUsdc, types.ErrMarketNotEnabled),
),
TC("cannot partial close position on disabled market").When(
CreateCustomMarket(
pairBtcUsdc,
WithPricePeg(sdk.OneDec()),
WithSqrtDepth(sdk.NewDec(100_000)),
WithEnabled(true),
),
SetBlockNumber(1),
SetBlockTime(startTime),
FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))),
MarketOrder(
alice,
pairBtcUsdc,
types.Direction_LONG,
sdk.NewInt(10_000),
sdk.OneDec(),
sdk.ZeroDec(),
),
).When(
CloseMarket(pairBtcUsdc),
AMMShouldBeEqual(pairBtcUsdc, AMM_SettlementPriceShoulBeEqual(sdk.MustNewDecFromStr("1.1"))),
).Then(
PartialCloseFails(alice, pairBtcUsdc, sdk.NewDec(5_000), types.ErrMarketNotEnabled),
),
}

NewTestSuite(t).WithTestCases(tc...).Run()
}

func TestSettlePosition(t *testing.T) {
pairBtcUsdc := asset.Registry.Pair(denoms.BTC, denoms.NUSD)
startTime := time.Now()
Expand Down

0 comments on commit 15e06c4

Please sign in to comment.