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

feat: add market version to allow disabling markets #1559

Merged
merged 21 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#1501](https://github.com/NibiruChain/nibiru/pull/1501) - feat(proto): add Python buf generation logic for py-sdk
* [#1503](https://github.com/NibiruChain/nibiru/pull/1503) - feat(wasm): add Oracle Exchange Rate query for wasm
* [#1543](https://github.com/NibiruChain/nibiru/pull/1543) - epic(devgas): devgas module for incentivizing smart contract
* [#1559](https://github.com/NibiruChain/nibiru/pull/1559) - feat: add versions to markets to allow to disable them

### Bug Fixes

Expand Down
15 changes: 15 additions & 0 deletions proto/nibiru/perp/v2/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types";
message GenesisState {
repeated Market markets = 2 [ (gogoproto.nullable) = false ];

repeated GenesisMarketLastVersion market_last_versions = 8 [ (gogoproto.nullable) = false ];

repeated AMM amms = 3 [ (gogoproto.nullable) = false ];

repeated Position positions = 4 [ (gogoproto.nullable) = false ];

repeated ReserveSnapshot reserve_snapshots = 5
[ (gogoproto.nullable) = false ];

uint64 dnr_epoch = 6;

repeated TraderVolume trader_volumes = 7 [ (gogoproto.nullable) = false ];

message TraderVolume {
Expand All @@ -30,4 +34,15 @@ message GenesisState {
(gogoproto.nullable) = false
];
}
}

// GenesisMarketLastVersion is the last version including pair only used for genesis
message GenesisMarketLastVersion {
string pair = 1 [
(gogoproto.customtype) =
"github.com/NibiruChain/nibiru/x/common/asset.Pair",
(gogoproto.nullable) = false
];

uint64 version = 2;
}
14 changes: 14 additions & 0 deletions proto/nibiru/perp/v2/state.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ message Market {
// whether or not the market is enabled
bool enabled = 2;

// the version of the Market, only one market can exist per pair, when one is closed it cannot be reactivated,
// so a new market must be created, this is the version of the market
uint64 version = 14;

// the minimum margin ratio which a user must maintain on this market
string maintenance_margin_ratio = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
Expand Down Expand Up @@ -114,6 +118,12 @@ message Market {
];
}

// MarketLastVersion is used to store the last version of the market
message MarketLastVersion {
// version of the market
uint64 version = 1;
}

message AMM {
// identifies the market this AMM belongs to
string pair = 1 [
Expand All @@ -122,6 +132,10 @@ message AMM {
(gogoproto.nullable) = false
];

// the version of the AMM, only one AMM can exist per pair, when one is closed it cannot be reactivated,
// so a new AMM must be created, this is the version of the AMM
uint64 version = 8;

// the amount of base reserves this AMM has
string base_reserve = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
Expand Down
2 changes: 1 addition & 1 deletion x/common/asset/pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func NewPair(base string, quote string) Pair {
return Pair(ap)
}

// New returns a new asset pair instance if the pair is valid.
// TryNewPair New returns a new asset pair instance if the pair is valid.
// The form, "token0:token1", is expected for 'pair'.
// Use this function to return an error instead of panicking.
func TryNewPair(pair string) (Pair, error) {
Expand Down
30 changes: 26 additions & 4 deletions x/common/testutil/genesis/perp_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
asset.Registry.Pair(denoms.BTC, denoms.NUSD): {
Market: perpv2types.Market{
Pair: asset.NewPair(denoms.BTC, denoms.NUSD),
Version: 1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't want to start with 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the one given that 0 is the typical default value in proto

Enabled: true,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.04"),
MaxLeverage: sdk.MustNewDecFromStr("20"),
Expand All @@ -35,6 +36,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
},
Amm: perpv2types.AMM{
Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(10e6),
QuoteReserve: sdk.NewDec(10e6),
SqrtDepth: sdk.NewDec(10e6),
Expand All @@ -47,6 +49,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
Market: perpv2types.Market{
Pair: asset.NewPair(denoms.ATOM, denoms.NUSD),
Enabled: true,
Version: 1,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"),
MaxLeverage: sdk.MustNewDecFromStr("15"),
ExchangeFeeRatio: sdk.MustNewDecFromStr("0.0010"),
Expand All @@ -61,6 +64,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
},
Amm: perpv2types.AMM{
Pair: asset.Registry.Pair(denoms.ATOM, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(10e6),
QuoteReserve: sdk.NewDec(10e6),
SqrtDepth: sdk.NewDec(10e6),
Expand All @@ -73,6 +77,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
Market: perpv2types.Market{
Pair: asset.NewPair(denoms.OSMO, denoms.NUSD),
Enabled: true,
Version: 1,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"),
MaxLeverage: sdk.MustNewDecFromStr("15"),
ExchangeFeeRatio: sdk.MustNewDecFromStr("0.0010"),
Expand All @@ -87,6 +92,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {
},
Amm: perpv2types.AMM{
Pair: asset.Registry.Pair(denoms.OSMO, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(10e6),
QuoteReserve: sdk.NewDec(10e6),
SqrtDepth: sdk.NewDec(10e6),
Expand All @@ -102,16 +108,22 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState {

var marketsv2 []perpv2types.Market
var ammsv2 []perpv2types.AMM
var marketLastVersions []perpv2types.GenesisMarketLastVersion
for _, marketAmm := range extraMarketAmms {
marketsv2 = append(marketsv2, marketAmm.Market)
ammsv2 = append(ammsv2, marketAmm.Amm)
marketLastVersions = append(marketLastVersions, perpv2types.GenesisMarketLastVersion{
Pair: marketAmm.Market.Pair,
Version: marketAmm.Market.Version,
})
}

perpV2Gen := &perpv2types.GenesisState{
Markets: marketsv2,
Amms: ammsv2,
Positions: []perpv2types.Position{},
ReserveSnapshots: []perpv2types.ReserveSnapshot{},
Markets: marketsv2,
MarketLastVersions: marketLastVersions,
Amms: ammsv2,
Positions: []perpv2types.Position{},
ReserveSnapshots: []perpv2types.ReserveSnapshot{},
}

gen[perpv2types.ModuleName] = TEST_ENCODING_CONFIG.Marshaler.
Expand All @@ -124,6 +136,7 @@ var START_MARKETS = map[asset.Pair]perpv2types.AmmMarket{
Market: perpv2types.Market{
Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD),
Enabled: true,
Version: 1,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"),
MaxLeverage: sdk.MustNewDecFromStr("15"),
LatestCumulativePremiumFraction: sdk.ZeroDec(),
Expand All @@ -138,6 +151,7 @@ var START_MARKETS = map[asset.Pair]perpv2types.AmmMarket{
},
Amm: perpv2types.AMM{
Pair: asset.Registry.Pair(denoms.ETH, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(10e6),
QuoteReserve: sdk.NewDec(10e6),
SqrtDepth: sdk.NewDec(10e6),
Expand All @@ -150,6 +164,7 @@ var START_MARKETS = map[asset.Pair]perpv2types.AmmMarket{
Market: perpv2types.Market{
Pair: asset.Registry.Pair(denoms.NIBI, denoms.NUSD),
Enabled: true,
Version: 1,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.04"),
MaxLeverage: sdk.MustNewDecFromStr("20"),
LatestCumulativePremiumFraction: sdk.ZeroDec(),
Expand All @@ -164,6 +179,7 @@ var START_MARKETS = map[asset.Pair]perpv2types.AmmMarket{
},
Amm: perpv2types.AMM{
Pair: asset.Registry.Pair(denoms.NIBI, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(10 * common.TO_MICRO),
QuoteReserve: sdk.NewDec(10 * common.TO_MICRO),
SqrtDepth: common.MustSqrtDec(sdk.NewDec(10 * common.TO_MICRO * 10 * common.TO_MICRO)),
Expand Down Expand Up @@ -193,6 +209,12 @@ func PerpV2Genesis() *perpv2types.GenesisState {
PrepaidBadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()),
},
},
MarketLastVersions: []perpv2types.GenesisMarketLastVersion{
{
Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD),
Version: 1,
},
},
Amms: []perpv2types.AMM{
{
Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD),
Expand Down
1 change: 1 addition & 0 deletions x/common/testutil/mock/perp_amm.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
func TestAMMDefault() *types.AMM {
return &types.AMM{
Pair: asset.NewPair(denoms.BTC, denoms.NUSD),
Version: 1,
BaseReserve: sdk.NewDec(1e12),
QuoteReserve: sdk.NewDec(1e12),
SqrtDepth: sdk.NewDec(1e12),
Expand Down
1 change: 1 addition & 0 deletions x/common/testutil/mock/perp_market.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func TestMarket() *types.Market {
return &types.Market{
Pair: asset.NewPair(denoms.BTC, denoms.NUSD),
Enabled: true,
Version: 1,
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"),
MaxLeverage: sdk.MustNewDecFromStr("10"),
LatestCumulativePremiumFraction: sdk.ZeroDec(),
Expand Down
2 changes: 1 addition & 1 deletion x/epochs/types/identifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func ValidateEpochIdentifierInterface(i interface{}) error {
return ValidateEpochIdentifierString(v)
}

// ValidateEpochIdentifierInterface performs a stateless
// ValidateEpochIdentifierString performs a stateless
// validation of the epoch ID.
func ValidateEpochIdentifierString(s string) error {
s = strings.TrimSpace(s)
Expand Down
12 changes: 7 additions & 5 deletions x/perp/v2/integration/action/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type logger struct {
log string
}

func (e logger) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
func (e logger) Do(_ *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
fmt.Println(e.log)
return ctx, nil, true
}
Expand All @@ -39,8 +39,9 @@ type createMarketAction struct {
}

func (c createMarketAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
app.PerpKeeperV2.Markets.Insert(ctx, c.Market.Pair, c.Market)
app.PerpKeeperV2.AMMs.Insert(ctx, c.AMM.Pair, c.AMM)
app.PerpKeeperV2.MarketLastVersion.Insert(ctx, c.Market.Pair, types.MarketLastVersion{Version: 1})
app.PerpKeeperV2.SaveMarket(ctx, c.Market)
app.PerpKeeperV2.SaveAMM(ctx, c.AMM)

app.PerpKeeperV2.ReserveSnapshots.Insert(ctx, collections.Join(c.AMM.Pair, ctx.BlockTime()), types.ReserveSnapshot{
Amm: c.AMM,
Expand All @@ -55,6 +56,7 @@ func CreateCustomMarket(pair asset.Pair, marketModifiers ...marketModifier) acti
market := types.DefaultMarket(pair)
amm := types.AMM{
Pair: pair,
Version: 1,
BaseReserve: sdk.NewDec(1e12),
QuoteReserve: sdk.NewDec(1e12),
SqrtDepth: sdk.NewDec(1e12),
Expand All @@ -64,11 +66,11 @@ func CreateCustomMarket(pair asset.Pair, marketModifiers ...marketModifier) acti
}

for _, modifier := range marketModifiers {
modifier(market, &amm)
modifier(&market, &amm)
}

return createMarketAction{
Market: *market,
Market: market,
AMM: amm,
}
}
Expand Down
2 changes: 1 addition & 1 deletion x/perp/v2/integration/action/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ type QueryMarketsChecker func(resp []types.AmmMarket) error
func QueryMarkets_MarketsShouldContain(expectedMarket types.Market) QueryMarketsChecker {
return func(resp []types.AmmMarket) error {
for _, market := range resp {
if types.MarketsAreEqual(&expectedMarket, &market.Market) == nil {
if types.MarketsAreEqual(expectedMarket, market.Market) == nil {
return nil
}
}
Expand Down
3 changes: 2 additions & 1 deletion x/perp/v2/integration/action/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ type insertReserveSnapshot struct {
}

func (i insertReserveSnapshot) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
amm := app.PerpKeeperV2.AMMs.GetOr(ctx, i.pair, types.AMM{
amm := app.PerpKeeperV2.AMMs.GetOr(ctx, collections.Join(i.pair, uint64(1)), types.AMM{
Pair: i.pair,
Version: uint64(1),
BaseReserve: sdk.ZeroDec(),
QuoteReserve: sdk.ZeroDec(),
SqrtDepth: sdk.ZeroDec(),
Expand Down
2 changes: 1 addition & 1 deletion x/perp/v2/integration/action/withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type withdraw struct {
func (w withdraw) Do(app *app.NibiruApp, ctx sdk.Context) (
outCtx sdk.Context, err error, isMandatory bool,
) {
market, err := app.PerpKeeperV2.Markets.Get(ctx, w.Pair)
market, err := app.PerpKeeperV2.GetMarket(ctx, w.Pair)
if err != nil {
return ctx, err, true
}
Expand Down
19 changes: 15 additions & 4 deletions x/perp/v2/integration/assertion/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package assertion
import (
"fmt"

"github.com/NibiruChain/nibiru/x/common/testutil/action"

sdkmath "cosmossdk.io/math"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -20,7 +22,7 @@ type marketShouldBeEqual struct {
}

func (m marketShouldBeEqual) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
market, err := app.PerpKeeperV2.Markets.Get(ctx, m.Pair)
market, err := app.PerpKeeperV2.GetMarket(ctx, m.Pair)
if err != nil {
return ctx, err, false
}
Expand All @@ -34,7 +36,7 @@ func (m marketShouldBeEqual) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Contex
return ctx, nil, false
}

func MarketShouldBeEqual(pair asset.Pair, marketCheckers ...MarketChecker) marketShouldBeEqual {
func MarketShouldBeEqual(pair asset.Pair, marketCheckers ...MarketChecker) action.Action {
return marketShouldBeEqual{
Pair: pair,
Checkers: marketCheckers,
Expand Down Expand Up @@ -77,7 +79,7 @@ type ammShouldBeEqual struct {
type AMMChecker func(amm types.AMM) error

func (a ammShouldBeEqual) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
amm, err := app.PerpKeeperV2.AMMs.Get(ctx, a.Pair)
amm, err := app.PerpKeeperV2.GetAMM(ctx, a.Pair)
if err != nil {
return ctx, err, false
}
Expand All @@ -91,7 +93,7 @@ func (a ammShouldBeEqual) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context,
return ctx, nil, false
}

func AMMShouldBeEqual(pair asset.Pair, ammCheckers ...AMMChecker) ammShouldBeEqual {
func AMMShouldBeEqual(pair asset.Pair, ammCheckers ...AMMChecker) action.Action {
return ammShouldBeEqual{
Pair: pair,
Checkers: ammCheckers,
Expand Down Expand Up @@ -152,3 +154,12 @@ func AMM_BiasShouldBeEqual(expectedBias sdk.Dec) AMMChecker {
return nil
}
}

func AMM_VersionShouldBeEqual(expectedVersion uint64) AMMChecker {
return func(amm types.AMM) error {
if amm.Version != expectedVersion {
return fmt.Errorf("expected version to be %d, got %d", expectedVersion, amm.Version)
}
return nil
}
}
Loading
Loading