diff --git a/.github/workflows/changelog-deps.yml b/.github/workflows/changelog-deps.yml index b9336196d3..4e20a6d04f 100644 --- a/.github/workflows/changelog-deps.yml +++ b/.github/workflows/changelog-deps.yml @@ -1,26 +1,28 @@ name: "Automatically update changelog with dependabot" -on: +on: pull_request: types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] jobs: changelog-update: runs-on: ubuntu-latest + + # TODO: feat: try to use author of the commit(s) to see if it's dependabot + # ${{ any(contains(commit.author.username, 'dependabot') for commit in github.event.commits) }} if: contains(github.event.pull_request.labels.*.name, 'dependabot') - # TODO: feat: try to use author of the commit(s) to see if it's dependabot - # ${{ any(contains(commit.author.username, 'dependabot') for commit in github.event.commits) }} - steps: + + steps: - uses: actions/checkout@v4 with: - token: ${{ secrets.NIBIRU_PM }} + token: ${{ secrets.NIBIBOT_GIT_TOKEN }} # to avoid checking out the repo in a detached state ref: ${{ github.head_ref }} # Helps keep your repository up-to-date when Dependabot updates your dependencies. # This step updates adds a line to the "## Unreleased" section - uses: dangoslen/dependabot-changelog-helper@v3 with: - activationLabel: 'dependabot' - changelogPath: './CHANGELOG.md' + activationLabel: "dependabot" + changelogPath: "./CHANGELOG.md" - uses: stefanzweifel/git-auto-commit-action@v5 with: diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 7ffa17164a..e9f512f7e9 100644 --- a/.github/workflows/proto-lint.yml +++ b/.github/workflows/proto-lint.yml @@ -22,7 +22,7 @@ jobs: # timeout-minutes: 5 # steps: # - uses: actions/checkout@v4 - # - uses: bufbuild/buf-setup-action@v1.27.2 + # - uses: bufbuild/buf-setup-action@v1.28.0 # - uses: bufbuild/buf-lint-action@v1 # with: # input: "proto" @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.27.2 + - uses: bufbuild/buf-setup-action@v1.28.0 with: github_token: ${{ github.token }} - uses: bufbuild/buf-breaking-action@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eda47a871..824c25c0b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#1620](https://github.com/NibiruChain/nibiru/pull/1620) - Token factory transaction messages for Mint and Burn * [#1573](https://github.com/NibiruChain/nibiru/pull/1573) - feat(perp): Close markets and compute settlement price * [#1632](https://github.com/NibiruChain/nibiru/pull/1632) - feat(perp): Add settle position transaction +* [#1656](https://github.com/NibiruChain/nibiru/pull/1656) - feat(perp): Make the collateral denom a stateful collections.Item +* [#1670](https://github.com/NibiruChain/nibiru/pull/1670) - feat(inflation): Make inflation polynomial ### State Machine Breaking @@ -71,7 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Dependencies - Bump `github.com/prometheus/client_golang` from 1.16.0 to 1.17.0 ([#1605](https://github.com/NibiruChain/nibiru/pull/1605)) -- Bump `bufbuild/buf-setup-action` from 1.26.1 to 1.27.2 ([#1624](https://github.com/NibiruChain/nibiru/pull/1624), [#1641](https://github.com/NibiruChain/nibiru/pull/1641), [#1654](https://github.com/NibiruChain/nibiru/pull/1654)) +- Bump `bufbuild/buf-setup-action` from 1.26.1 to 1.28.0 ([#1624](https://github.com/NibiruChain/nibiru/pull/1624), [#1641](https://github.com/NibiruChain/nibiru/pull/1641), [#1654](https://github.com/NibiruChain/nibiru/pull/1654), [#1671](https://github.com/NibiruChain/nibiru/pull/1671)) - Bump `stefanzweifel/git-auto-commit-action` from 4 to 5 ([#1625](https://github.com/NibiruChain/nibiru/pull/1625)) - Bump `github.com/CosmWasm/wasmvm` from 1.4.0 to 1.5.0 ([#1629](https://github.com/NibiruChain/nibiru/pull/1629), [#1657](https://github.com/NibiruChain/nibiru/pull/1657)) - Bump `google.golang.org/grpc` from 1.58.2 to 1.59.0 ([#1633](https://github.com/NibiruChain/nibiru/pull/1633), [#1643](https://github.com/NibiruChain/nibiru/pull/1643)) @@ -784,4 +786,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Testing * [#695](https://github.com/NibiruChain/nibiru/pull/695) Add `OpenPosition` integration tests. -* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods. \ No newline at end of file +* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods. diff --git a/app/keepers.go b/app/keepers.go index 01430d884b..dd3a5bfe7a 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -364,13 +364,14 @@ func (app *NibiruApp) InitKeepers( appCodec, keys[epochstypes.StoreKey], ) + app.SudoKeeper = keeper.NewKeeper( + appCodec, keys[sudotypes.StoreKey], + ) + app.PerpKeeperV2 = perpkeeper.NewKeeper( appCodec, keys[perptypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.OracleKeeper, app.EpochsKeeper, - ) - - app.SudoKeeper = keeper.NewKeeper( - appCodec, keys[sudotypes.StoreKey], + app.SudoKeeper, ) app.InflationKeeper = inflationkeeper.NewKeeper( diff --git a/proto/nibiru/inflation/v1/genesis.proto b/proto/nibiru/inflation/v1/genesis.proto index 6eacf44c4f..e72fff223b 100644 --- a/proto/nibiru/inflation/v1/genesis.proto +++ b/proto/nibiru/inflation/v1/genesis.proto @@ -23,14 +23,23 @@ message Params { // inflation_enabled is the parameter that enables inflation and halts // increasing the skipped_epochs bool inflation_enabled = 1; - // exponential_calculation takes in the variables to calculate exponential + // polynomial_factors takes in the variables to calculate polynomial // inflation - ExponentialCalculation exponential_calculation = 2 - [ (gogoproto.nullable) = false ]; + repeated string polynomial_factors = 2[ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; // inflation_distribution of the minted denom InflationDistribution inflation_distribution = 3 [ (gogoproto.nullable) = false ]; // epochs_per_period is the number of epochs that must pass before a new // period is created uint64 epochs_per_period = 4; + + // periods_per_year is the number of periods that occur in a year + uint64 periods_per_year = 5; + + // max_period is the maximum number of periods that have inflation being + // paid off. After this period, inflation will be disabled. + uint64 max_period = 6; } diff --git a/proto/nibiru/inflation/v1/inflation.proto b/proto/nibiru/inflation/v1/inflation.proto index ca900bb9e5..cad921ede1 100644 --- a/proto/nibiru/inflation/v1/inflation.proto +++ b/proto/nibiru/inflation/v1/inflation.proto @@ -28,25 +28,3 @@ message InflationDistribution { (gogoproto.nullable) = false ]; } - -// ExponentialCalculation holds factors to calculate exponential inflation on -// each period. Calculation reference: -// periodProvision = exponentialDecay -// f(x) = a * (1 - r) ^ x + c -message ExponentialCalculation { - // a defines the initial value - string a = 1 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // r defines the reduction factor - string r = 2 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; - // c defines the parameter for long term inflation - string c = 3 [ - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", - (gogoproto.nullable) = false - ]; -} diff --git a/proto/nibiru/perp/v2/genesis.proto b/proto/nibiru/perp/v2/genesis.proto index 66ca0a8a84..01410cdcc2 100644 --- a/proto/nibiru/perp/v2/genesis.proto +++ b/proto/nibiru/perp/v2/genesis.proto @@ -2,9 +2,9 @@ syntax = "proto3"; package nibiru.perp.v2; -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; import "nibiru/perp/v2/state.proto"; option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; @@ -33,6 +33,9 @@ message GenesisState { ]; } + // For testing purposes, we allow the collateral to be set at genesis + string collateral_denom = 11; + repeated TraderVolume trader_volumes = 7 [ (gogoproto.nullable) = false ]; message Discount { @@ -81,4 +84,4 @@ message GenesisPosition { uint64 version = 2; Position position = 3 [ (gogoproto.nullable) = false ]; -} \ No newline at end of file +} diff --git a/proto/nibiru/perp/v2/tx.proto b/proto/nibiru/perp/v2/tx.proto index 261c4feefa..f6b799694b 100644 --- a/proto/nibiru/perp/v2/tx.proto +++ b/proto/nibiru/perp/v2/tx.proto @@ -28,6 +28,9 @@ service Msg { rpc DonateToEcosystemFund(MsgDonateToEcosystemFund) returns (MsgDonateToEcosystemFundResponse) {} + + rpc ChangeCollateralDenom(MsgChangeCollateralDenom) + returns (MsgChangeCollateralDenomResponse) {} } // -------------------------- Settle Position -------------------------- @@ -328,3 +331,14 @@ message MsgDonateToEcosystemFund { } message MsgDonateToEcosystemFundResponse {} + +// ----------------------- MsgChangeCollateralDenom ----------------------- + +// MsgChangeCollateralDenom: Changes the collateral denom for the module. +// [Admin] Only callable by sudoers. +message MsgChangeCollateralDenom { + string sender = 1; + string new_denom = 2; +} + +message MsgChangeCollateralDenomResponse {} diff --git a/wasmbinding/exec_perp_test.go b/wasmbinding/exec_perp_test.go index 652eb787ca..20a2159adf 100644 --- a/wasmbinding/exec_perp_test.go +++ b/wasmbinding/exec_perp_test.go @@ -52,7 +52,7 @@ func (s *TestSuitePerpExecutor) SetupSuite() { }) coins := sdk.NewCoins( sdk.NewCoin(denoms.NIBI, sdk.NewInt(1_000_000)), - sdk.NewCoin(denoms.NUSD, sdk.NewInt(420_000*69)), + sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(420_000*69)), sdk.NewCoin(denoms.USDT, sdk.NewInt(420_000*69)), ) s.NoError(testapp.FundAccount(nibiru.BankKeeper, ctx, sender, coins)) @@ -66,6 +66,7 @@ func (s *TestSuitePerpExecutor) SetupSuite() { s.exec = &wasmbinding.ExecutorPerp{ PerpV2: nibiru.PerpKeeperV2, } + s.nibiru.PerpKeeperV2.Collateral.Set(s.ctx, perpv2types.TestingCollateralDenomNUSD) s.NoError(testapp.FundAccount(nibiru.BankKeeper, ctx, s.contractPerp, coins)) s.OnSetupEnd() @@ -79,7 +80,8 @@ func (s *TestSuitePerpExecutor) OnSetupEnd() { // Happy path coverage of MarketOrder, AddMargin, RemoveMargin, and ClosePosition func (s *TestSuitePerpExecutor) TestOpenAddRemoveClose() { pair := asset.MustNewPair(s.happyFields.Pair) - margin := sdk.NewCoin(denoms.NUSD, sdk.NewInt(69)) + + margin := sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(69)) incorrectMargin := sdk.NewCoin(denoms.USDT, sdk.NewInt(69)) for _, err := range []error{ @@ -243,7 +245,7 @@ func (s *TestSuitePerpExecutor) DoInsuranceFundWithdrawTest( s.nibiru.BankKeeper, s.ctx, perpv2types.PerpEFModuleAccount, - sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(420))), + sdk.NewCoins(sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(420))), ) s.NoError(err) @@ -330,7 +332,7 @@ func (s *TestSuitePerpExecutor) DoSetMarketEnabledTest( } func (s *TestSuitePerpExecutor) TestSadPath_InsuranceFundWithdraw() { - fundsToWithdraw := sdk.NewCoin(denoms.NUSD, sdk.NewInt(69_000)) + fundsToWithdraw := sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(69_000)) err := s.DoInsuranceFundWithdrawTest(fundsToWithdraw.Amount, s.contractDeployer) s.Error(err) @@ -339,7 +341,7 @@ func (s *TestSuitePerpExecutor) TestSadPath_InsuranceFundWithdraw() { func (s *TestSuitePerpExecutor) TestSadPaths_InvalidPair() { sadPair := asset.Pair("ftt:ust:doge") pair := sadPair - margin := sdk.NewCoin(denoms.NUSD, sdk.NewInt(69)) + margin := sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(69)) for _, err := range []error{ s.DoMarketOrderTest(pair), diff --git a/wasmbinding/exec_test.go b/wasmbinding/exec_test.go index 7c3912b1ed..a02fd36a9b 100644 --- a/wasmbinding/exec_test.go +++ b/wasmbinding/exec_test.go @@ -98,9 +98,11 @@ func (s *TestSuiteExecutor) SetupSuite() { ChainID: "nibiru-wasmnet-1", Time: time.Now().UTC(), }) + nibiru.PerpKeeperV2.Collateral.Set(ctx, perpv2types.TestingCollateralDenomNUSD) + coins := sdk.NewCoins( sdk.NewCoin(denoms.NIBI, sdk.NewInt(10_000_000)), - sdk.NewCoin(denoms.NUSD, sdk.NewInt(420_000*69)), + sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(420_000*69)), ) s.NoError(testapp.FundAccount(nibiru.BankKeeper, ctx, sender, coins)) @@ -110,6 +112,7 @@ func (s *TestSuiteExecutor) SetupSuite() { s.ctx = ctx s.keeper = TestOnlySudoKeeper{Keeper: s.nibiru.SudoKeeper} s.wasmKeeper = wasmkeeper.NewDefaultPermissionKeeper(nibiru.WasmKeeper) + s.nibiru.PerpKeeperV2.Collateral.Set(s.ctx, perpv2types.TestingCollateralDenomNUSD) s.contractPerp = ContractMap[wasmbin.WasmKeyPerpBinding] s.contractController = ContractMap[wasmbin.WasmKeyController] @@ -126,10 +129,10 @@ func (s *TestSuiteExecutor) OnSetupEnd() { func (s *TestSuiteExecutor) TestOpenAddRemoveClose() { pair := asset.MustNewPair(s.happyFields.Pair) - margin := sdk.NewCoin(denoms.NUSD, sdk.NewInt(69)) + margin := sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(69)) coins := sdk.NewCoins( - margin.Add(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1_000))), + margin.Add(sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(1_000))), ) s.NoError(testapp.FundAccount(s.nibiru.BankKeeper, s.ctx, s.contractPerp, coins)) @@ -466,7 +469,7 @@ func (s *TestSuiteExecutor) TestInsuranceFundWithdraw() { s.nibiru.BankKeeper, s.ctx, perpv2types.PerpEFModuleAccount, - sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(420))), + sdk.NewCoins(sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(420))), ) s.NoError(err) s.keeper.SetSudoContracts( diff --git a/wasmbinding/querier_perp_test.go b/wasmbinding/querier_perp_test.go index 28d25a12c8..efd8d644ad 100644 --- a/wasmbinding/querier_perp_test.go +++ b/wasmbinding/querier_perp_test.go @@ -94,7 +94,7 @@ func (s *TestSuitePerpQuerier) SetupSuite() { }) coins := sdk.NewCoins( sdk.NewCoin(denoms.NIBI, sdk.NewInt(10_000_000)), - sdk.NewCoin(denoms.NUSD, sdk.NewInt(1_420_000)), + sdk.NewCoin(perpv2types.TestingCollateralDenomNUSD, sdk.NewInt(1_420_000)), ) s.NoError(testapp.FundAccount(nibiru.BankKeeper, ctx, sender, coins)) diff --git a/x/common/address.go b/x/common/address.go index 9687293617..67bf644d55 100644 --- a/x/common/address.go +++ b/x/common/address.go @@ -1,6 +1,7 @@ package common import ( + "github.com/NibiruChain/collections" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,3 +21,13 @@ func StringsToAddrs(strs ...string) []sdk.AccAddress { } return addrs } + +// TODO: (realu) Move to collections library +var StringValueEncoder collections.ValueEncoder[string] = stringValueEncoder{} + +type stringValueEncoder struct{} + +func (a stringValueEncoder) Encode(value string) []byte { return []byte(value) } +func (a stringValueEncoder) Decode(b []byte) string { return string(b) } +func (a stringValueEncoder) Stringify(value string) string { return value } +func (a stringValueEncoder) Name() string { return "string" } diff --git a/x/common/address_test.go b/x/common/address_test.go index 77f156f08c..031a55918e 100644 --- a/x/common/address_test.go +++ b/x/common/address_test.go @@ -3,6 +3,7 @@ package common_test import ( "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/NibiruChain/nibiru/x/common" @@ -17,3 +18,25 @@ func TestAddress(t *testing.T) { require.EqualValues(t, addrs, addrsOut) }) } + +func TestStringValueEncoder(t *testing.T) { + encoder := common.StringValueEncoder + tests := []struct { + given string + }{ + {"hello"}, + {"12345"}, + {""}, + {testutil.AccAddress().String()}, + } + + for _, tc := range tests { + t.Run(tc.given, func(t *testing.T) { + want := tc.given + encoded := encoder.Encode(tc.given) + got := encoder.Decode(encoded) + assert.Equal(t, want, got) + assert.Equal(t, want, encoder.Stringify(got)) + }) + } +} diff --git a/x/common/constants.go b/x/common/constants.go index 9b0a36fdc7..ae5fe5522c 100644 --- a/x/common/constants.go +++ b/x/common/constants.go @@ -1,7 +1,15 @@ package common +import sdk "github.com/cosmos/cosmos-sdk/types" + const ( TreasuryPoolModuleAccount = "treasury_pool" // TO_MICRO: multiplier for converting between units and micro-units. TO_MICRO = int64(1_000_000) + + NibiruTeam = "nibi1l8dxzwz9d4peazcqjclnkj2mhvtj7mpnkqx85mg0ndrlhwrnh7gskkzg0v" ) + +func NibiruTeamAddr() sdk.AccAddress { + return sdk.MustAccAddressFromBech32(NibiruTeam) +} diff --git a/x/common/error.go b/x/common/error.go index 8036faa776..a7c9ba9d38 100644 --- a/x/common/error.go +++ b/x/common/error.go @@ -4,6 +4,9 @@ import ( "errors" "fmt" "runtime/debug" + + grpccodes "google.golang.org/grpc/codes" + grpcstatus "google.golang.org/grpc/status" ) // TryCatch is an implementation of the try-catch block from languages like C++ and JS. @@ -180,3 +183,7 @@ func CombineErrorsFromStrings(strs ...string) (err error) { } return CombineErrors(errs...) } + +func ErrNilMsg() error { + return grpcstatus.Errorf(grpccodes.InvalidArgument, "nil msg") +} diff --git a/x/common/testutil/cli/network.go b/x/common/testutil/cli/network.go index 897f286a51..b80d227ebf 100644 --- a/x/common/testutil/cli/network.go +++ b/x/common/testutil/cli/network.go @@ -42,6 +42,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "google.golang.org/grpc" + perpV2types "github.com/NibiruChain/nibiru/x/perp/v2/types" + "github.com/NibiruChain/nibiru/x/common/denoms" "github.com/NibiruChain/nibiru/app" @@ -174,6 +176,7 @@ func BuildNetworkConfig(appGenesis app.GenesisState) Config { BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), StartingTokens: sdk.NewCoins( sdk.NewCoin(denoms.NUSD, sdk.TokensFromConsensusPower(1e12, sdk.DefaultPowerReduction)), + sdk.NewCoin(perpV2types.TestingCollateralDenomNUSD, sdk.TokensFromConsensusPower(1e12, sdk.DefaultPowerReduction)), sdk.NewCoin(denoms.NIBI, sdk.TokensFromConsensusPower(1e12, sdk.DefaultPowerReduction)), sdk.NewCoin(denoms.USDC, sdk.TokensFromConsensusPower(1e12, sdk.DefaultPowerReduction)), ), diff --git a/x/common/testutil/genesis/perp_genesis.go b/x/common/testutil/genesis/perp_genesis.go index a15bb4f761..b1d3326369 100644 --- a/x/common/testutil/genesis/perp_genesis.go +++ b/x/common/testutil/genesis/perp_genesis.go @@ -122,6 +122,7 @@ func AddPerpV2Genesis(gen app.GenesisState) app.GenesisState { Amms: ammsv2, Positions: []perpv2types.GenesisPosition{}, ReserveSnapshots: []perpv2types.ReserveSnapshot{}, + CollateralDenom: perpv2types.TestingCollateralDenomNUSD, } gen[perpv2types.ModuleName] = app.MakeEncodingConfig().Marshaler. diff --git a/x/common/testutil/testapp/testapp.go b/x/common/testutil/testapp/testapp.go index 0d7443791d..4682a29a65 100644 --- a/x/common/testutil/testapp/testapp.go +++ b/x/common/testutil/testapp/testapp.go @@ -17,6 +17,7 @@ import ( "github.com/NibiruChain/nibiru/x/common/denoms" epochstypes "github.com/NibiruChain/nibiru/x/epochs/types" inflationtypes "github.com/NibiruChain/nibiru/x/inflation/types" + "github.com/NibiruChain/nibiru/x/perp/v2/types" ) // NewNibiruTestAppAndContext creates an 'app.NibiruApp' instance with an @@ -34,6 +35,8 @@ func NewNibiruTestAppAndContext() (*app.NibiruApp, sdk.Context) { app.OracleKeeper.SetPrice(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), sdk.NewDec(20000)) app.OracleKeeper.SetPrice(ctx, "xxx:yyy", sdk.NewDec(20000)) + app.PerpKeeperV2.Collateral.Set(ctx, types.TestingCollateralDenomNUSD) + return app, ctx } diff --git a/x/epochs/types/query.pb.go b/x/epochs/types/query.pb.go index e486ff1167..bab7018fbc 100644 --- a/x/epochs/types/query.pb.go +++ b/x/epochs/types/query.pb.go @@ -208,33 +208,33 @@ func init() { func init() { proto.RegisterFile("nibiru/epochs/v1/query.proto", fileDescriptor_2d273c3d69b40555) } var fileDescriptor_2d273c3d69b40555 = []byte{ - // 413 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4f, 0x8b, 0xd3, 0x40, - 0x14, 0xcf, 0xd4, 0x5a, 0x70, 0xac, 0x20, 0x83, 0x68, 0x8c, 0x35, 0x2d, 0xf1, 0x0f, 0xb5, 0x96, - 0x0c, 0xa9, 0x27, 0x3d, 0x49, 0x8b, 0x82, 0x17, 0xc1, 0xe0, 0xc9, 0x8b, 0x4c, 0xe2, 0x34, 0x1d, - 0xb0, 0x33, 0x69, 0x66, 0x52, 0xec, 0xd5, 0xd3, 0x1e, 0x17, 0x96, 0xfd, 0x12, 0xfb, 0x49, 0x7a, - 0x2c, 0xec, 0x65, 0x4f, 0xcb, 0xd2, 0xee, 0x07, 0x59, 0x3a, 0x93, 0x2e, 0xdd, 0xfe, 0x81, 0xde, - 0x92, 0xf7, 0xfb, 0xf3, 0x7e, 0xef, 0xbd, 0x81, 0x35, 0xce, 0x22, 0x96, 0xe5, 0x98, 0xa6, 0x22, - 0x1e, 0x48, 0x3c, 0x0e, 0xf0, 0x28, 0xa7, 0xd9, 0xc4, 0x4f, 0x33, 0xa1, 0x04, 0x7a, 0x6c, 0x50, - 0xdf, 0xa0, 0xfe, 0x38, 0x70, 0x9e, 0x24, 0x22, 0x11, 0x1a, 0xc4, 0xcb, 0x2f, 0xc3, 0x73, 0x6a, - 0x89, 0x10, 0xc9, 0x5f, 0x8a, 0x49, 0xca, 0x30, 0xe1, 0x5c, 0x28, 0xa2, 0x98, 0xe0, 0xb2, 0x40, - 0x5b, 0xb1, 0x90, 0x43, 0x21, 0x71, 0x44, 0x24, 0x35, 0xf6, 0x78, 0x1c, 0x44, 0x54, 0x91, 0x00, - 0xa7, 0x24, 0x61, 0x5c, 0x93, 0x57, 0x4e, 0x5b, 0x79, 0xa4, 0x22, 0x8a, 0x1a, 0xd4, 0xb3, 0xe1, - 0xd3, 0x1f, 0x4b, 0xfd, 0x17, 0x8d, 0x7e, 0xe3, 0x7d, 0x11, 0xd2, 0x51, 0x4e, 0xa5, 0xf2, 0x7e, - 0xc2, 0x67, 0x5b, 0x88, 0x4c, 0x05, 0x97, 0x14, 0x7d, 0x84, 0x15, 0xe3, 0x66, 0x83, 0xc6, 0xbd, - 0xe6, 0xc3, 0xce, 0x0b, 0x7f, 0x73, 0x2a, 0x5f, 0xab, 0x96, 0xa2, 0x6e, 0x79, 0x7a, 0x59, 0xb7, - 0xc2, 0x42, 0xe0, 0x7d, 0x82, 0xb6, 0x76, 0xed, 0xe5, 0x59, 0x46, 0xb9, 0xd2, 0xb4, 0xa2, 0x23, - 0x72, 0x21, 0x64, 0x7f, 0x28, 0x57, 0xac, 0xcf, 0x68, 0x66, 0x83, 0x06, 0x68, 0x3e, 0x08, 0xd7, - 0x2a, 0xde, 0x67, 0xf8, 0x7c, 0x87, 0xb6, 0xc8, 0xf4, 0x0a, 0x3e, 0x8a, 0x4d, 0xfd, 0xb7, 0x6e, - 0xa5, 0xf5, 0xe5, 0xb0, 0x1a, 0xaf, 0x91, 0x3b, 0x67, 0x25, 0x78, 0x5f, 0x5b, 0xa0, 0x23, 0x00, - 0xe1, 0x6d, 0x46, 0x89, 0x9a, 0xdb, 0x13, 0xec, 0x5e, 0x8b, 0xf3, 0xee, 0x00, 0xa6, 0x89, 0xe4, - 0xbd, 0xf9, 0x7f, 0x7e, 0x7d, 0x52, 0xaa, 0xa3, 0x97, 0x78, 0xf3, 0x04, 0xe6, 0x54, 0xe6, 0x17, - 0x9d, 0x02, 0x58, 0x5d, 0x1f, 0x09, 0xb5, 0xf6, 0xb4, 0xd8, 0xb1, 0x33, 0xe7, 0xfd, 0x41, 0xdc, - 0x22, 0x50, 0x5b, 0x07, 0x7a, 0x8b, 0x5e, 0xef, 0x09, 0x74, 0x67, 0x81, 0xdd, 0xaf, 0xd3, 0xb9, - 0x0b, 0x66, 0x73, 0x17, 0x5c, 0xcd, 0x5d, 0x70, 0xbc, 0x70, 0xad, 0xd9, 0xc2, 0xb5, 0x2e, 0x16, - 0xae, 0xf5, 0xab, 0x9d, 0x30, 0x35, 0xc8, 0x23, 0x3f, 0x16, 0x43, 0xfc, 0x5d, 0x3b, 0xf5, 0x06, - 0x84, 0xf1, 0x95, 0xeb, 0xbf, 0x95, 0xaf, 0x9a, 0xa4, 0x54, 0x46, 0x15, 0xfd, 0xd2, 0x3e, 0xdc, - 0x04, 0x00, 0x00, 0xff, 0xff, 0x57, 0x11, 0x22, 0x69, 0x19, 0x03, 0x00, 0x00, + // 412 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x4d, 0x8b, 0xd3, 0x40, + 0x18, 0xce, 0xd4, 0x5a, 0x70, 0xac, 0x20, 0x83, 0x68, 0x8c, 0x35, 0x2d, 0xf1, 0x83, 0x5a, 0x4b, + 0x86, 0xd4, 0x93, 0x9e, 0xa4, 0x45, 0xc1, 0x8b, 0x60, 0xf0, 0xe4, 0x45, 0x26, 0x71, 0x9a, 0x0e, + 0xd8, 0x99, 0x34, 0x33, 0x29, 0xf6, 0xea, 0xc9, 0xa3, 0xb0, 0xec, 0x9f, 0xd8, 0x5f, 0xd2, 0x63, + 0x61, 0x2f, 0x7b, 0x5a, 0x96, 0x76, 0x7f, 0xc8, 0xd2, 0x99, 0x74, 0xb7, 0xdb, 0x0f, 0xe8, 0x2d, + 0x99, 0xe7, 0xe3, 0x7d, 0x9e, 0x77, 0x06, 0xd6, 0x38, 0x8b, 0x58, 0x96, 0x63, 0x9a, 0x8a, 0x78, + 0x20, 0xf1, 0x38, 0xc0, 0xa3, 0x9c, 0x66, 0x13, 0x3f, 0xcd, 0x84, 0x12, 0xe8, 0xa1, 0x41, 0x7d, + 0x83, 0xfa, 0xe3, 0xc0, 0x79, 0x94, 0x88, 0x44, 0x68, 0x10, 0x2f, 0xbf, 0x0c, 0xcf, 0xa9, 0x25, + 0x42, 0x24, 0xbf, 0x29, 0x26, 0x29, 0xc3, 0x84, 0x73, 0xa1, 0x88, 0x62, 0x82, 0xcb, 0x02, 0x6d, + 0xc5, 0x42, 0x0e, 0x85, 0xc4, 0x11, 0x91, 0xd4, 0xd8, 0xe3, 0x71, 0x10, 0x51, 0x45, 0x02, 0x9c, + 0x92, 0x84, 0x71, 0x4d, 0x5e, 0x39, 0x6d, 0xe5, 0x91, 0x8a, 0x28, 0x6a, 0x50, 0xcf, 0x86, 0x8f, + 0xbf, 0x2d, 0xf5, 0x9f, 0x96, 0xe8, 0x17, 0xde, 0x17, 0x32, 0xa4, 0xa3, 0x9c, 0x4a, 0xe5, 0x7d, + 0x87, 0x4f, 0xb6, 0x10, 0x99, 0x0a, 0x2e, 0x29, 0x7a, 0x0f, 0x2b, 0xc6, 0xcd, 0x06, 0x8d, 0x3b, + 0xcd, 0xfb, 0x9d, 0x67, 0xfe, 0x66, 0x2b, 0xff, 0x5a, 0xd5, 0x2d, 0x4f, 0xcf, 0xeb, 0x56, 0x58, + 0x08, 0xbc, 0x0f, 0xd0, 0xd6, 0xae, 0xbd, 0x3c, 0xcb, 0x28, 0x57, 0x9a, 0x56, 0x4c, 0x44, 0x2e, + 0x84, 0xec, 0x17, 0xe5, 0x8a, 0xf5, 0x19, 0xcd, 0x6c, 0xd0, 0x00, 0xcd, 0x7b, 0xe1, 0xda, 0x89, + 0xf7, 0x11, 0x3e, 0xdd, 0xa1, 0x2d, 0x32, 0xbd, 0x80, 0x0f, 0x62, 0x73, 0xfe, 0x53, 0x8f, 0xd2, + 0xfa, 0x72, 0x58, 0x8d, 0xd7, 0xc8, 0x9d, 0x93, 0x12, 0xbc, 0xab, 0x2d, 0xd0, 0x3f, 0x00, 0xe1, + 0x4d, 0x33, 0xd4, 0xdc, 0x6e, 0xb0, 0x7b, 0x2d, 0xce, 0x9b, 0x03, 0x98, 0x26, 0x92, 0xf7, 0xea, + 0xef, 0xe9, 0xe5, 0x51, 0xa9, 0x8e, 0x9e, 0xe3, 0xcd, 0x2b, 0x30, 0x57, 0x65, 0x7e, 0xd1, 0x31, + 0x80, 0xd5, 0xf5, 0x4a, 0xa8, 0xb5, 0x67, 0xc4, 0x8e, 0x9d, 0x39, 0x6f, 0x0f, 0xe2, 0x16, 0x81, + 0xda, 0x3a, 0xd0, 0x6b, 0xf4, 0x72, 0x4f, 0xa0, 0x5b, 0x0b, 0xec, 0x7e, 0x9e, 0xce, 0x5d, 0x30, + 0x9b, 0xbb, 0xe0, 0x62, 0xee, 0x82, 0xff, 0x0b, 0xd7, 0x9a, 0x2d, 0x5c, 0xeb, 0x6c, 0xe1, 0x5a, + 0x3f, 0xda, 0x09, 0x53, 0x83, 0x3c, 0xf2, 0x63, 0x31, 0xc4, 0x5f, 0xb5, 0x53, 0x6f, 0x40, 0x18, + 0x5f, 0xb9, 0xfe, 0x59, 0xf9, 0xaa, 0x49, 0x4a, 0x65, 0x54, 0xd1, 0x2f, 0xed, 0xdd, 0x55, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xe7, 0x96, 0x70, 0xa3, 0x19, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/inflation/keeper/hooks_test.go b/x/inflation/keeper/hooks_test.go index 97ccd310fc..0db86f9bcc 100644 --- a/x/inflation/keeper/hooks_test.go +++ b/x/inflation/keeper/hooks_test.go @@ -74,13 +74,13 @@ func TestPeriodChangesSkippedEpochsAfterEpochEnd(t *testing.T) { false, }, { - "[Period 0] period changes once enough epochs have passed", - 0, - currentEpochPeriod + 1, - epochstypes.DayEpochID, - 0, - true, - true, + name: "[Period 0] period changes once enough epochs have passed", + currentPeriod: 0, + height: currentEpochPeriod + 1, + epochIdentifier: epochstypes.DayEpochID, + skippedEpochs: 0, + InflationEnabled: true, + periodChanges: true, }, { "[Period 1] period stays the same under the epoch per period", @@ -161,6 +161,7 @@ func TestPeriodChangesSkippedEpochsAfterEpochEnd(t *testing.T) { // Perform Epoch Hooks futureCtx := ctx.WithBlockTime(time.Now().Add(time.Minute)) + fmt.Println("tc.height", tc.height) nibiruApp.EpochsKeeper.BeforeEpochStart(futureCtx, tc.epochIdentifier, tc.height) nibiruApp.EpochsKeeper.AfterEpochEnd(futureCtx, tc.epochIdentifier, tc.height) @@ -168,14 +169,22 @@ func TestPeriodChangesSkippedEpochsAfterEpochEnd(t *testing.T) { period := nibiruApp.InflationKeeper.CurrentPeriod.Peek(ctx) if tc.periodChanges { + fmt.Println("periodChanges", tc.periodChanges) newProvision := nibiruApp.InflationKeeper.GetEpochMintProvision(ctx) + expectedProvision := types.CalculateEpochMintProvision( nibiruApp.InflationKeeper.GetParams(ctx), period, ) + + fmt.Println("periodChanges", tc.periodChanges) + fmt.Println("newProvision", newProvision) + fmt.Println("expectedProvision", expectedProvision) + fmt.Println("originalProvision", originalProvision) + require.Equal(t, expectedProvision, newProvision) // mint provisions will change - require.NotEqual(t, newProvision.BigInt().Uint64(), originalProvision.BigInt().Uint64()) + require.NotEqual(t, newProvision, originalProvision) require.Equal(t, currentSkippedEpochs, skippedEpochs) require.Equal(t, currentPeriod+1, period) } else { diff --git a/x/inflation/keeper/inflation.go b/x/inflation/keeper/inflation.go index ab9355b673..a039874271 100644 --- a/x/inflation/keeper/inflation.go +++ b/x/inflation/keeper/inflation.go @@ -28,7 +28,7 @@ func (k Keeper) MintAndAllocateInflation( } // Allocate minted coins according to allocation proportions (staking, strategic, community pool) - return k.AllocateExponentialInflation(ctx, coins, params) + return k.AllocatePolynomialInflation(ctx, coins, params) } // MintCoins implements an alias call to the underlying supply keeper's @@ -38,12 +38,12 @@ func (k Keeper) MintCoins(ctx sdk.Context, coin sdk.Coin) error { return k.bankKeeper.MintCoins(ctx, types.ModuleName, coins) } -// AllocateExponentialInflation allocates coins from the inflation to external +// AllocatePolynomialInflation allocates coins from the inflation to external // modules according to allocation proportions: // - staking rewards -> sdk `auth` module fee collector // - strategic reserves -> root account of x/sudo module // - community pool -> `sdk `distr` module community pool -func (k Keeper) AllocateExponentialInflation( +func (k Keeper) AllocatePolynomialInflation( ctx sdk.Context, mintedCoin sdk.Coin, params types.Params, @@ -125,7 +125,11 @@ func (k Keeper) GetInflationRate(ctx sdk.Context, mintDenom string) sdk.Dec { // EpochMintProvision * 365 / circulatingSupply * 100 circulatingSupplyToDec := sdk.NewDecFromInt(circulatingSupply) - return epochMintProvision.MulInt64(int64(k.EpochsPerPeriod(ctx))).Quo(circulatingSupplyToDec).Mul(sdk.NewDec(100)) + return epochMintProvision. + MulInt64(int64(k.EpochsPerPeriod(ctx))). + MulInt64(int64(k.PeriodsPerYear(ctx))). + Quo(circulatingSupplyToDec). + Mul(sdk.NewDec(100)) } // GetEpochMintProvision retrieves necessary params KV storage diff --git a/x/inflation/keeper/inflation_test.go b/x/inflation/keeper/inflation_test.go index 103e6d721f..0394dfc5e1 100644 --- a/x/inflation/keeper/inflation_test.go +++ b/x/inflation/keeper/inflation_test.go @@ -129,10 +129,10 @@ func TestGetCirculatingSupplyAndInflationRate(t *testing.T) { sdk.TokensFromConsensusPower(400_000_000, sdk.DefaultPowerReduction), func(nibiruApp *app.NibiruApp, ctx sdk.Context) { nibiruApp.InflationKeeper.SetParams(ctx, types.Params{ - EpochsPerPeriod: 0, - InflationEnabled: true, - ExponentialCalculation: types.DefaultExponentialCalculation, - InflationDistribution: types.DefaultInflationDistribution, + EpochsPerPeriod: 0, + InflationEnabled: true, + PolynomialFactors: types.DefaultPolynomialFactors, + InflationDistribution: types.DefaultInflationDistribution, }) }, sdk.ZeroDec(), @@ -141,13 +141,13 @@ func TestGetCirculatingSupplyAndInflationRate(t *testing.T) { "high supply", sdk.TokensFromConsensusPower(800_000_000, sdk.DefaultPowerReduction), func(nibiruApp *app.NibiruApp, ctx sdk.Context) {}, - sdk.MustNewDecFromStr("50.674438476562500000"), + sdk.MustNewDecFromStr("27.095518287362700000"), }, { "low supply", sdk.TokensFromConsensusPower(400_000_000, sdk.DefaultPowerReduction), func(nibiruApp *app.NibiruApp, ctx sdk.Context) {}, - sdk.MustNewDecFromStr("101.348876953125000000"), + sdk.MustNewDecFromStr("54.191036574725400000"), }, } for _, tc := range testCases { @@ -177,7 +177,8 @@ func TestGetters(t *testing.T) { nibiruApp, ctx := testapp.NewNibiruTestAppAndContext() k := nibiruApp.InflationKeeper require.NotPanics(t, func() { - _ = k.ExponentialCalculation(ctx) + _ = k.PolynomialFactors(ctx) + _ = k.PeriodsPerYear(ctx) _ = k.InflationDistribution(ctx) _ = k.InflationEnabled(ctx) _ = k.EpochsPerPeriod(ctx) diff --git a/x/inflation/keeper/params.go b/x/inflation/keeper/params.go index 7b8b2ce0bc..c741ff3049 100644 --- a/x/inflation/keeper/params.go +++ b/x/inflation/keeper/params.go @@ -18,8 +18,8 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { } // VotePeriod returns the number of blocks during which voting takes place. -func (k Keeper) ExponentialCalculation(ctx sdk.Context) (res types.ExponentialCalculation) { - k.paramSpace.Get(ctx, types.KeyExponentialCalculation, &res) +func (k Keeper) PolynomialFactors(ctx sdk.Context) (res []sdk.Dec) { + k.paramSpace.Get(ctx, types.KeyPolynomialFactors, &res) return } @@ -39,3 +39,8 @@ func (k Keeper) EpochsPerPeriod(ctx sdk.Context) (res uint64) { k.paramSpace.Get(ctx, types.KeyEpochsPerPeriod, &res) return } + +func (k Keeper) PeriodsPerYear(ctx sdk.Context) (res uint64) { + k.paramSpace.Get(ctx, types.KeyPeriodsPerYear, &res) + return +} diff --git a/x/inflation/types/genesis.pb.go b/x/inflation/types/genesis.pb.go index c008f58899..61e7d72ce7 100644 --- a/x/inflation/types/genesis.pb.go +++ b/x/inflation/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -93,14 +94,19 @@ type Params struct { // inflation_enabled is the parameter that enables inflation and halts // increasing the skipped_epochs InflationEnabled bool `protobuf:"varint,1,opt,name=inflation_enabled,json=inflationEnabled,proto3" json:"inflation_enabled,omitempty"` - // exponential_calculation takes in the variables to calculate exponential + // polynomial_factors takes in the variables to calculate polynomial // inflation - ExponentialCalculation ExponentialCalculation `protobuf:"bytes,2,opt,name=exponential_calculation,json=exponentialCalculation,proto3" json:"exponential_calculation"` + PolynomialFactors []github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,rep,name=polynomial_factors,json=polynomialFactors,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"polynomial_factors"` // inflation_distribution of the minted denom InflationDistribution InflationDistribution `protobuf:"bytes,3,opt,name=inflation_distribution,json=inflationDistribution,proto3" json:"inflation_distribution"` // epochs_per_period is the number of epochs that must pass before a new // period is created EpochsPerPeriod uint64 `protobuf:"varint,4,opt,name=epochs_per_period,json=epochsPerPeriod,proto3" json:"epochs_per_period,omitempty"` + // periods_per_year is the number of periods that occur in a year + PeriodsPerYear uint64 `protobuf:"varint,5,opt,name=periods_per_year,json=periodsPerYear,proto3" json:"periods_per_year,omitempty"` + // max_period is the maximum number of periods that have inflation being + // paid off. After this period, inflation will be disabled. + MaxPeriod uint64 `protobuf:"varint,6,opt,name=max_period,json=maxPeriod,proto3" json:"max_period,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -143,13 +149,6 @@ func (m *Params) GetInflationEnabled() bool { return false } -func (m *Params) GetExponentialCalculation() ExponentialCalculation { - if m != nil { - return m.ExponentialCalculation - } - return ExponentialCalculation{} -} - func (m *Params) GetInflationDistribution() InflationDistribution { if m != nil { return m.InflationDistribution @@ -164,6 +163,20 @@ func (m *Params) GetEpochsPerPeriod() uint64 { return 0 } +func (m *Params) GetPeriodsPerYear() uint64 { + if m != nil { + return m.PeriodsPerYear + } + return 0 +} + +func (m *Params) GetMaxPeriod() uint64 { + if m != nil { + return m.MaxPeriod + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "nibiru.inflation.v1.GenesisState") proto.RegisterType((*Params)(nil), "nibiru.inflation.v1.Params") @@ -172,31 +185,35 @@ func init() { func init() { proto.RegisterFile("nibiru/inflation/v1/genesis.proto", fileDescriptor_2d00e2bb98c08f74) } var fileDescriptor_2d00e2bb98c08f74 = []byte{ - // 375 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0x4d, 0x4f, 0xfa, 0x30, - 0x1c, 0xde, 0x80, 0x2c, 0xff, 0x94, 0xbf, 0x2f, 0x54, 0x45, 0x82, 0xc9, 0x44, 0x8c, 0x09, 0x81, - 0x64, 0x0b, 0x78, 0xf2, 0x0a, 0x12, 0xc3, 0xc5, 0x10, 0xbc, 0x79, 0x59, 0xba, 0xad, 0x8e, 0xea, - 0x68, 0x9b, 0xad, 0x23, 0xf8, 0x0d, 0x3c, 0xfa, 0x69, 0xfc, 0x0c, 0x1c, 0x39, 0x7a, 0x32, 0x06, - 0xbe, 0x88, 0xb1, 0x9d, 0x8c, 0xc3, 0x6e, 0xed, 0xf3, 0xd2, 0xe7, 0xe9, 0x2f, 0x3f, 0x70, 0x41, - 0x89, 0x4b, 0xa2, 0xc4, 0x26, 0xf4, 0x29, 0x44, 0x82, 0x30, 0x6a, 0xcf, 0xbb, 0x76, 0x80, 0x29, - 0x8e, 0x49, 0x6c, 0xf1, 0x88, 0x09, 0x06, 0x8f, 0x94, 0xc4, 0xda, 0x4a, 0xac, 0x79, 0xb7, 0x7e, - 0x1c, 0xb0, 0x80, 0x49, 0xde, 0xfe, 0x3d, 0x29, 0x69, 0xfd, 0x32, 0xef, 0xb5, 0xcc, 0x27, 0x45, - 0xcd, 0x37, 0x1d, 0xfc, 0xbf, 0x53, 0x09, 0x0f, 0x02, 0x09, 0x0c, 0x6f, 0x80, 0xc1, 0x51, 0x84, - 0x66, 0x71, 0x4d, 0x6f, 0xe8, 0xad, 0x72, 0xef, 0xcc, 0xca, 0x49, 0xb4, 0xc6, 0x52, 0xd2, 0x2f, - 0x2d, 0xbf, 0xce, 0xb5, 0x49, 0x6a, 0x80, 0x55, 0x60, 0x70, 0x1c, 0x11, 0xe6, 0xd7, 0x0a, 0x0d, - 0xbd, 0x55, 0x9a, 0xa4, 0x37, 0x78, 0x05, 0xf6, 0xe3, 0x17, 0xc2, 0x39, 0xf6, 0x1d, 0xcc, 0x99, - 0x37, 0x8d, 0x6b, 0x45, 0xc9, 0xef, 0xa5, 0xe8, 0x50, 0x82, 0xcd, 0x8f, 0x02, 0x30, 0xd4, 0xbb, - 0xb0, 0x03, 0x2a, 0xdb, 0x38, 0x07, 0x53, 0xe4, 0x86, 0xd8, 0x97, 0x7d, 0xfe, 0x4d, 0x0e, 0xb7, - 0xc4, 0x50, 0xe1, 0xf0, 0x19, 0x9c, 0xe2, 0x05, 0x67, 0x14, 0x53, 0x41, 0x50, 0xe8, 0x78, 0x28, - 0xf4, 0x12, 0xa5, 0x90, 0x3d, 0xca, 0xbd, 0x4e, 0xee, 0x17, 0x86, 0x99, 0x67, 0x90, 0x59, 0xd2, - 0x2f, 0x55, 0x71, 0x2e, 0x0b, 0x03, 0x50, 0xcd, 0x8a, 0xf9, 0x24, 0x16, 0x11, 0x71, 0x13, 0x19, - 0x55, 0x94, 0x51, 0xed, 0xdc, 0xa8, 0xd1, 0xdf, 0xe5, 0x76, 0xc7, 0x91, 0x26, 0x9d, 0x90, 0x3c, - 0x12, 0xb6, 0x41, 0x45, 0xcd, 0xca, 0xe1, 0x38, 0x72, 0xd2, 0xb1, 0x96, 0xe4, 0xd8, 0x0e, 0x14, - 0x31, 0xc6, 0xd1, 0x58, 0xc2, 0xfd, 0xd1, 0x72, 0x6d, 0xea, 0xab, 0xb5, 0xa9, 0x7f, 0xaf, 0x4d, - 0xfd, 0x7d, 0x63, 0x6a, 0xab, 0x8d, 0xa9, 0x7d, 0x6e, 0x4c, 0xed, 0xd1, 0x0e, 0x88, 0x98, 0x26, - 0xae, 0xe5, 0xb1, 0x99, 0x7d, 0x2f, 0x8b, 0x0d, 0xa6, 0x88, 0x50, 0x3b, 0xdd, 0x8c, 0xc5, 0xce, - 0x6e, 0x88, 0x57, 0x8e, 0x63, 0xd7, 0x90, 0x5b, 0x71, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb4, - 0xdb, 0xd9, 0x20, 0x8a, 0x02, 0x00, 0x00, + // 438 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xcf, 0x6e, 0xd4, 0x30, + 0x10, 0xc6, 0x37, 0xdb, 0x25, 0xa2, 0x2e, 0x94, 0xae, 0x81, 0x2a, 0x2a, 0x22, 0x5d, 0x8a, 0x40, + 0x51, 0x11, 0xb6, 0x5a, 0x4e, 0x5c, 0x97, 0x16, 0xd4, 0x0b, 0x8a, 0xc2, 0x09, 0x24, 0x14, 0x39, + 0x89, 0x9b, 0xb5, 0x9a, 0xc4, 0x96, 0xed, 0xad, 0x76, 0xdf, 0x80, 0x23, 0x8f, 0xd5, 0x63, 0x8f, + 0x88, 0x43, 0x85, 0x76, 0xdf, 0x80, 0x27, 0xa8, 0xd6, 0xf6, 0xfe, 0x39, 0xe4, 0x94, 0xcc, 0xcc, + 0x6f, 0xbe, 0x19, 0x7f, 0x1a, 0xf0, 0xaa, 0x61, 0x19, 0x93, 0x63, 0xcc, 0x9a, 0xcb, 0x8a, 0x68, + 0xc6, 0x1b, 0x7c, 0x7d, 0x82, 0x4b, 0xda, 0x50, 0xc5, 0x14, 0x12, 0x92, 0x6b, 0x0e, 0x9f, 0x5a, + 0x04, 0xad, 0x10, 0x74, 0x7d, 0x72, 0xf0, 0xac, 0xe4, 0x25, 0x37, 0x75, 0xbc, 0xf8, 0xb3, 0xe8, + 0xc1, 0xeb, 0x36, 0xb5, 0x75, 0x9f, 0x81, 0x8e, 0x7e, 0x79, 0xe0, 0xd1, 0x17, 0x3b, 0xe1, 0x9b, + 0x26, 0x9a, 0xc2, 0x8f, 0xc0, 0x17, 0x44, 0x92, 0x5a, 0x05, 0xde, 0xc0, 0x8b, 0x76, 0x4e, 0x5f, + 0xa0, 0x96, 0x89, 0x28, 0x36, 0xc8, 0xb0, 0x77, 0x73, 0x77, 0xd8, 0x49, 0x5c, 0x03, 0xdc, 0x07, + 0xbe, 0xa0, 0x92, 0xf1, 0x22, 0xe8, 0x0e, 0xbc, 0xa8, 0x97, 0xb8, 0x08, 0xbe, 0x01, 0xbb, 0xea, + 0x8a, 0x09, 0x41, 0x8b, 0x94, 0x0a, 0x9e, 0x8f, 0x54, 0xb0, 0x65, 0xea, 0x8f, 0x5d, 0xf6, 0xdc, + 0x24, 0x8f, 0xfe, 0x77, 0x81, 0x6f, 0x75, 0xe1, 0x3b, 0xd0, 0x5f, 0x8d, 0x4b, 0x69, 0x43, 0xb2, + 0x8a, 0x16, 0x66, 0x9f, 0x87, 0xc9, 0xde, 0xaa, 0x70, 0x6e, 0xf3, 0xf0, 0x27, 0x80, 0x82, 0x57, + 0xd3, 0x86, 0xd7, 0x8c, 0x54, 0xe9, 0x25, 0xc9, 0x35, 0x97, 0x2a, 0xe8, 0x0e, 0xb6, 0xa2, 0xed, + 0x21, 0x5a, 0x2c, 0xf8, 0xf7, 0xee, 0xf0, 0x6d, 0xc9, 0xf4, 0x68, 0x9c, 0xa1, 0x9c, 0xd7, 0x38, + 0xe7, 0xaa, 0xe6, 0xca, 0x7d, 0xde, 0xab, 0xe2, 0x0a, 0xeb, 0xa9, 0xa0, 0x0a, 0x9d, 0xd1, 0x3c, + 0xe9, 0xaf, 0x95, 0x3e, 0x5b, 0x21, 0x58, 0x82, 0xfd, 0xf5, 0x2e, 0x05, 0x53, 0x5a, 0xb2, 0x6c, + 0xbc, 0x08, 0xcc, 0x2b, 0x76, 0x4e, 0x8f, 0x5b, 0x0d, 0xba, 0x58, 0x06, 0x67, 0x1b, 0x1d, 0xce, + 0xaf, 0xe7, 0xac, 0xad, 0x08, 0x8f, 0x41, 0xdf, 0xda, 0x93, 0x0a, 0x2a, 0x53, 0xe7, 0x64, 0xcf, + 0x38, 0xf5, 0xc4, 0x16, 0x62, 0x2a, 0x63, 0x6b, 0x69, 0x04, 0xf6, 0x2c, 0x60, 0xe1, 0x29, 0x25, + 0x32, 0x78, 0x60, 0xd0, 0x5d, 0x97, 0x8f, 0xa9, 0xfc, 0x4e, 0x89, 0x84, 0x2f, 0x01, 0xa8, 0xc9, + 0x64, 0x29, 0xe7, 0x1b, 0x66, 0xbb, 0x26, 0x13, 0x2b, 0x34, 0xbc, 0xb8, 0x99, 0x85, 0xde, 0xed, + 0x2c, 0xf4, 0xfe, 0xcd, 0x42, 0xef, 0xf7, 0x3c, 0xec, 0xdc, 0xce, 0xc3, 0xce, 0x9f, 0x79, 0xd8, + 0xf9, 0x81, 0x37, 0x2c, 0xfb, 0x6a, 0x5e, 0xf8, 0x69, 0x44, 0x58, 0x83, 0xdd, 0x55, 0x4d, 0x36, + 0xee, 0xca, 0xf8, 0x97, 0xf9, 0xe6, 0xa2, 0x3e, 0xdc, 0x07, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x56, + 0x6e, 0x63, 0xc6, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -262,6 +279,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MaxPeriod != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.MaxPeriod)) + i-- + dAtA[i] = 0x30 + } + if m.PeriodsPerYear != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.PeriodsPerYear)) + i-- + dAtA[i] = 0x28 + } if m.EpochsPerPeriod != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.EpochsPerPeriod)) i-- @@ -277,16 +304,20 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - { - size, err := m.ExponentialCalculation.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.PolynomialFactors) > 0 { + for iNdEx := len(m.PolynomialFactors) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.PolynomialFactors[iNdEx].Size() + i -= size + if _, err := m.PolynomialFactors[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 if m.InflationEnabled { i-- if m.InflationEnabled { @@ -337,13 +368,23 @@ func (m *Params) Size() (n int) { if m.InflationEnabled { n += 2 } - l = m.ExponentialCalculation.Size() - n += 1 + l + sovGenesis(uint64(l)) + if len(m.PolynomialFactors) > 0 { + for _, e := range m.PolynomialFactors { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } l = m.InflationDistribution.Size() n += 1 + l + sovGenesis(uint64(l)) if m.EpochsPerPeriod != 0 { n += 1 + sovGenesis(uint64(m.EpochsPerPeriod)) } + if m.PeriodsPerYear != 0 { + n += 1 + sovGenesis(uint64(m.PeriodsPerYear)) + } + if m.MaxPeriod != 0 { + n += 1 + sovGenesis(uint64(m.MaxPeriod)) + } return n } @@ -525,9 +566,9 @@ func (m *Params) Unmarshal(dAtA []byte) error { m.InflationEnabled = bool(v != 0) case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ExponentialCalculation", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PolynomialFactors", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -537,22 +578,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenesis } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenesis } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ExponentialCalculation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + var v github_com_cosmos_cosmos_sdk_types.Dec + m.PolynomialFactors = append(m.PolynomialFactors, v) + if err := m.PolynomialFactors[len(m.PolynomialFactors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -608,6 +652,44 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PeriodsPerYear", wireType) + } + m.PeriodsPerYear = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PeriodsPerYear |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxPeriod", wireType) + } + m.MaxPeriod = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxPeriod |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/inflation/types/inflation.pb.go b/x/inflation/types/inflation.pb.go index ecc0666b39..632c86ebf5 100644 --- a/x/inflation/types/inflation.pb.go +++ b/x/inflation/types/inflation.pb.go @@ -72,55 +72,8 @@ func (m *InflationDistribution) XXX_DiscardUnknown() { var xxx_messageInfo_InflationDistribution proto.InternalMessageInfo -// ExponentialCalculation holds factors to calculate exponential inflation on -// each period. Calculation reference: -// periodProvision = exponentialDecay -// f(x) = a * (1 - r) ^ x + c -type ExponentialCalculation struct { - // a defines the initial value - A github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=a,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"a"` - // r defines the reduction factor - R github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=r,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"r"` - // c defines the parameter for long term inflation - C github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=c,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"c"` -} - -func (m *ExponentialCalculation) Reset() { *m = ExponentialCalculation{} } -func (m *ExponentialCalculation) String() string { return proto.CompactTextString(m) } -func (*ExponentialCalculation) ProtoMessage() {} -func (*ExponentialCalculation) Descriptor() ([]byte, []int) { - return fileDescriptor_37da805e9a324a97, []int{1} -} -func (m *ExponentialCalculation) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ExponentialCalculation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ExponentialCalculation.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ExponentialCalculation) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExponentialCalculation.Merge(m, src) -} -func (m *ExponentialCalculation) XXX_Size() int { - return m.Size() -} -func (m *ExponentialCalculation) XXX_DiscardUnknown() { - xxx_messageInfo_ExponentialCalculation.DiscardUnknown(m) -} - -var xxx_messageInfo_ExponentialCalculation proto.InternalMessageInfo - func init() { proto.RegisterType((*InflationDistribution)(nil), "nibiru.inflation.v1.InflationDistribution") - proto.RegisterType((*ExponentialCalculation)(nil), "nibiru.inflation.v1.ExponentialCalculation") } func init() { @@ -128,28 +81,25 @@ func init() { } var fileDescriptor_37da805e9a324a97 = []byte{ - // 329 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xcd, 0x4a, 0x3b, 0x31, - 0x14, 0xc5, 0x27, 0xfd, 0xc3, 0x1f, 0x0c, 0x58, 0x71, 0xfc, 0xa0, 0xb8, 0x48, 0xa5, 0x82, 0xb8, - 0x71, 0x42, 0x71, 0xeb, 0xaa, 0xad, 0x8b, 0x6e, 0x44, 0x0a, 0x22, 0x08, 0x52, 0x32, 0x69, 0x9c, - 0x86, 0xce, 0xe4, 0x0e, 0x49, 0xa6, 0xb6, 0x6f, 0xe1, 0x53, 0xf8, 0x2c, 0x5d, 0x16, 0x57, 0xe2, - 0xa2, 0x48, 0xe7, 0x45, 0x64, 0x3e, 0x6c, 0xbb, 0x9e, 0x55, 0x6e, 0x92, 0x73, 0x7e, 0x70, 0x0f, - 0x07, 0x5f, 0x28, 0xe9, 0x4b, 0x9d, 0x50, 0xa9, 0x5e, 0x43, 0x66, 0x25, 0x28, 0x3a, 0x6d, 0x6f, - 0x2f, 0x5e, 0xac, 0xc1, 0x82, 0x7b, 0x54, 0x88, 0xbc, 0xed, 0xfb, 0xb4, 0x7d, 0x76, 0x1c, 0x40, - 0x00, 0xf9, 0x3f, 0xcd, 0xa6, 0x42, 0xda, 0xfa, 0xa8, 0xe1, 0x93, 0xfe, 0x9f, 0xac, 0x27, 0x8d, - 0xd5, 0xd2, 0x4f, 0xb2, 0xd9, 0x7d, 0xc2, 0x07, 0xc6, 0xb2, 0x89, 0x54, 0xc1, 0x50, 0x8b, 0x37, - 0xa6, 0x47, 0xa6, 0x81, 0xce, 0xd1, 0xd5, 0x5e, 0xc7, 0x5b, 0xac, 0x9a, 0xce, 0xf7, 0xaa, 0x79, - 0x19, 0x48, 0x3b, 0x4e, 0x7c, 0x8f, 0x43, 0x44, 0x39, 0x98, 0x08, 0x4c, 0x79, 0x5c, 0x9b, 0xd1, - 0x84, 0xda, 0x79, 0x2c, 0x8c, 0xd7, 0x13, 0x7c, 0x50, 0x2f, 0x31, 0x83, 0x82, 0xe2, 0x3e, 0xe2, - 0x3a, 0x87, 0x28, 0x4a, 0x94, 0xb4, 0xf3, 0x61, 0x0c, 0x10, 0x36, 0x6a, 0x95, 0xb8, 0xfb, 0x1b, - 0xca, 0x03, 0x40, 0xe8, 0xbe, 0x60, 0xd7, 0x58, 0xcd, 0xac, 0x08, 0x24, 0x1f, 0x6a, 0x61, 0x84, - 0x9e, 0x0a, 0xd3, 0xf8, 0x57, 0x09, 0x7d, 0xb8, 0x21, 0x0d, 0x4a, 0x50, 0xeb, 0x13, 0xe1, 0xd3, - 0xbb, 0x59, 0x0c, 0x4a, 0x28, 0x2b, 0x59, 0xd8, 0x65, 0x21, 0x4f, 0x8a, 0xd4, 0xdc, 0x5b, 0x8c, - 0x58, 0xc5, 0x6c, 0x10, 0xcb, 0xdc, 0xba, 0x62, 0x02, 0x48, 0x67, 0x6e, 0x5e, 0x71, 0x49, 0xc4, - 0x3b, 0xfd, 0xc5, 0x9a, 0xa0, 0xe5, 0x9a, 0xa0, 0x9f, 0x35, 0x41, 0xef, 0x29, 0x71, 0x96, 0x29, - 0x71, 0xbe, 0x52, 0xe2, 0x3c, 0xd3, 0x1d, 0xc8, 0x7d, 0xde, 0xa6, 0xee, 0x98, 0x49, 0x45, 0xcb, - 0xfa, 0xcd, 0x76, 0x0a, 0x98, 0x13, 0xfd, 0xff, 0x79, 0x9f, 0x6e, 0x7e, 0x03, 0x00, 0x00, 0xff, - 0xff, 0xe0, 0x01, 0x1c, 0xb7, 0xa1, 0x02, 0x00, 0x00, + // 284 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xce, 0xcb, 0x4c, 0xca, + 0x2c, 0x2a, 0xd5, 0xcf, 0xcc, 0x4b, 0xcb, 0x49, 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x2f, 0x33, 0x44, + 0x70, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x84, 0x21, 0x8a, 0xf4, 0x10, 0xe2, 0x65, 0x86, + 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0x79, 0x7d, 0x10, 0x0b, 0xa2, 0x54, 0x69, 0x19, 0x13, + 0x97, 0xa8, 0x27, 0x4c, 0x99, 0x4b, 0x66, 0x71, 0x49, 0x51, 0x66, 0x52, 0x29, 0x88, 0x2d, 0x14, + 0xce, 0xc5, 0x5f, 0x5c, 0x92, 0x98, 0x9d, 0x99, 0x97, 0x1e, 0x5f, 0x94, 0x5a, 0x9e, 0x58, 0x94, + 0x52, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe9, 0xa4, 0x77, 0xe2, 0x9e, 0x3c, 0xc3, 0xad, 0x7b, + 0xf2, 0x6a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, 0xc5, + 0xb9, 0xf9, 0xc5, 0x50, 0x4a, 0xb7, 0x38, 0x25, 0x5b, 0xbf, 0xa4, 0xb2, 0x20, 0xb5, 0x58, 0xcf, + 0x25, 0x35, 0x39, 0x88, 0x0f, 0x6a, 0x4c, 0x10, 0xc4, 0x14, 0xa1, 0x50, 0x2e, 0xbe, 0xe4, 0xfc, + 0xdc, 0xdc, 0xd2, 0xbc, 0xcc, 0x92, 0xca, 0xf8, 0x82, 0xfc, 0xfc, 0x1c, 0x09, 0x26, 0xb2, 0xcc, + 0xe5, 0x85, 0x9b, 0x12, 0x90, 0x9f, 0x9f, 0x23, 0x14, 0xcb, 0x25, 0x54, 0x5c, 0x52, 0x94, 0x58, + 0x92, 0x9a, 0x9e, 0x99, 0x1c, 0x5f, 0x94, 0x5a, 0x9c, 0x5a, 0x54, 0x96, 0x5a, 0x2c, 0xc1, 0x4c, + 0x96, 0xd1, 0x82, 0x70, 0x93, 0x82, 0xa0, 0x06, 0x39, 0x79, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, + 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, + 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x3e, 0x92, 0xa1, 0x7e, 0xe0, 0x80, 0x77, 0xce, 0x48, 0xcc, 0xcc, + 0xd3, 0x87, 0xc6, 0x54, 0x05, 0x52, 0x5c, 0x81, 0x6d, 0x48, 0x62, 0x03, 0x07, 0xbd, 0x31, 0x20, + 0x00, 0x00, 0xff, 0xff, 0x75, 0xbf, 0x6b, 0xae, 0xcc, 0x01, 0x00, 0x00, } func (m *InflationDistribution) Marshal() (dAtA []byte, err error) { @@ -205,59 +155,6 @@ func (m *InflationDistribution) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ExponentialCalculation) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExponentialCalculation) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExponentialCalculation) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size := m.C.Size() - i -= size - if _, err := m.C.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintInflation(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size := m.R.Size() - i -= size - if _, err := m.R.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintInflation(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size := m.A.Size() - i -= size - if _, err := m.A.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintInflation(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - func encodeVarintInflation(dAtA []byte, offset int, v uint64) int { offset -= sovInflation(v) base := offset @@ -284,21 +181,6 @@ func (m *InflationDistribution) Size() (n int) { return n } -func (m *ExponentialCalculation) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.A.Size() - n += 1 + l + sovInflation(uint64(l)) - l = m.R.Size() - n += 1 + l + sovInflation(uint64(l)) - l = m.C.Size() - n += 1 + l + sovInflation(uint64(l)) - return n -} - func sovInflation(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -457,158 +339,6 @@ func (m *InflationDistribution) Unmarshal(dAtA []byte) error { } return nil } -func (m *ExponentialCalculation) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowInflation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExponentialCalculation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExponentialCalculation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field A", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowInflation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthInflation - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthInflation - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.A.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field R", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowInflation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthInflation - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthInflation - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.R.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field C", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowInflation - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthInflation - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthInflation - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.C.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipInflation(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthInflation - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipInflation(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/inflation/types/inflation_calculation.go b/x/inflation/types/inflation_calculation.go index 9fa5e542ff..e1c6d2c389 100644 --- a/x/inflation/types/inflation_calculation.go +++ b/x/inflation/types/inflation_calculation.go @@ -9,25 +9,31 @@ func CalculateEpochMintProvision( params Params, period uint64, ) sdk.Dec { - if params.EpochsPerPeriod == 0 { + if params.EpochsPerPeriod == 0 || !params.InflationEnabled || period >= params.MaxPeriod { return sdk.ZeroDec() } - x := period // period - a := params.ExponentialCalculation.A // initial value - r := params.ExponentialCalculation.R // reduction factor - c := params.ExponentialCalculation.C // long term inflation + // truncating to the nearest integer + x := period - // exponentialDecay := a * (1 - r) ^ x + c - decay := sdk.OneDec().Sub(r) - periodProvision := a.Mul(decay.Power(x)).Add(c) + // Calculate the value of the polynomial at x + polynomialValue := polynomial(params.PolynomialFactors, sdk.NewDec(int64(x))) - // epochProvision = periodProvision / epochsPerPeriod - epochProvision := periodProvision.QuoInt64(int64(params.EpochsPerPeriod)) + if polynomialValue.IsNegative() { + // Just to make sure nothing weird occur + return sdk.ZeroDec() + } + + return polynomialValue.Quo(sdk.NewDec(int64(params.EpochsPerPeriod))) +} + +// Compute the value of x given the polynomial factors +func polynomial(factors []sdk.Dec, x sdk.Dec) sdk.Dec { + result := sdk.ZeroDec() + for i, factor := range factors { + result = result.Add(factor.Mul(x.Power(uint64(len(factors) - i - 1)))) + } - // Multiply epochMintProvision with power reduction (10^6 for unibi) as the - // calculation is based on `NIBI` and the issued tokens need to be given in - // `uNIBI` - epochProvision = epochProvision.MulInt(sdk.DefaultPowerReduction) - return epochProvision + // Multiply by 1 million to get the value in unibi + return result.Mul(sdk.NewDec(1_000_000)) } diff --git a/x/inflation/types/inflation_calculation_test.go b/x/inflation/types/inflation_calculation_test.go index 1b9b21ba85..a63701e87c 100644 --- a/x/inflation/types/inflation_calculation_test.go +++ b/x/inflation/types/inflation_calculation_test.go @@ -8,63 +8,45 @@ import ( "github.com/stretchr/testify/require" ) +// These numbers are for year n month 1 +var ExpectedYearlyInflation = []sdk.Dec{ + sdk.NewDec(195_895_391_000_000), + sdk.NewDec(156_348_637_000_000), + sdk.NewDec(124_785_459_000_000), + sdk.NewDec(99_594_157_000_000), + sdk.NewDec(79_488_398_000_000), + sdk.NewDec(63_441_527_000_000), + sdk.NewDec(50_634_148_000_000), + sdk.NewDec(40_412_283_000_000), +} + +var ExpectedTotalInflation = sdk.NewDec(810_600_000_000_000) + func TestCalculateEpochMintProvision(t *testing.T) { - testCases := []struct { - name string - period uint64 - expEpochProvision sdk.Dec - }{ - { - "pass - initial period", - 0, - sdk.MustNewDecFromStr("1110672624143.835616438356000000"), - }, - { - "pass - period 1", - 1, - sdk.MustNewDecFromStr("555878103595.890410958904000000"), - }, - { - "pass - period 2", - 2, - sdk.MustNewDecFromStr("278480843321.917808219178000000"), - }, - { - "pass - period 3", - 3, - sdk.MustNewDecFromStr("139782213184.931506849315000000"), - }, - { - "pass - period 4", - 4, - sdk.MustNewDecFromStr("70432898116.438356164383000000"), - }, - { - "pass - period 5", - 5, - sdk.MustNewDecFromStr("35758240582.191780821917000000"), - }, - { - "pass - period 6", - 6, - sdk.MustNewDecFromStr("18420911815.068493150684000000"), - }, - { - "pass - period 7", - 7, - sdk.MustNewDecFromStr("9752247431.506849315068000000"), - }, - } - for _, tc := range testCases { - t.Run(fmt.Sprintf("Case %s", tc.name), func(t *testing.T) { - epochMintProvisions := CalculateEpochMintProvision( - DefaultParams(), - tc.period, - ) + params := DefaultParams() - require.Equal(t, tc.expEpochProvision, epochMintProvisions) - }) + epochId := uint64(0) + totalInflation := sdk.ZeroDec() + + // Only the first 8 years have inflation with default params + for year := uint64(0); year < 10; year++ { + yearlyInflation := sdk.ZeroDec() + for month := uint64(0); month < 12; month++ { + for day := uint64(0); day < 30; day++ { + epochMintProvisions := CalculateEpochMintProvision(params, epochId) + yearlyInflation = yearlyInflation.Add(epochMintProvisions) + } + epochId++ + } + // Should be within 0.0098% + if year < uint64(len(ExpectedYearlyInflation)) { + require.NoError(t, withingRange(yearlyInflation, ExpectedYearlyInflation[year])) + } else { + require.Equal(t, yearlyInflation, sdk.ZeroDec()) + } + totalInflation = totalInflation.Add(yearlyInflation) } + require.NoError(t, withingRange(totalInflation, ExpectedTotalInflation)) } func TestCalculateEpochMintProvision_ZeroEpochs(t *testing.T) { @@ -74,3 +56,15 @@ func TestCalculateEpochMintProvision_ZeroEpochs(t *testing.T) { epochMintProvisions := CalculateEpochMintProvision(params, 1) require.Equal(t, epochMintProvisions, sdk.ZeroDec()) } + +// withingRange returns an error if the actual value is not within the expected value +/- tolerance +// tolerance is a percentage set to 0.01% by default +func withingRange(expected, actual sdk.Dec) error { + tolerance := sdk.NewDecWithPrec(1, 4) + is_within := expected.Sub(actual).Abs().Quo(expected).LTE(tolerance) + if !is_within { + tolerancePercent := tolerance.Mul(sdk.NewDec(100)) + return fmt.Errorf("expected %s to be within %s%% of %s", actual.String(), tolerancePercent.String(), expected.String()) + } + return nil +} diff --git a/x/inflation/types/params.go b/x/inflation/types/params.go index f043f1eb14..9d0be967a2 100644 --- a/x/inflation/types/params.go +++ b/x/inflation/types/params.go @@ -9,48 +9,61 @@ import ( ) var ( - KeyInflationEnabled = []byte("InflationEnabled") - KeyExponentialCalculation = []byte("ExponentialCalculation") - KeyInflationDistribution = []byte("InflationDistribution") - KeyEpochsPerPeriod = []byte("EpochsPerPeriod") + KeyInflationEnabled = []byte("InflationEnabled") + KeyPolynomialFactors = []byte("PolynomialFactors") + KeyInflationDistribution = []byte("InflationDistribution") + KeyEpochsPerPeriod = []byte("EpochsPerPeriod") + KeyPeriodsPerYear = []byte("PeriodsPerYear") + KeyMaxPeriod = []byte("MaxPeriod") ) var ( - DefaultInflation = true - DefaultExponentialCalculation = ExponentialCalculation{ - A: sdk.NewDec(int64(405_000_000)), - R: sdk.NewDecWithPrec(50, 2), // 50% - C: sdk.NewDecWithPrec(395_507_8125, 4), + DefaultInflation = true + DefaultPolynomialFactors = []sdk.Dec{ + sdk.MustNewDecFromStr("-0.00014903"), + sdk.MustNewDecFromStr("0.07527647"), + sdk.MustNewDecFromStr("-19.11742154"), + sdk.MustNewDecFromStr("3170.0969905"), + sdk.MustNewDecFromStr("-339271.31060432"), + sdk.MustNewDecFromStr("18063678.8582418"), } DefaultInflationDistribution = InflationDistribution{ StakingRewards: sdk.NewDecWithPrec(27_8, 3), // 27.8% CommunityPool: sdk.NewDecWithPrec(62_20, 4), // 62.20% StrategicReserves: sdk.NewDecWithPrec(10, 2), // 10% } - DefaultEpochsPerPeriod = uint64(365) + DefaultEpochsPerPeriod = uint64(30) + DefaultPeriodsPerYear = uint64(12) + DefaultMaxPeriod = uint64(8 * 12) // 8 years with 360 days per year ) func NewParams( - exponentialCalculation ExponentialCalculation, + polynomialCalculation []sdk.Dec, inflationDistribution InflationDistribution, inflationEnabled bool, - epochsPerPeriod uint64, + epochsPerPeriod, + periodsPerYear, + maxPeriod uint64, ) Params { return Params{ - ExponentialCalculation: exponentialCalculation, - InflationDistribution: inflationDistribution, - InflationEnabled: inflationEnabled, - EpochsPerPeriod: epochsPerPeriod, + PolynomialFactors: polynomialCalculation, + InflationDistribution: inflationDistribution, + InflationEnabled: inflationEnabled, + EpochsPerPeriod: epochsPerPeriod, + PeriodsPerYear: periodsPerYear, + MaxPeriod: maxPeriod, } } // default minting module parameters func DefaultParams() Params { return Params{ - ExponentialCalculation: DefaultExponentialCalculation, - InflationDistribution: DefaultInflationDistribution, - InflationEnabled: DefaultInflation, - EpochsPerPeriod: DefaultEpochsPerPeriod, + PolynomialFactors: DefaultPolynomialFactors, + InflationDistribution: DefaultInflationDistribution, + InflationEnabled: DefaultInflation, + EpochsPerPeriod: DefaultEpochsPerPeriod, + PeriodsPerYear: DefaultPeriodsPerYear, + MaxPeriod: DefaultMaxPeriod, } } @@ -66,37 +79,23 @@ var _ paramstypes.ParamSet = (*Params)(nil) func (p *Params) ParamSetPairs() paramstypes.ParamSetPairs { return paramstypes.ParamSetPairs{ paramstypes.NewParamSetPair(KeyInflationEnabled, &p.InflationEnabled, validateBool), - paramstypes.NewParamSetPair(KeyExponentialCalculation, &p.ExponentialCalculation, validateExponentialCalculation), + paramstypes.NewParamSetPair(KeyPolynomialFactors, &p.PolynomialFactors, validatePolynomialFactors), paramstypes.NewParamSetPair(KeyInflationDistribution, &p.InflationDistribution, validateInflationDistribution), paramstypes.NewParamSetPair(KeyEpochsPerPeriod, &p.EpochsPerPeriod, validateUint64), + paramstypes.NewParamSetPair(KeyPeriodsPerYear, &p.PeriodsPerYear, validateUint64), + paramstypes.NewParamSetPair(KeyMaxPeriod, &p.MaxPeriod, validateUint64), } } -func validateExponentialCalculation(i interface{}) error { - v, ok := i.(ExponentialCalculation) +func validatePolynomialFactors(i interface{}) error { + v, ok := i.([]sdk.Dec) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - // validate initial value - if v.A.IsNegative() { - return fmt.Errorf("initial value cannot be negative") + if len(v) == 0 { + return errors.New("polynomial factors cannot be empty") } - - // validate reduction factor - if v.R.GT(sdk.OneDec()) { - return fmt.Errorf("reduction factor cannot be greater than 1") - } - - if v.R.IsNegative() { - return fmt.Errorf("reduction factor cannot be negative") - } - - // validate long term inflation - if v.C.IsNegative() { - return fmt.Errorf("long term inflation cannot be negative") - } - return nil } @@ -156,16 +155,35 @@ func validateEpochsPerPeriod(i interface{}) error { return nil } +func validatePeriodsPerYear(i interface{}) error { + val, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if val <= 0 { + return fmt.Errorf("periods per year must be positive: %d", val) + } + + return nil +} + func (p Params) Validate() error { if err := validateEpochsPerPeriod(p.EpochsPerPeriod); err != nil { return err } - if err := validateExponentialCalculation(p.ExponentialCalculation); err != nil { + if err := validatePeriodsPerYear(p.PeriodsPerYear); err != nil { + return err + } + if err := validatePolynomialFactors(p.PolynomialFactors); err != nil { return err } if err := validateInflationDistribution(p.InflationDistribution); err != nil { return err } + if err := validateUint64(p.MaxPeriod); err != nil { + return err + } return validateBool(p.InflationEnabled) } diff --git a/x/inflation/types/params_test.go b/x/inflation/types/params_test.go index 1dbadcef1d..805855c366 100644 --- a/x/inflation/types/params_test.go +++ b/x/inflation/types/params_test.go @@ -29,83 +29,41 @@ func TestParamsValidate(t *testing.T) { { "valid", inflationtypes.NewParams( - inflationtypes.DefaultExponentialCalculation, + inflationtypes.DefaultPolynomialFactors, inflationtypes.DefaultInflationDistribution, true, inflationtypes.DefaultEpochsPerPeriod, + inflationtypes.DefaultPeriodsPerYear, + inflationtypes.DefaultMaxPeriod, ), false, }, { "valid param literal", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.DefaultExponentialCalculation, - InflationDistribution: inflationtypes.DefaultInflationDistribution, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - }, - false, - }, - { - "invalid - exponential calculation - negative A", - inflationtypes.Params{ - ExponentialCalculation: inflationtypes.ExponentialCalculation{ - A: sdk.NewDec(int64(-1)), - R: sdk.NewDecWithPrec(5, 1), - C: sdk.NewDec(int64(9_375_000)), - }, + PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.DefaultInflationDistribution, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, - true, - }, - { - "invalid - exponential calculation - R greater than 1", - inflationtypes.Params{ - ExponentialCalculation: inflationtypes.ExponentialCalculation{ - A: sdk.NewDec(int64(300_000_000)), - R: sdk.NewDecWithPrec(5, 0), - C: sdk.NewDec(int64(9_375_000)), - }, - InflationDistribution: inflationtypes.DefaultInflationDistribution, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - }, - true, - }, - { - "invalid - exponential calculation - negative R", - inflationtypes.Params{ - ExponentialCalculation: inflationtypes.ExponentialCalculation{ - A: sdk.NewDec(int64(300_000_000)), - R: sdk.NewDecWithPrec(-5, 1), - C: sdk.NewDec(int64(9_375_000)), - }, - InflationDistribution: inflationtypes.DefaultInflationDistribution, - InflationEnabled: true, - EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, - }, - true, + false, }, { - "invalid - exponential calculation - negative C", + "invalid - polynomial calculation - no coefficient", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.ExponentialCalculation{ - A: sdk.NewDec(int64(300_000_000)), - R: sdk.NewDecWithPrec(5, 1), - C: sdk.NewDec(int64(-9_375_000)), - }, + PolynomialFactors: []sdk.Dec{}, InflationDistribution: inflationtypes.DefaultInflationDistribution, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, { "invalid - inflation distribution - negative staking rewards", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.DefaultExponentialCalculation, + PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.InflationDistribution{ StakingRewards: sdk.OneDec().Neg(), CommunityPool: sdk.NewDecWithPrec(133333, 6), @@ -113,13 +71,14 @@ func TestParamsValidate(t *testing.T) { }, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, { "invalid - inflation distribution - negative usage incentives", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.DefaultExponentialCalculation, + PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.InflationDistribution{ StakingRewards: sdk.NewDecWithPrec(533334, 6), CommunityPool: sdk.NewDecWithPrec(133333, 6), @@ -127,13 +86,14 @@ func TestParamsValidate(t *testing.T) { }, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, { "invalid - inflation distribution - negative community pool rewards", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.DefaultExponentialCalculation, + PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.InflationDistribution{ StakingRewards: sdk.NewDecWithPrec(533334, 6), CommunityPool: sdk.OneDec().Neg(), @@ -141,13 +101,14 @@ func TestParamsValidate(t *testing.T) { }, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, { "invalid - inflation distribution - total distribution ratio unequal 1", inflationtypes.Params{ - ExponentialCalculation: inflationtypes.DefaultExponentialCalculation, + PolynomialFactors: inflationtypes.DefaultPolynomialFactors, InflationDistribution: inflationtypes.InflationDistribution{ StakingRewards: sdk.NewDecWithPrec(533333, 6), CommunityPool: sdk.NewDecWithPrec(133333, 6), @@ -155,6 +116,7 @@ func TestParamsValidate(t *testing.T) { }, InflationEnabled: true, EpochsPerPeriod: inflationtypes.DefaultEpochsPerPeriod, + PeriodsPerYear: inflationtypes.DefaultPeriodsPerYear, }, true, }, diff --git a/x/perp/v2/client/cli/cli_test.go b/x/perp/v2/client/cli/cli_test.go index 95bf784ef6..2546bdf242 100644 --- a/x/perp/v2/client/cli/cli_test.go +++ b/x/perp/v2/client/cli/cli_test.go @@ -82,7 +82,7 @@ func (s *IntegrationTestSuite) SetupSuite() { sdk.NewCoins( sdk.NewInt64Coin(denoms.NIBI, 10e6), sdk.NewInt64Coin(denoms.USDC, 1e3*common.TO_MICRO), - sdk.NewInt64Coin(denoms.NUSD, 5e3*common.TO_MICRO), + sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 5e3*common.TO_MICRO), ), val, denoms.NIBI, @@ -478,14 +478,14 @@ func (s *IntegrationTestSuite) TestRemoveMargin() { s.T().Log("removing margin on user 0....") _, err = s.network.ExecTxCmd(cli.RemoveMarginCmd(), s.users[0], []string{ asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("%s%s", "10000000", denoms.NUSD), + fmt.Sprintf("%s%s", "10000000", types.TestingCollateralDenomNUSD), }) s.Contains(err.Error(), types.ErrBadDebt.Error()) s.T().Log("removing margin on user 0....") _, err = s.network.ExecTxCmd(cli.RemoveMarginCmd(), s.users[0], []string{ asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("%s%s", "1", denoms.NUSD), + fmt.Sprintf("%s%s", "1", types.TestingCollateralDenomNUSD), }) s.NoError(err) s.NoError(s.network.WaitForNextBlock()) @@ -513,31 +513,34 @@ func (s *IntegrationTestSuite) TestX_AddMargin() { expectFail bool }{ { - name: "PASS: add margin to correct position", + name: "fail: not correct margin denom", args: []string{ - asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.NUSD), + asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), + fmt.Sprintf("10000%s", denoms.USDT), }, - expectedCode: 0, - expectedMargin: sdk.NewDec(1_010_000), expectFail: false, + expectedMargin: sdk.NewDec(1_000_000), + expectedCode: 1, }, { name: "fail: position not found", args: []string{ asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.NUSD), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, - expectedCode: types.ErrPositionNotFound.ABCICode(), - expectFail: false, + expectedCode: types.ErrPositionNotFound.ABCICode(), + expectedMargin: sdk.NewDec(1_000_000), + expectFail: false, }, { - name: "fail: not correct margin denom", + name: "PASS: add margin to correct position", args: []string{ - asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.USDT), + asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, - expectFail: true, + expectedCode: 0, + expectedMargin: sdk.NewDec(1_010_000), + expectFail: false, }, { name: "fail: invalid coin", @@ -551,7 +554,7 @@ func (s *IntegrationTestSuite) TestX_AddMargin() { name: "fail: invalid pair", args: []string{ "alisdhjal;dhao;sdh", - fmt.Sprintf("10000%s", denoms.NUSD), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, expectFail: true, }, @@ -582,12 +585,10 @@ func (s *IntegrationTestSuite) TestX_AddMargin() { s.Require().NoError(err) s.Require().EqualValues(tc.expectedCode, resp.Code) - if tc.expectedCode == 0 { - // query trader position - queryResp, err := testutilcli.QueryPositionV2(s.network.Validators[0].ClientCtx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), s.users[1]) - s.NoError(err) - s.EqualValues(tc.expectedMargin, queryResp.Position.Margin) - } + // query trader position + queryResp, err := testutilcli.QueryPositionV2(s.network.Validators[0].ClientCtx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), s.users[1]) + s.NoError(err) + s.EqualValues(tc.expectedMargin, queryResp.Position.Margin) } }) } @@ -615,31 +616,34 @@ func (s *IntegrationTestSuite) TestX_RemoveMargin() { expectFail bool }{ { - name: "PASS: remove margin to correct position", + name: "fail: not correct margin denom", args: []string{ - asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.NUSD), + asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), + fmt.Sprintf("10000%s", denoms.USDT), }, - expectedCode: 0, - expectedMargin: sdk.NewDec(990_000), expectFail: false, + expectedCode: 1, + expectedMargin: sdk.NewDec(1_000_000), }, { name: "fail: position not found", args: []string{ asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.NUSD), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, - expectedCode: types.ErrPositionNotFound.ABCICode(), - expectFail: false, + expectedCode: types.ErrPositionNotFound.ABCICode(), + expectedMargin: sdk.NewDec(1_000_000), + expectFail: false, }, { - name: "fail: not correct margin denom", + name: "PASS: remove margin to correct position", args: []string{ - asset.Registry.Pair(denoms.BTC, denoms.NUSD).String(), - fmt.Sprintf("10000%s", denoms.USDT), + asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, - expectFail: true, + expectedCode: 0, + expectedMargin: sdk.NewDec(990_000), + expectFail: false, }, { name: "fail: invalid coin", @@ -653,7 +657,7 @@ func (s *IntegrationTestSuite) TestX_RemoveMargin() { name: "fail: invalid pair", args: []string{ "alisdhjal;dhao;sdh", - fmt.Sprintf("10000%s", denoms.NUSD), + fmt.Sprintf("10000%s", types.TestingCollateralDenomNUSD), }, expectFail: true, }, @@ -680,12 +684,9 @@ func (s *IntegrationTestSuite) TestX_RemoveMargin() { s.Require().NoError(err) s.Require().EqualValues(tc.expectedCode, resp.Code) - if tc.expectedCode == 0 { - // query trader position - queryResp, err := testutilcli.QueryPositionV2(s.network.Validators[0].ClientCtx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), s.users[2]) - s.NoError(err) - s.EqualValues(tc.expectedMargin, queryResp.Position.Margin) - } + queryResp, err := testutilcli.QueryPositionV2(s.network.Validators[0].ClientCtx, asset.Registry.Pair(denoms.ETH, denoms.NUSD), s.users[2]) + s.NoError(err) + s.EqualValues(tc.expectedMargin, queryResp.Position.Margin) } }) } @@ -696,7 +697,7 @@ func (s *IntegrationTestSuite) TestDonateToEcosystemFund() { out, err := s.network.ExecTxCmd( cli.DonateToEcosystemFundCmd(), sdk.MustAccAddressFromBech32("nibi1w89pf5yq8ntjg89048qmtaz929fdxup0a57d8m"), - []string{"100unusd"}, + []string{"100" + types.TestingCollateralDenomNUSD}, ) s.NoError(err) s.Require().EqualValues(abcitypes.CodeTypeOK, out.Code) @@ -716,11 +717,11 @@ func (s *IntegrationTestSuite) TestDonateToEcosystemFund() { testutilcli.ExecQuery( s.network.Validators[0].ClientCtx, bankcli.GetBalancesCmd(), - []string{moduleAccountAddrPerpEF, "--denom", "unusd"}, + []string{moduleAccountAddrPerpEF, "--denom", types.TestingCollateralDenomNUSD}, resp, ), ) - s.Require().EqualValues(sdk.NewInt64Coin("unusd", 100), *resp) + s.Require().EqualValues(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100), *resp) } func (s *IntegrationTestSuite) TestQueryModuleAccount() { diff --git a/x/perp/v2/integration/action/dnr.go b/x/perp/v2/integration/action/dnr.go index eb2c38035a..7c3546c997 100644 --- a/x/perp/v2/integration/action/dnr.go +++ b/x/perp/v2/integration/action/dnr.go @@ -131,7 +131,12 @@ func MarketOrderFeeIs( } func (o *marketOrderFeeIs) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { - balanceBefore := app.BankKeeper.GetBalance(ctx, o.trader, o.pair.QuoteDenom()).Amount + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + balanceBefore := app.BankKeeper.GetBalance(ctx, o.trader, collateral).Amount resp, err := app.PerpKeeperV2.MarketOrder( ctx, o.pair, o.dir, o.trader, o.margin, o.leverage, o.baseAssetLimit, @@ -143,7 +148,7 @@ func (o *marketOrderFeeIs) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, balanceBefore = balanceBefore.Sub(resp.MarginToVault.TruncateInt()) expectedFee := math.LegacyNewDecFromInt(o.margin).Mul(o.fee.Add(sdk.MustNewDecFromStr("0.001"))) // we add the ecosystem fund fee - balanceAfter := app.BankKeeper.GetBalance(ctx, o.trader, o.pair.QuoteDenom()).Amount + balanceAfter := app.BankKeeper.GetBalance(ctx, o.trader, collateral).Amount paidFees := balanceBefore.Sub(balanceAfter) if !paidFees.Equal(expectedFee.TruncateInt()) { return ctx, fmt.Errorf("unexpected fee, wanted %s, got %s", expectedFee, paidFees), true diff --git a/x/perp/v2/integration/action/margin.go b/x/perp/v2/integration/action/margin.go index 83f09828e7..1aee0732b7 100644 --- a/x/perp/v2/integration/action/margin.go +++ b/x/perp/v2/integration/action/margin.go @@ -32,8 +32,13 @@ type addMarginAction struct { } func (a addMarginAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { - _, err := app.PerpKeeperV2.AddMargin( - ctx, a.Pair, a.Account, sdk.NewCoin(a.Pair.QuoteDenom(), a.Margin), + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + _, err = app.PerpKeeperV2.AddMargin( + ctx, a.Pair, a.Account, sdk.NewCoin(collateral, a.Margin), ) if err != nil { return ctx, err, true @@ -65,8 +70,13 @@ type addMarginFailAction struct { } func (a addMarginFailAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { - _, err := app.PerpKeeperV2.AddMargin( - ctx, a.Pair, a.Account, sdk.NewCoin(a.Pair.QuoteDenom(), a.Margin), + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + _, err = app.PerpKeeperV2.AddMargin( + ctx, a.Pair, a.Account, sdk.NewCoin(collateral, a.Margin), ) if !errors.Is(err, a.ExpectedErr) { return ctx, fmt.Errorf("expected error %v, got %v", a.ExpectedErr, err), false @@ -94,8 +104,13 @@ type removeMarginAction struct { } func (a removeMarginAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { - _, err := app.PerpKeeperV2.RemoveMargin( - ctx, a.Pair, a.Account, sdk.NewCoin(a.Pair.QuoteDenom(), a.Margin), + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + _, err = app.PerpKeeperV2.RemoveMargin( + ctx, a.Pair, a.Account, sdk.NewCoin(collateral, a.Margin), ) if err != nil { return ctx, err, false @@ -126,8 +141,13 @@ type removeMarginActionFail struct { } func (a removeMarginActionFail) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { - _, err := app.PerpKeeperV2.RemoveMargin( - ctx, a.Pair, a.Account, sdk.NewCoin(a.Pair.QuoteDenom(), a.Margin), + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + _, err = app.PerpKeeperV2.RemoveMargin( + ctx, a.Pair, a.Account, sdk.NewCoin(collateral, a.Margin), ) if !errors.Is(err, a.ExpectedErr) { return ctx, fmt.Errorf("expected error %v, got %v", a.ExpectedErr, err), false diff --git a/x/perp/v2/integration/action/market.go b/x/perp/v2/integration/action/market.go index a28ec7e3b3..805252b076 100644 --- a/x/perp/v2/integration/action/market.go +++ b/x/perp/v2/integration/action/market.go @@ -6,6 +6,7 @@ import ( "github.com/NibiruChain/collections" + "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/common/asset" "github.com/NibiruChain/nibiru/x/common/testutil/action" @@ -45,6 +46,8 @@ func (c createMarketAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context TimestampMs: ctx.BlockTime().UnixMilli(), }) + app.PerpKeeperV2.Collateral.Set(ctx, types.TestingCollateralDenomNUSD) + return ctx, nil, true } @@ -74,9 +77,9 @@ func CreateCustomMarket(pair asset.Pair, marketModifiers ...MarketModifier) acti type MarketModifier func(market *types.Market, amm *types.AMM) -func WithPrepaidBadDebt(amount sdkmath.Int) MarketModifier { +func WithPrepaidBadDebt(amount sdkmath.Int, collateral string) MarketModifier { return func(market *types.Market, amm *types.AMM) { - market.PrepaidBadDebt = sdk.NewCoin(market.Pair.QuoteDenom(), amount) + market.PrepaidBadDebt = sdk.NewCoin(collateral, amount) } } @@ -188,3 +191,31 @@ func CreateMarket(pair asset.Pair, market types.Market, amm types.AMM) action.Ac amm: amm, } } + +type setCollateral struct { + Denom string + Sender string +} + +func (c setCollateral) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { + sudoers, err := app.SudoKeeper.Sudoers.Get(ctx) + if err != nil { + return ctx, err, true + } + sudoers.Root = common.NibiruTeam + app.SudoKeeper.Sudoers.Set(ctx, sudoers) + + senderAddr, err := sdk.AccAddressFromBech32(c.Sender) + if err != nil { + return ctx, err, true + } + err = app.PerpKeeperV2.Admin.ChangeCollateralDenom(ctx, c.Denom, senderAddr) + return ctx, err, true +} + +func SetCollateral(denom string) action.Action { + return setCollateral{ + Denom: denom, + Sender: common.NibiruTeam, + } +} diff --git a/x/perp/v2/integration/action/tx.go b/x/perp/v2/integration/action/tx.go index 389ed17e1c..30ae15b981 100644 --- a/x/perp/v2/integration/action/tx.go +++ b/x/perp/v2/integration/action/tx.go @@ -6,7 +6,6 @@ import ( "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/x/common/asset" - "github.com/NibiruChain/nibiru/x/common/denoms" "github.com/NibiruChain/nibiru/x/common/testutil/action" "github.com/NibiruChain/nibiru/x/perp/v2/keeper" types "github.com/NibiruChain/nibiru/x/perp/v2/types" @@ -122,11 +121,16 @@ type msgServerAddmargin struct { func (m msgServerAddmargin) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { msgServer := keeper.NewMsgServerImpl(app.PerpKeeperV2) + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + // don't need to check response because it's already checked in clearing_house tests - _, err := msgServer.AddMargin(sdk.WrapSDKContext(ctx), &types.MsgAddMargin{ + _, err = msgServer.AddMargin(sdk.WrapSDKContext(ctx), &types.MsgAddMargin{ Pair: m.pair, Sender: m.traderAddress.String(), - Margin: sdk.NewCoin(m.pair.QuoteDenom(), m.amount), + Margin: sdk.NewCoin(collateral, m.amount), }) return ctx, err, true @@ -153,11 +157,16 @@ type msgServerRemoveMargin struct { func (m msgServerRemoveMargin) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { msgServer := keeper.NewMsgServerImpl(app.PerpKeeperV2) + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + // don't need to check response because it's already checked in clearing_house tests - _, err := msgServer.RemoveMargin(sdk.WrapSDKContext(ctx), &types.MsgRemoveMargin{ + _, err = msgServer.RemoveMargin(sdk.WrapSDKContext(ctx), &types.MsgRemoveMargin{ Pair: m.pair, Sender: m.traderAddress.String(), - Margin: sdk.NewCoin(m.pair.QuoteDenom(), m.amount), + Margin: sdk.NewCoin(collateral, m.amount), }) return ctx, err, true @@ -183,9 +192,14 @@ type msgServerDonateToPerpEf struct { func (m msgServerDonateToPerpEf) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) { msgServer := keeper.NewMsgServerImpl(app.PerpKeeperV2) - _, err := msgServer.DonateToEcosystemFund(sdk.WrapSDKContext(ctx), &types.MsgDonateToEcosystemFund{ + collateral, err := app.PerpKeeperV2.Collateral.Get(ctx) + if err != nil { + return ctx, err, true + } + + _, err = msgServer.DonateToEcosystemFund(sdk.WrapSDKContext(ctx), &types.MsgDonateToEcosystemFund{ Sender: m.sender.String(), - Donation: sdk.NewCoin(denoms.NUSD, m.amount), + Donation: sdk.NewCoin(collateral, m.amount), }) return ctx, err, true diff --git a/x/perp/v2/integration/assertion/market.go b/x/perp/v2/integration/assertion/market.go index 30fce5f7d4..4ab24b76bd 100644 --- a/x/perp/v2/integration/assertion/market.go +++ b/x/perp/v2/integration/assertion/market.go @@ -52,9 +52,9 @@ func Market_LatestCPFShouldBeEqualTo(expectedCPF sdk.Dec) MarketChecker { } } -func Market_PrepaidBadDebtShouldBeEqualTo(expectedAmount sdkmath.Int) MarketChecker { +func Market_PrepaidBadDebtShouldBeEqualTo(expectedAmount sdkmath.Int, collateral string) MarketChecker { return func(market types.Market) error { - expectedBadDebt := sdk.NewCoin(market.Pair.QuoteDenom(), expectedAmount) + expectedBadDebt := sdk.NewCoin(collateral, expectedAmount) if !market.PrepaidBadDebt.Equal(expectedBadDebt) { return fmt.Errorf("expected prepaid bad debt to be %s, got %s", expectedBadDebt, market.PrepaidBadDebt) } diff --git a/x/perp/v2/keeper/admin.go b/x/perp/v2/keeper/admin.go index 6345f6958a..34ec601f3a 100644 --- a/x/perp/v2/keeper/admin.go +++ b/x/perp/v2/keeper/admin.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/NibiruChain/nibiru/x/common/asset" - "github.com/NibiruChain/nibiru/x/common/denoms" types "github.com/NibiruChain/nibiru/x/perp/v2/types" ) @@ -36,7 +35,12 @@ Args: func (k admin) WithdrawFromInsuranceFund( ctx sdk.Context, amount sdkmath.Int, to sdk.AccAddress, ) (err error) { - coinToSend := sdk.NewCoin(denoms.NUSD, amount) + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return err + } + + coinToSend := sdk.NewCoin(collateral, amount) if err = k.BankKeeper.SendCoinsFromModuleToAccount( ctx, /* from */ types.PerpEFModuleAccount, @@ -144,3 +148,29 @@ func (k admin) CloseMarket(ctx sdk.Context, pair asset.Pair) (err error) { return nil } + +// ChangeCollateralDenom: Updates the collateral denom. A denom is valid if it is +// possible to make an sdk.Coin using it. [Admin] Only callable by sudoers. +func (k admin) ChangeCollateralDenom( + ctx sdk.Context, + denom string, + sender sdk.AccAddress, +) error { + if err := k.SudoKeeper.CheckPermissions(sender, ctx); err != nil { + return err + } + return k.UnsafeChangeCollateralDenom(ctx, denom) +} + +// UnsafeChangeCollateralDenom: Used in the genesis to set the collateral +// without requiring an explicit call from sudoers. +func (k admin) UnsafeChangeCollateralDenom( + ctx sdk.Context, + denom string, +) error { + if err := sdk.ValidateDenom(denom); err != nil { + return types.ErrInvalidCollateral.Wrap(err.Error()) + } + k.Collateral.Set(ctx, denom) + return nil +} diff --git a/x/perp/v2/keeper/admin_test.go b/x/perp/v2/keeper/admin_test.go index 66fe05d2b7..5e8d66e25f 100644 --- a/x/perp/v2/keeper/admin_test.go +++ b/x/perp/v2/keeper/admin_test.go @@ -16,6 +16,8 @@ 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" + sudotypes "github.com/NibiruChain/nibiru/x/sudo/types" + tftypes "github.com/NibiruChain/nibiru/x/tokenfactory/types" . "github.com/NibiruChain/nibiru/x/common/testutil/action" . "github.com/NibiruChain/nibiru/x/perp/v2/integration/action" @@ -28,18 +30,20 @@ func TestAdmin_WithdrawFromInsuranceFund(t *testing.T) { ) { insuranceFund := nibiru.AccountKeeper.GetModuleAddress(types.PerpEFModuleAccount) balances := nibiru.BankKeeper.GetAllBalances(ctx, insuranceFund) - got := balances.AmountOf(denoms.NUSD) + got := balances.AmountOf(types.TestingCollateralDenomNUSD) require.EqualValues(t, want.String(), got.String()) } setup := func() (nibiru *app.NibiruApp, ctx sdk.Context) { + testapp.EnsureNibiruPrefix() nibiru, ctx = testapp.NewNibiruTestAppAndContext() expectBalance(sdk.ZeroInt(), t, nibiru, ctx) + nibiru.PerpKeeperV2.Collateral.Set(ctx, types.TestingCollateralDenomNUSD) return nibiru, ctx } fundModule := func(t *testing.T, amount sdkmath.Int, ctx sdk.Context, nibiru *app.NibiruApp) { - coins := sdk.NewCoins(sdk.NewCoin(denoms.NUSD, amount)) + coins := sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, amount)) err := testapp.FundModuleAccount( nibiru.BankKeeper, ctx, types.PerpEFModuleAccount, coins, @@ -63,7 +67,7 @@ func TestAdmin_WithdrawFromInsuranceFund(t *testing.T) { require.EqualValues(t, amountToFund.String(), - nibiru.BankKeeper.GetBalance(ctx, admin, denoms.NUSD).Amount.String(), + nibiru.BankKeeper.GetBalance(ctx, admin, types.TestingCollateralDenomNUSD).Amount.String(), ) expectBalance(sdk.ZeroInt(), t, nibiru, ctx) }, @@ -201,7 +205,7 @@ func TestCloseMarket(t *testing.T) { SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( CloseMarket(pairBtcUsdc), @@ -226,7 +230,7 @@ func TestCloseMarket(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), MarketOrder( alice, pairBtcUsdc, @@ -251,7 +255,7 @@ func TestCloseMarket(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), MarketOrder( alice, pairBtcUsdc, @@ -270,3 +274,68 @@ func TestCloseMarket(t *testing.T) { NewTestSuite(t).WithTestCases(tc...).Run() } + +func TestAdmin_ChangeCollateralDenom(t *testing.T) { + adminSender := testutil.AccAddress() + nonAdminSender := testutil.AccAddress() + + setup := func() (nibiru *app.NibiruApp, ctx sdk.Context) { + nibiru, ctx = testapp.NewNibiruTestAppAndContext() + nibiru.SudoKeeper.Sudoers.Set(ctx, sudotypes.Sudoers{ + Root: "mock-root", // unused + Contracts: []string{adminSender.String()}, + }) + return nibiru, ctx + } + + for _, tc := range []struct { + newDenom string + sender sdk.AccAddress + wantErr string + name string + }{ + {name: "happy: normal denom", newDenom: "nusd", sender: adminSender, wantErr: ""}, + + {name: "happy: token factory denom", + newDenom: tftypes.TFDenom{ + Creator: testutil.AccAddress().String(), + Subdenom: "nusd", + }.String(), sender: adminSender, wantErr: ""}, + + {name: "happy: token factory denom", + newDenom: tftypes.TFDenom{ + Creator: testutil.AccAddress().String(), + Subdenom: "nusd", + }.String(), sender: adminSender, wantErr: "", + }, + + {name: "happy: IBC denom", + newDenom: "ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED", // JUNO on Osmosis + sender: adminSender, wantErr: "", + }, + + {name: "sad: invalid denom", + newDenom: "", sender: adminSender, wantErr: types.ErrInvalidCollateral.Error(), + }, + {name: "sad: sender not in sudoers", + newDenom: "nusd", sender: nonAdminSender, wantErr: "insufficient permissions on smart contract", + }, + } { + t.Run(tc.name, func(t *testing.T) { + bapp, ctx := setup() + err := bapp.PerpKeeperV2.Admin.ChangeCollateralDenom( + ctx, tc.newDenom, tc.sender, + ) + + if tc.wantErr != "" { + require.ErrorContains(t, err, tc.wantErr) + return + } + require.NoError(t, err) + + newDenom, err := bapp.PerpKeeperV2.Collateral.Get(ctx) + require.NoError(t, err) + require.Equal(t, tc.newDenom, newDenom) + }) + } +} diff --git a/x/perp/v2/keeper/amm.go b/x/perp/v2/keeper/amm.go index 79b85d1826..722e6d349e 100644 --- a/x/perp/v2/keeper/amm.go +++ b/x/perp/v2/keeper/amm.go @@ -79,10 +79,15 @@ func (k Keeper) EditSwapInvariant(ctx sdk.Context, pair asset.Pair, newSwapInvar } func (k Keeper) handleMarketUpdateCost(ctx sdk.Context, pair asset.Pair, costAmt sdkmath.Int) (err error) { + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return err + } + if costAmt.IsPositive() { // Positive cost, send from perp EF to vault cost := sdk.NewCoins( - sdk.NewCoin(pair.QuoteDenom(), costAmt), + sdk.NewCoin(collateral, costAmt), ) err = k.BankKeeper.SendCoinsFromModuleToModule( ctx, @@ -94,7 +99,7 @@ func (k Keeper) handleMarketUpdateCost(ctx sdk.Context, pair asset.Pair, costAmt return types.ErrNotEnoughFundToPayAction.Wrapf( "not enough fund in perp ef to pay for repeg, need %s got %s", cost.String(), - k.BankKeeper.GetBalance(ctx, k.AccountKeeper.GetModuleAddress(types.PerpEFModuleAccount), pair.QuoteDenom()).String(), + k.BankKeeper.GetBalance(ctx, k.AccountKeeper.GetModuleAddress(types.PerpEFModuleAccount), collateral).String(), ) } } else if costAmt.IsNegative() { @@ -104,7 +109,7 @@ func (k Keeper) handleMarketUpdateCost(ctx sdk.Context, pair asset.Pair, costAmt types.VaultModuleAccount, types.PerpEFModuleAccount, sdk.NewCoins( - sdk.NewCoin(pair.QuoteDenom(), costAmt.Neg()), + sdk.NewCoin(collateral, costAmt.Neg()), ), ) if err != nil { // nolint:staticcheck diff --git a/x/perp/v2/keeper/amm_test.go b/x/perp/v2/keeper/amm_test.go index 6b4cd13a36..b2ff2513a3 100644 --- a/x/perp/v2/keeper/amm_test.go +++ b/x/perp/v2/keeper/amm_test.go @@ -11,6 +11,7 @@ import ( "github.com/NibiruChain/nibiru/x/common/asset" "github.com/NibiruChain/nibiru/x/common/denoms" + "github.com/NibiruChain/nibiru/x/common/testutil" . "github.com/NibiruChain/nibiru/x/common/testutil/action" . "github.com/NibiruChain/nibiru/x/common/testutil/assertion" "github.com/NibiruChain/nibiru/x/common/testutil/testapp" @@ -27,15 +28,15 @@ func TestEditPriceMultipler(t *testing.T) { TC("same price multiplier"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(1000)), WithTotalShort(sdk.NewDec(500))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.OneDec()), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -50,15 +51,15 @@ func TestEditPriceMultipler(t *testing.T) { WithTotalLong(sdk.NewDec(1000)), WithTotalShort(sdk.NewDec(1000)), WithEnabled(true), ), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.NewDec(10)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -70,15 +71,15 @@ func TestEditPriceMultipler(t *testing.T) { TC("long bias, increase price multiplier"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(1000)), WithTotalShort(sdk.NewDec(500))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.NewDec(10)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1004500)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(995500)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1004500)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(995500)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -90,15 +91,15 @@ func TestEditPriceMultipler(t *testing.T) { TC("long bias, decrease price multiplier"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(1000)), WithTotalShort(sdk.NewDec(500))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.MustNewDecFromStr("0.25")), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(999626)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1000374)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999626)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1000374)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -110,15 +111,15 @@ func TestEditPriceMultipler(t *testing.T) { TC("short bias, increase price multiplier"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(500)), WithTotalShort(sdk.NewDec(1000))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.NewDec(10)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(995500)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1004500)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(995500)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1004500)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -130,15 +131,15 @@ func TestEditPriceMultipler(t *testing.T) { TC("short bias, decrease price multiplier"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(500)), WithTotalShort(sdk.NewDec(1000))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditPriceMultiplier(pair, sdk.MustNewDecFromStr("0.25")), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1000376)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(999624)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1000376)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999624)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e12)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e12)), @@ -154,7 +155,8 @@ func TestEditPriceMultipler(t *testing.T) { func TestEditPriceMultiplerFail(t *testing.T) { pair := asset.Registry.Pair(denoms.BTC, denoms.NUSD) app, ctx := testapp.NewNibiruTestAppAndContext() - account := sdk.MustAccAddressFromBech32("cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v") + + account := testutil.AccAddress() err := app.PerpKeeperV2.Admin.CreateMarket( ctx, @@ -191,17 +193,17 @@ func TestEditPriceMultiplerFail(t *testing.T) { require.ErrorIs(t, err, types.ErrNonPositivePegMultiplier) // Add market activity - err = app.BankKeeper.MintCoins(ctx, "inflation", sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1020)))) + err = app.BankKeeper.MintCoins(ctx, "inflation", sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1020)))) require.NoError(t, err) - err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, "inflation", account, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1020)))) + err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, "inflation", account, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1020)))) require.NoError(t, err) _, err = app.PerpKeeperV2.MarketOrder( ctx, pair, types.Direction_LONG, - sdk.MustAccAddressFromBech32("cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v"), + account, sdk.NewInt(1000), sdk.OneDec(), sdk.ZeroDec(), @@ -220,7 +222,7 @@ func TestEditPriceMultiplerFail(t *testing.T) { func TestEditSwapInvariantFail(t *testing.T) { pair := asset.Registry.Pair(denoms.BTC, denoms.NUSD) app, ctx := testapp.NewNibiruTestAppAndContext() - account := sdk.MustAccAddressFromBech32("cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v") + account := testutil.AccAddress() err := app.PerpKeeperV2.Admin.CreateMarket( ctx, @@ -257,17 +259,17 @@ func TestEditSwapInvariantFail(t *testing.T) { require.ErrorIs(t, err, types.ErrNegativeSwapInvariant) // Add market activity - err = app.BankKeeper.MintCoins(ctx, "inflation", sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(102)))) + err = app.BankKeeper.MintCoins(ctx, "inflation", sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(102)))) require.NoError(t, err) - err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, "inflation", account, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(102)))) + err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, "inflation", account, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(102)))) require.NoError(t, err) _, err = app.PerpKeeperV2.MarketOrder( ctx, pair, types.Direction_LONG, - sdk.MustAccAddressFromBech32("cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v"), + account, sdk.NewInt(100), sdk.OneDec(), sdk.ZeroDec(), @@ -298,15 +300,15 @@ func TestEditSwapInvariant(t *testing.T) { WithTotalShort(sdk.NewDec(500)), WithSqrtDepth(sdk.NewDec(1e6)), ), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e12)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e6)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e6)), @@ -322,15 +324,15 @@ func TestEditSwapInvariant(t *testing.T) { WithTotalShort(sdk.NewDec(1000)), WithSqrtDepth(sdk.NewDec(1e6)), ), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e18)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e9)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e9)), @@ -342,15 +344,15 @@ func TestEditSwapInvariant(t *testing.T) { TC("long bias, increase swap invariant"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(1e5)), WithSqrtDepth(sdk.NewDec(1e6))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e14)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1008101)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(991899)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1008101)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(991899)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e7)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e7)), @@ -362,15 +364,15 @@ func TestEditSwapInvariant(t *testing.T) { TC("long bias, decrease swap invariant"). Given( CreateCustomMarket(pair, WithTotalLong(sdk.NewDec(1e2)), WithSqrtDepth(sdk.NewDec(1e6))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e6)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(999991)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1000009)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999991)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1000009)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e3)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e3)), @@ -382,15 +384,15 @@ func TestEditSwapInvariant(t *testing.T) { TC("short bias, increase swap invariant"). Given( CreateCustomMarket(pair, WithTotalShort(sdk.NewDec(1e5)), WithSqrtDepth(sdk.NewDec(1e6))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e14)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1010102)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(989898)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1010102)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(989898)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e7)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e7)), @@ -402,15 +404,15 @@ func TestEditSwapInvariant(t *testing.T) { TC("short bias, decrease swap invariant"). Given( CreateCustomMarket(pair, WithTotalShort(sdk.NewDec(1e2)), WithSqrtDepth(sdk.NewDec(1e6))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( EditSwapInvariant(pair, sdk.NewDec(1e6)), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(999989)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(1000011)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(999989)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1000011)), AMMShouldBeEqual(pair, AMM_SqrtDepthShouldBeEqual(sdk.NewDec(1e3)), AMM_BaseReserveShouldBeEqual(sdk.NewDec(1e3)), diff --git a/x/perp/v2/keeper/clearing_house.go b/x/perp/v2/keeper/clearing_house.go index 672449d355..2022bf4715 100644 --- a/x/perp/v2/keeper/clearing_house.go +++ b/x/perp/v2/keeper/clearing_house.go @@ -539,9 +539,15 @@ func (k Keeper) afterPositionUpdate( ) (err error) { // transfer trader <=> vault marginToVault := positionResp.MarginToVault.RoundInt() + + collateral, err := k.Collateral.Get(ctx) + if errors.Is(err, collections.ErrNotFound) { + return types.ErrCollateralTokenFactoryDenomNotSet + } + switch { case marginToVault.IsPositive(): - coinToSend := sdk.NewCoin(market.Pair.QuoteDenom(), marginToVault) + coinToSend := sdk.NewCoin(collateral, marginToVault) if err = k.BankKeeper.SendCoinsFromAccountToModule( ctx, traderAddr, types.VaultModuleAccount, sdk.NewCoins(coinToSend)); err != nil { return err @@ -577,9 +583,9 @@ func (k Keeper) afterPositionUpdate( &types.PositionChangedEvent{ FinalPosition: positionResp.Position, PositionNotional: positionNotional, - TransactionFee: sdk.NewCoin(market.Pair.QuoteDenom(), transferredFee), + TransactionFee: sdk.NewCoin(collateral, transferredFee), RealizedPnl: positionResp.RealizedPnl, - BadDebt: sdk.NewCoin(market.Pair.QuoteDenom(), positionResp.BadDebt.RoundInt()), + BadDebt: sdk.NewCoin(collateral, positionResp.BadDebt.RoundInt()), FundingPayment: positionResp.FundingPayment, BlockHeight: ctx.BlockHeight(), MarginToUser: marginToVault.Neg().Sub(transferredFee), @@ -635,6 +641,11 @@ func (k Keeper) transferFee( exchangeFeeRatio sdk.Dec, ecosystemFundFeeRatio sdk.Dec, ) (fees sdkmath.Int, err error) { + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return sdkmath.Int{}, err + } + exchangeFeeRatio, err = k.applyDiscountAndRebate(ctx, pair, trader, positionNotional, exchangeFeeRatio) if err != nil { return sdkmath.Int{}, err @@ -647,7 +658,7 @@ func (k Keeper) transferFee( /* to */ types.FeePoolModuleAccount, /* coins */ sdk.NewCoins( sdk.NewCoin( - pair.QuoteDenom(), + collateral, feeToExchangeFeePool, ), ), @@ -664,7 +675,7 @@ func (k Keeper) transferFee( /* to */ types.PerpEFModuleAccount, /* coins */ sdk.NewCoins( sdk.NewCoin( - pair.QuoteDenom(), + collateral, feeToEcosystemFund, ), ), diff --git a/x/perp/v2/keeper/clearing_house_test.go b/x/perp/v2/keeper/clearing_house_test.go index 713176cbd9..270b1dba29 100644 --- a/x/perp/v2/keeper/clearing_house_test.go +++ b/x/perp/v2/keeper/clearing_house_test.go @@ -41,9 +41,9 @@ func TestMarketOrder(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), - FundAccount(bob, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), + FundAccount(bob, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()), MarketOrder(bob, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()), @@ -65,7 +65,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1020)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec(), @@ -111,9 +111,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(10_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), BlockHeight: 1, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 20).Neg(), @@ -128,7 +128,7 @@ func TestMarketOrder(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), CreateCustomMarket(pairBtcNusd, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(2040)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2040)))), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -167,9 +167,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(20_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 20).Neg(), @@ -189,7 +189,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -225,7 +225,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -261,9 +261,9 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_000)))), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(9_000), sdk.NewDec(10), sdk.ZeroDec()), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), EditSwapInvariant(pairBtcNusd, sdk.OneDec()), ). When( @@ -278,7 +278,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1030)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1030)))), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -318,9 +318,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(5000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(10)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(0 + 10).Neg(), @@ -340,7 +340,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -372,7 +372,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(4080)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4080)))), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -412,9 +412,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(20000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(60)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(60)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 60).Neg(), @@ -433,7 +433,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -479,9 +479,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("-1100.000088999999110000"), - BadDebt: sdk.NewInt64Coin(denoms.NUSD, 102), + BadDebt: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 102), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewInt64Coin(denoms.NUSD, 18), // 20 bps + TransactionFee: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 18), // 20 bps BlockHeight: 2, MarginToUser: sdk.NewInt(-18), ChangeReason: types.ChangeReason_MarketOrder, @@ -495,7 +495,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1020)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec(), @@ -543,9 +543,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(10_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), BlockHeight: 1, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 20).Neg(), @@ -560,7 +560,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(2040)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2040)))), MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -600,9 +600,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(20_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 20).Neg(), @@ -620,7 +620,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(22)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(22)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -652,7 +652,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1030)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1030)))), MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -692,9 +692,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(5000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(10)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(0 + 10).Neg(), @@ -713,7 +713,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(22)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(22)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -745,7 +745,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(4080)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4080)))), MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -785,9 +785,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.NewDec(20000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(60)), // 20 bps + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(60)), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(1_000 + 60).Neg(), @@ -805,7 +805,7 @@ func TestMarketOrder(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(22)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(22)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -851,9 +851,9 @@ func TestMarketOrder(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("-1100.000111000001110000"), - BadDebt: sdk.NewInt64Coin(denoms.NUSD, 98), + BadDebt: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 98), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewInt64Coin(denoms.NUSD, 22), // 20 bps + TransactionFee: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 22), // 20 bps BlockHeight: 2, // exchangedMargin = - marginToVault - transferredFee MarginToUser: sdk.NewInt(-22), @@ -868,7 +868,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(99)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(99)))), ). When( MarketOrderFails( @@ -884,7 +884,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(47_714_285_715)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(47_714_285_715)))), CloseMarket(pairBtcNusd), ). When( @@ -899,7 +899,7 @@ func TestMarketOrder(t *testing.T) { Given( SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(47_714_285_715)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(47_714_285_715)))), ). When( MarketOrderFails(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(47_619_047_619), sdk.OneDec(), sdk.ZeroDec(), @@ -914,7 +914,7 @@ func TestMarketOrder(t *testing.T) { SetBlockTime(startBlockTime), SetBlockNumber(1), CreateCustomMarket(pairBtcNusd, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(47_714_285_715)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(47_714_285_715)))), ). When( MarketOrderFails(alice, pairBtcNusd, types.Direction_LONG, sdk.ZeroInt(), sdk.OneDec(), sdk.ZeroDec(), @@ -929,7 +929,7 @@ func TestMarketOrder(t *testing.T) { SetBlockTime(startBlockTime), SetBlockNumber(1), CreateCustomMarket(pairBtcNusd, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrderFails(alice, pairBtcNusd, types.Direction_LONG, sdk.OneInt(), sdk.ZeroDec(), sdk.ZeroDec(), @@ -944,7 +944,7 @@ func TestMarketOrder(t *testing.T) { SetBlockTime(startBlockTime), SetBlockNumber(1), CreateCustomMarket(pairBtcNusd, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrderFails(alice, pairBtcNusd, types.Direction_LONG, sdk.OneInt(), sdk.NewDec(11), sdk.ZeroDec(), @@ -961,7 +961,7 @@ func TestMarketOrder(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true), WithPricePeg(sdk.MustNewDecFromStr("25001.0112"))), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_000_000_000+20_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_000_000_000+20_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -979,7 +979,7 @@ func TestMarketOrder(t *testing.T) { pairBtcNusd, WithEnabled(true), WithPricePeg(sdk.MustNewDecFromStr("25001.0112"))), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(100_000), sdk.OneDec(), sdk.ZeroDec()), @@ -996,7 +996,7 @@ func TestMarketOrder(t *testing.T) { pairBtcNusd, WithEnabled(true), WithPricePeg(sdk.MustNewDecFromStr("25001.0112"))), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(50_000), sdk.NewDec(2), sdk.ZeroDec()), @@ -1014,7 +1014,7 @@ func TestMarketOrder(t *testing.T) { pairBtcNusd, WithEnabled(true), WithPricePeg(sdk.MustNewDecFromStr("25001.0112"))), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(100_000), sdk.OneDec(), sdk.ZeroDec()), @@ -1032,7 +1032,7 @@ func TestMarketOrder(t *testing.T) { pairBtcNusd, WithEnabled(true), WithPricePeg(sdk.MustNewDecFromStr("25000"))), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1e6)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1e6)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(100_000), sdk.OneDec(), sdk.ZeroDec()), @@ -1064,7 +1064,7 @@ func TestMarketOrderError(t *testing.T) { }{ { name: "not enough trader funds", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 999)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 999)), initialPosition: nil, side: types.Direction_LONG, margin: sdk.NewInt(1000), @@ -1074,7 +1074,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "position has bad debt", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 999)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 999)), initialPosition: &types.Position{ Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD), Size_: sdk.OneDec(), @@ -1091,7 +1091,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "new long position not over base limit", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_LONG, margin: sdk.NewInt(1000), @@ -1101,7 +1101,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "new short position not under base limit", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_SHORT, margin: sdk.NewInt(1000), @@ -1111,7 +1111,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "quote asset amount is zero", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_SHORT, margin: sdk.ZeroInt(), @@ -1121,7 +1121,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "leverage amount is zero", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_SHORT, margin: sdk.NewInt(1000), @@ -1131,7 +1131,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "leverage amount is too high - SELL", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_SHORT, margin: sdk.NewInt(100), @@ -1141,7 +1141,7 @@ func TestMarketOrderError(t *testing.T) { }, { name: "leverage amount is too high - BUY", - traderFunds: sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1020)), + traderFunds: sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1020)), initialPosition: nil, side: types.Direction_LONG, margin: sdk.NewInt(100), @@ -1197,7 +1197,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1231,9 +1231,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("14999.999812500001968750"), RealizedPnl: sdk.MustNewDecFromStr("2499.999950000000500000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(10)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10)), BlockHeight: 1, MarginToUser: sdk.NewInt(-10), ChangeReason: types.ChangeReason_PartialClose, @@ -1252,7 +1252,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(4)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1286,9 +1286,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("7124.999910937500935156"), RealizedPnl: sdk.MustNewDecFromStr("-125.000023749999762500"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(4)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4)), BlockHeight: 1, MarginToUser: sdk.NewInt(-4), ChangeReason: types.ChangeReason_PartialClose, @@ -1307,7 +1307,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(4)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1341,9 +1341,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("7049.999911875000925312"), RealizedPnl: sdk.MustNewDecFromStr("-150.000023499999765000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(4)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(4)), BlockHeight: 1, MarginToUser: sdk.NewInt(-4), ChangeReason: types.ChangeReason_PartialClose, @@ -1361,8 +1361,8 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 2))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 27))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 2))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 27))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1396,9 +1396,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("4424.999944687500580781"), RealizedPnl: sdk.MustNewDecFromStr("-1025.000014749999852500"), - BadDebt: sdk.NewInt64Coin(denoms.NUSD, 27), + BadDebt: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 27), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewInt64Coin(denoms.NUSD, 2), + TransactionFee: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 2), BlockHeight: 1, MarginToUser: sdk.NewInt(-2), ChangeReason: types.ChangeReason_PartialClose, @@ -1416,7 +1416,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(2)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1450,9 +1450,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("250.000004375000057812"), RealizedPnl: sdk.MustNewDecFromStr("6749.999992499999925000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(2)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2)), BlockHeight: 1, MarginToUser: sdk.NewInt(-2), ChangeReason: types.ChangeReason_PartialClose, @@ -1471,7 +1471,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(16)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(16)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1505,9 +1505,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("2625.000045937500607031"), RealizedPnl: sdk.MustNewDecFromStr("-375.000078750000787500"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(16)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(16)), BlockHeight: 1, MarginToUser: sdk.NewInt(-16), ChangeReason: types.ChangeReason_PartialClose, @@ -1526,7 +1526,7 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(16)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(16)))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1560,9 +1560,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("2725.000047687500630156"), RealizedPnl: sdk.MustNewDecFromStr("-675.000081750000817500"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(16)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(16)), BlockHeight: 1, MarginToUser: sdk.NewInt(-16), ChangeReason: types.ChangeReason_PartialClose, @@ -1581,8 +1581,8 @@ func TestPartialClose(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 48))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 48))), InsertPosition( WithPair(pairBtcNusd), WithTrader(alice), @@ -1616,9 +1616,9 @@ func TestPartialClose(t *testing.T) { }, PositionNotional: sdk.MustNewDecFromStr("2850.000049875000659062"), RealizedPnl: sdk.MustNewDecFromStr("-1050.000085500000855000"), - BadDebt: sdk.NewInt64Coin(denoms.NUSD, 48), + BadDebt: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 48), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(18)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(18)), BlockHeight: 1, MarginToUser: sdk.NewInt(-18), ChangeReason: types.ChangeReason_PartialClose, @@ -1637,7 +1637,7 @@ func TestPartialClose(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), PartialCloseFails(alice, pairBtcNusd, sdk.NewDec(5_000), types.ErrPositionNotFound), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(9_000), sdk.OneDec(), sdk.ZeroDec()), @@ -1665,8 +1665,8 @@ func TestClosePosition(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(40)))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 10_998))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(40)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 10_998))), InsertPosition( WithTrader(alice), WithPair(pairBtcNusd), @@ -1692,9 +1692,9 @@ func TestClosePosition(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("9999.999800000002000000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(40)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(40)), BlockHeight: 1, MarginToUser: sdk.NewInt(10_958), ChangeReason: types.ChangeReason_ClosePosition, @@ -1712,8 +1712,8 @@ func TestClosePosition(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 898))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 898))), InsertPosition( WithTrader(alice), WithPair(pairBtcNusd), @@ -1739,9 +1739,9 @@ func TestClosePosition(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("-100.000098999999010000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), BlockHeight: 1, MarginToUser: sdk.NewInt(878), ChangeReason: types.ChangeReason_ClosePosition, @@ -1766,9 +1766,9 @@ func TestClosePosition(t *testing.T) { WithMargin(sdk.NewDec(1_000)), WithOpenNotional(sdk.NewDec(10_000)), ), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 18))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1000))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 102))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 18))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 102))), ). When( MoveToNextBlock(), @@ -1787,9 +1787,9 @@ func TestClosePosition(t *testing.T) { LastUpdatedBlockNumber: 2, }, PositionNotional: sdk.ZeroDec(), - TransactionFee: sdk.NewInt64Coin(denoms.NUSD, 18), + TransactionFee: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 18), RealizedPnl: sdk.MustNewDecFromStr("-1100.000088999999110000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.NewInt(102)), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(102)), FundingPayment: sdk.NewDec(2), BlockHeight: 2, MarginToUser: sdk.NewInt(-18), @@ -1797,8 +1797,8 @@ func TestClosePosition(t *testing.T) { ExchangedNotional: sdk.MustNewDecFromStr("-10000.000000000000000000"), ExchangedSize: sdk.MustNewDecFromStr("-10000.000000000000000000"), }), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1102)), // 1000 + 102 from perp ef - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(9)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1102)), // 1000 + 102 from perp ef + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(9)), ), TC("close short position with positive PnL"). @@ -1810,8 +1810,8 @@ func TestClosePosition(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(2)))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 10_002))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 10_002))), InsertPosition( WithTrader(alice), WithPair(pairBtcNusd), @@ -1837,9 +1837,9 @@ func TestClosePosition(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("8999.999989999999900000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(2)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2)), BlockHeight: 1, MarginToUser: sdk.NewInt(10_000), ChangeReason: types.ChangeReason_ClosePosition, @@ -1857,8 +1857,8 @@ func TestClosePosition(t *testing.T) { ), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 902))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 902))), InsertPosition( WithTrader(alice), WithPair(pairBtcNusd), @@ -1884,9 +1884,9 @@ func TestClosePosition(t *testing.T) { }, PositionNotional: sdk.ZeroDec(), RealizedPnl: sdk.MustNewDecFromStr("-100.000101000001010000"), - BadDebt: sdk.NewCoin(denoms.NUSD, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.NewDec(-2), - TransactionFee: sdk.NewCoin(denoms.NUSD, sdk.NewInt(20)), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20)), BlockHeight: 1, MarginToUser: sdk.NewInt(882), ChangeReason: types.ChangeReason_ClosePosition, @@ -1911,9 +1911,9 @@ func TestClosePosition(t *testing.T) { WithMargin(sdk.NewDec(1_000)), WithOpenNotional(sdk.NewDec(10_000)), ), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 22))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 1000))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 98))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 22))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 98))), ). When( MoveToNextBlock(), @@ -1932,9 +1932,9 @@ func TestClosePosition(t *testing.T) { LastUpdatedBlockNumber: 2, }, PositionNotional: sdk.ZeroDec(), - TransactionFee: sdk.NewInt64Coin(denoms.NUSD, 22), + TransactionFee: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 22), RealizedPnl: sdk.MustNewDecFromStr("-1100.000111000001110000"), - BadDebt: sdk.NewInt64Coin(denoms.NUSD, 98), + BadDebt: sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 98), FundingPayment: sdk.NewDec(-2), BlockHeight: 2, MarginToUser: sdk.NewInt(-22), @@ -1942,8 +1942,8 @@ func TestClosePosition(t *testing.T) { ExchangedNotional: sdk.MustNewDecFromStr("-10000.000000000000000000"), ExchangedSize: sdk.MustNewDecFromStr("10000.000000000000000000"), }), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.NUSD, sdk.NewInt(1098)), // 1000 + 98 from perp ef - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(11)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(1098)), // 1000 + 98 from perp ef + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(11)), ), } @@ -1964,8 +1964,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -1979,8 +1979,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.NewDec(10_000_000_000_000)), @@ -1994,8 +1994,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2014,8 +2014,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2027,7 +2027,7 @@ func TestUpdateSwapInvariant(t *testing.T) { ). Then( PositionShouldNotExist(alice, pairBtcNusd, 1), - ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.OneInt()))), + ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.OneInt()))), ), TC("only long position - decreasing k"). @@ -2035,8 +2035,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2055,8 +2055,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_SHORT, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2076,8 +2076,8 @@ func TestUpdateSwapInvariant(t *testing.T) { CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundAccount(bob, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundAccount(bob, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2089,8 +2089,8 @@ func TestUpdateSwapInvariant(t *testing.T) { AMM_BiasShouldBeEqual(sdk.ZeroDec()), AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("100000000000000000000000000.000000000000000000"))), - ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_000_000_000)))), - ModuleBalanceShouldBeEqualTo(types.FeePoolModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_000_000)))), // Fees are 10_000_000_000 * 0.0010 * 2 + ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_000_000_000)))), + ModuleBalanceShouldBeEqualTo(types.FeePoolModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_000_000)))), // Fees are 10_000_000_000 * 0.0010 * 2 ClosePosition(alice, pairBtcNusd), ClosePosition(bob, pairBtcNusd), @@ -2100,15 +2100,15 @@ func TestUpdateSwapInvariant(t *testing.T) { PositionShouldNotExist(bob, pairBtcNusd, 1), ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins()), - ModuleBalanceShouldBeEqualTo(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(39_782_394)))), + ModuleBalanceShouldBeEqualTo(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(39_782_394)))), ), TC("long and short position - reducing k"). Given( CreateCustomMarket(pairBtcNusd, WithEnabled(true)), SetBlockTime(startBlockTime), SetBlockNumber(1), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), - FundAccount(bob, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), + FundAccount(bob, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000_000_000), sdk.OneDec(), sdk.ZeroDec()), @@ -2120,8 +2120,8 @@ func TestUpdateSwapInvariant(t *testing.T) { AMM_BiasShouldBeEqual(sdk.ZeroDec()), AMM_SwapInvariantShouldBeEqual(sdk.MustNewDecFromStr("99999999999999999873578.871987712489000000"))), - ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_000_000_000)))), - ModuleBalanceShouldBeEqualTo(types.FeePoolModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_000_000)))), // Fees are 10_000_000_000 * 0.0010 * 2 + ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_000_000_000)))), + ModuleBalanceShouldBeEqualTo(types.FeePoolModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_000_000)))), // Fees are 10_000_000_000 * 0.0010 * 2 ClosePosition(alice, pairBtcNusd), ClosePosition(bob, pairBtcNusd), @@ -2131,7 +2131,7 @@ func TestUpdateSwapInvariant(t *testing.T) { PositionShouldNotExist(bob, pairBtcNusd, 1), ModuleBalanceShouldBeEqualTo(types.VaultModuleAccount, sdk.NewCoins()), - ModuleBalanceShouldBeEqualTo(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(39_200_810)))), + ModuleBalanceShouldBeEqualTo(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(39_200_810)))), ), } diff --git a/x/perp/v2/keeper/dnr_test.go b/x/perp/v2/keeper/dnr_test.go index b1affbaa16..3495792632 100644 --- a/x/perp/v2/keeper/dnr_test.go +++ b/x/perp/v2/keeper/dnr_test.go @@ -35,8 +35,8 @@ func TestUserVolumes(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()), @@ -56,8 +56,8 @@ func TestUserVolumes(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( DnREpochIs(1), @@ -80,8 +80,8 @@ func TestUserVolumes(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ).When( DnREpochIs(1), MarketOrder(alice, pairBtcNusd, types.Direction_LONG, sdk.NewInt(10_000), sdk.OneDec(), sdk.ZeroDec()), // open epoch 1 @@ -125,8 +125,8 @@ func TestDiscount(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( DnREpochIs(1), @@ -146,8 +146,8 @@ func TestDiscount(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( SetGlobalDiscount(fauxGlobalFeeDiscount, sdk.NewInt(50_000)), @@ -171,8 +171,8 @@ func TestDiscount(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( SetGlobalDiscount(globalFeeDiscount, sdk.NewInt(50_000)), @@ -196,8 +196,8 @@ func TestDiscount(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, positionSize.AddRaw(1000)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(100_000_000)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, positionSize.AddRaw(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(100_000_000)))), ). When( SetGlobalDiscount(sdk.MustNewDecFromStr("0.0004"), sdk.NewInt(50_000)), diff --git a/x/perp/v2/keeper/keeper.go b/x/perp/v2/keeper/keeper.go index 60620852a0..ec7aa71bd1 100644 --- a/x/perp/v2/keeper/keeper.go +++ b/x/perp/v2/keeper/keeper.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/common/asset" types "github.com/NibiruChain/nibiru/x/perp/v2/types" ) @@ -25,6 +26,7 @@ type Keeper struct { AccountKeeper types.AccountKeeper OracleKeeper types.OracleKeeper EpochKeeper types.EpochKeeper + SudoKeeper types.SudoKeeper // Extends the Keeper with admin functions. See admin.go. Admin admin @@ -32,6 +34,7 @@ type Keeper struct { MarketLastVersion collections.Map[asset.Pair, types.MarketLastVersion] Markets collections.Map[collections.Pair[asset.Pair, uint64], types.Market] AMMs collections.Map[collections.Pair[asset.Pair, uint64], types.AMM] + Collateral collections.Item[string] Positions collections.Map[collections.Pair[collections.Pair[asset.Pair, uint64], sdk.AccAddress], types.Position] ReserveSnapshots collections.Map[collections.Pair[asset.Pair, time.Time], types.ReserveSnapshot] @@ -50,6 +53,7 @@ func NewKeeper( bankKeeper types.BankKeeper, oracleKeeper types.OracleKeeper, epochKeeper types.EpochKeeper, + sudoKeeper types.SudoKeeper, ) Keeper { // Ensure that the module account is set. if moduleAcc := accountKeeper.GetModuleAddress(types.ModuleName); moduleAcc == nil { @@ -63,6 +67,7 @@ func NewKeeper( AccountKeeper: accountKeeper, OracleKeeper: oracleKeeper, EpochKeeper: epochKeeper, + SudoKeeper: sudoKeeper, Markets: collections.NewMap( storeKey, NamespaceMarkets, collections.PairKeyEncoder(asset.PairKeyEncoder, collections.Uint64KeyEncoder), @@ -107,6 +112,10 @@ func NewKeeper( collections.PairKeyEncoder(collections.AccAddressKeyEncoder, IntKeyEncoder), collections.DecValueEncoder, ), + Collateral: collections.NewItem( + storeKey, NamespaceCollateral, + common.StringValueEncoder, + ), } k.Admin = admin{&k} return k @@ -122,6 +131,7 @@ const ( NamespaceGlobalDiscounts NamespaceUserDiscounts NamespaceMarketLastVersion + NamespaceCollateral ) func (k Keeper) Logger(ctx sdk.Context) log.Logger { diff --git a/x/perp/v2/keeper/liquidate.go b/x/perp/v2/keeper/liquidate.go index 79b92c76ec..25290ec095 100644 --- a/x/perp/v2/keeper/liquidate.go +++ b/x/perp/v2/keeper/liquidate.go @@ -291,10 +291,13 @@ func (k Keeper) executeFullLiquidation( ecosystemFundFeeAmount = remainMargin } - quoteDenom := market.Pair.QuoteDenom() + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return sdk.Coin{}, sdk.Coin{}, err + } - liquidatorfee = sdk.NewCoin(quoteDenom, liquidatorFeeAmount.RoundInt()) - ecosystemFundFee = sdk.NewCoin(quoteDenom, ecosystemFundFeeAmount.RoundInt()) + liquidatorfee = sdk.NewCoin(collateral, liquidatorFeeAmount.RoundInt()) + ecosystemFundFee = sdk.NewCoin(collateral, ecosystemFundFeeAmount.RoundInt()) err = k.distributeLiquidateRewards( ctx, @@ -311,17 +314,17 @@ func (k Keeper) executeFullLiquidation( PositionChangedEvent: types.PositionChangedEvent{ FinalPosition: positionResp.Position, PositionNotional: positionResp.PositionNotional, - TransactionFee: sdk.NewCoin(position.Pair.QuoteDenom(), sdk.ZeroInt()), // no transaction fee for liquidation + TransactionFee: sdk.NewCoin(collateral, sdk.ZeroInt()), // no transaction fee for liquidation RealizedPnl: positionResp.RealizedPnl, - BadDebt: sdk.NewCoin(position.Pair.QuoteDenom(), totalBadDebt.RoundInt()), + BadDebt: sdk.NewCoin(collateral, totalBadDebt.RoundInt()), FundingPayment: positionResp.FundingPayment, BlockHeight: ctx.BlockHeight(), MarginToUser: sdk.ZeroInt(), // no margin to user for full liquidation ChangeReason: types.ChangeReason_FullLiquidation, }, LiquidatorAddress: liquidator.String(), - FeeToLiquidator: sdk.NewCoin(position.Pair.QuoteDenom(), liquidatorFeeAmount.RoundInt()), - FeeToEcosystemFund: sdk.NewCoin(position.Pair.QuoteDenom(), ecosystemFundFeeAmount.RoundInt()), + FeeToLiquidator: sdk.NewCoin(collateral, liquidatorFeeAmount.RoundInt()), + FeeToEcosystemFund: sdk.NewCoin(collateral, ecosystemFundFeeAmount.RoundInt()), }) return liquidatorfee, ecosystemFundFee, err @@ -370,9 +373,14 @@ func (k Keeper) executePartialLiquidation( feeToLiquidator := liquidationFeeAmount.QuoInt64(2) feeToPerpEcosystemFund := liquidationFeeAmount.Sub(feeToLiquidator) + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return sdk.Coin{}, sdk.Coin{}, err + } + err = k.distributeLiquidateRewards(ctx, market, liquidator, - sdk.NewCoin(market.Pair.QuoteDenom(), feeToPerpEcosystemFund.RoundInt()), - sdk.NewCoin(market.Pair.QuoteDenom(), feeToLiquidator.RoundInt()), + sdk.NewCoin(collateral, feeToPerpEcosystemFund.RoundInt()), + sdk.NewCoin(collateral, feeToLiquidator.RoundInt()), ) if err != nil { return sdk.Coin{}, sdk.Coin{}, err @@ -382,17 +390,17 @@ func (k Keeper) executePartialLiquidation( PositionChangedEvent: types.PositionChangedEvent{ FinalPosition: positionResp.Position, PositionNotional: positionResp.PositionNotional, - TransactionFee: sdk.NewCoin(position.Pair.QuoteDenom(), sdk.ZeroInt()), // no transaction fee for liquidation + TransactionFee: sdk.NewCoin(collateral, sdk.ZeroInt()), // no transaction fee for liquidation RealizedPnl: positionResp.RealizedPnl, - BadDebt: sdk.NewCoin(position.Pair.QuoteDenom(), sdk.ZeroInt()), // no bad debt for partial liquidation + BadDebt: sdk.NewCoin(collateral, sdk.ZeroInt()), // no bad debt for partial liquidation FundingPayment: positionResp.FundingPayment, BlockHeight: ctx.BlockHeight(), MarginToUser: sdk.ZeroInt(), // no margin to user for partial liquidation ChangeReason: types.ChangeReason_PartialLiquidation, }, LiquidatorAddress: liquidator.String(), - FeeToLiquidator: sdk.NewCoin(position.Pair.QuoteDenom(), feeToLiquidator.RoundInt()), - FeeToEcosystemFund: sdk.NewCoin(position.Pair.QuoteDenom(), feeToPerpEcosystemFund.RoundInt()), + FeeToLiquidator: sdk.NewCoin(collateral, feeToLiquidator.RoundInt()), + FeeToEcosystemFund: sdk.NewCoin(collateral, feeToPerpEcosystemFund.RoundInt()), }) return liquidatorFee, ecosystemFundFee, err diff --git a/x/perp/v2/keeper/liquidate_test.go b/x/perp/v2/keeper/liquidate_test.go index 0415e0ed8d..dc3ec4b6a8 100644 --- a/x/perp/v2/keeper/liquidate_test.go +++ b/x/perp/v2/keeper/liquidate_test.go @@ -37,7 +37,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10400))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -46,9 +46,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(750)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(125)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(125)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(750)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(125)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(125)), PositionShouldBeEqual(alice, pairBtcUsdc, Position_PositionShouldBeEqualTo( types.Position{ @@ -70,7 +70,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -80,9 +80,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(600)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(150)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(600)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(150)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), @@ -92,7 +92,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -101,9 +101,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(600)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(150)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(600)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(150)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), @@ -113,7 +113,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -123,9 +123,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(600)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(150)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(600)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(150)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), @@ -135,7 +135,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -145,9 +145,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(600)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(150)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(600)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(150)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), @@ -157,8 +157,8 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10800))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 50))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 50))), ). When( MoveToNextBlock(), @@ -167,9 +167,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(800)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(800)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), @@ -177,9 +177,9 @@ func TestMultiLiquidate(t *testing.T) { Given( SetBlockNumber(1), SetBlockTime(startTime), - CreateCustomMarket(pairBtcUsdc, WithPrepaidBadDebt(sdk.NewInt(50))), + CreateCustomMarket(pairBtcUsdc, WithPrepaidBadDebt(sdk.NewInt(50), types.TestingCollateralDenomNUSD)), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10800))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -188,11 +188,11 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(750)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(750)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), - MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.ZeroInt())), + MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.ZeroInt(), types.TestingCollateralDenomNUSD)), ), TC("healthy position"). @@ -201,7 +201,7 @@ func TestMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(100)), WithMargin(sdk.NewDec(10)), WithOpenNotional(sdk.NewDec(100))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 10))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 10))), ). When( MoveToNextBlock(), @@ -210,9 +210,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(10)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - BalanceEqual(liquidator, denoms.USDC, sdk.ZeroInt()), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(10)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), PositionShouldBeEqual(alice, pairBtcUsdc, Position_PositionShouldBeEqualTo( types.Position{ @@ -244,7 +244,7 @@ func TestMultiLiquidate(t *testing.T) { InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10400))), // partial InsertPosition(WithTrader(alice), WithPair(pairEthUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), // full InsertPosition(WithTrader(alice), WithPair(pairAtomUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10000))), // healthy - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 3000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 3000))), ). When( MoveToNextBlock(), @@ -257,9 +257,9 @@ func TestMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(2350)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(275)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(375)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(2350)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(275)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(375)), PositionShouldBeEqual(alice, pairBtcUsdc, Position_PositionShouldBeEqualTo( types.Position{ diff --git a/x/perp/v2/keeper/margin.go b/x/perp/v2/keeper/margin.go index a62bb9be12..64b0ad4ccb 100644 --- a/x/perp/v2/keeper/margin.go +++ b/x/perp/v2/keeper/margin.go @@ -24,6 +24,11 @@ import ( func (k Keeper) AddMargin( ctx sdk.Context, pair asset.Pair, traderAddr sdk.AccAddress, marginToAdd sdk.Coin, ) (res *types.MsgAddMarginResponse, err error) { + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return nil, err + } + market, err := k.GetMarket(ctx, pair) if err != nil { return nil, fmt.Errorf("%w: %s", types.ErrPairNotFound, pair) @@ -33,7 +38,7 @@ func (k Keeper) AddMargin( return nil, fmt.Errorf("%w: %s", types.ErrPairNotFound, pair) } - if marginToAdd.Denom != amm.Pair.QuoteDenom() { + if marginToAdd.Denom != collateral { return nil, fmt.Errorf("invalid margin denom: %s", marginToAdd.Denom) } @@ -73,9 +78,9 @@ func (k Keeper) AddMargin( &types.PositionChangedEvent{ FinalPosition: position, PositionNotional: positionNotional, - TransactionFee: sdk.NewCoin(pair.QuoteDenom(), sdk.ZeroInt()), // always zero when adding margin - RealizedPnl: sdk.ZeroDec(), // always zero when adding margin - BadDebt: sdk.NewCoin(pair.QuoteDenom(), sdk.ZeroInt()), // always zero when adding margin + TransactionFee: sdk.NewCoin(collateral, sdk.ZeroInt()), // always zero when adding margin + RealizedPnl: sdk.ZeroDec(), // always zero when adding margin + BadDebt: sdk.NewCoin(collateral, sdk.ZeroInt()), // always zero when adding margin FundingPayment: fundingPayment, BlockHeight: ctx.BlockHeight(), MarginToUser: marginToAdd.Amount.Neg(), @@ -113,6 +118,11 @@ ret: func (k Keeper) RemoveMargin( ctx sdk.Context, pair asset.Pair, traderAddr sdk.AccAddress, marginToRemove sdk.Coin, ) (res *types.MsgRemoveMarginResponse, err error) { + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return nil, err + } + // fetch objects from state market, err := k.GetMarket(ctx, pair) if err != nil { @@ -123,7 +133,7 @@ func (k Keeper) RemoveMargin( if err != nil { return nil, fmt.Errorf("%w: %s", types.ErrPairNotFound, pair) } - if marginToRemove.Denom != amm.Pair.QuoteDenom() { + if marginToRemove.Denom != collateral { return nil, fmt.Errorf("invalid margin denom: %s", marginToRemove.Denom) } @@ -178,9 +188,9 @@ func (k Keeper) RemoveMargin( &types.PositionChangedEvent{ FinalPosition: position, PositionNotional: spotNotional, - TransactionFee: sdk.NewCoin(pair.QuoteDenom(), sdk.ZeroInt()), // always zero when removing margin - RealizedPnl: sdk.ZeroDec(), // always zero when removing margin - BadDebt: sdk.NewCoin(pair.QuoteDenom(), sdk.ZeroInt()), // always zero when removing margin + TransactionFee: sdk.NewCoin(collateral, sdk.ZeroInt()), // always zero when removing margin + RealizedPnl: sdk.ZeroDec(), // always zero when removing margin + BadDebt: sdk.NewCoin(collateral, sdk.ZeroInt()), // always zero when removing margin FundingPayment: fundingPayment, BlockHeight: ctx.BlockHeight(), MarginToUser: marginToRemove.Amount, diff --git a/x/perp/v2/keeper/margin_test.go b/x/perp/v2/keeper/margin_test.go index cc545eda36..db99d8e659 100644 --- a/x/perp/v2/keeper/margin_test.go +++ b/x/perp/v2/keeper/margin_test.go @@ -30,7 +30,7 @@ func TestAddMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(2020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2020)))), MarketOrder(alice, pairBtcUsdc, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -61,18 +61,18 @@ func TestAddMargin(t *testing.T) { }, PositionNotional: sdk.NewDec(10_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), BlockHeight: 2, MarginToUser: sdk.NewInt(-1_000), ChangeReason: types.ChangeReason_AddMargin, ExchangedNotional: sdk.MustNewDecFromStr("0"), ExchangedSize: sdk.MustNewDecFromStr("0"), }), - BalanceEqual(alice, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(10)), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.NewInt(10)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(10)), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(10)), ), TC("existing short position, add margin"). @@ -80,7 +80,7 @@ func TestAddMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(2020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(2020)))), MarketOrder(alice, pairBtcUsdc, types.Direction_SHORT, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -111,18 +111,18 @@ func TestAddMargin(t *testing.T) { }, PositionNotional: sdk.NewDec(10_000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), BlockHeight: 2, MarginToUser: sdk.NewInt(-1000), ChangeReason: types.ChangeReason_AddMargin, ExchangedNotional: sdk.MustNewDecFromStr("0"), ExchangedSize: sdk.MustNewDecFromStr("0"), }), - BalanceEqual(alice, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(10)), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.NewInt(10)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(10)), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(10)), ), TC("Testing fails"). @@ -132,7 +132,7 @@ func TestAddMargin(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1020)))), MarketOrder(alice, pairBtcUsdc, types.Direction_LONG, sdk.NewInt(1000), sdk.NewDec(10), sdk.ZeroDec()), ). When( @@ -162,7 +162,7 @@ func TestRemoveMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1002)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1002)))), MarketOrder(alice, pairBtcUsdc, types.Direction_LONG, sdk.NewInt(1000), sdk.OneDec(), sdk.ZeroDec()), ). When( @@ -191,18 +191,18 @@ func TestRemoveMargin(t *testing.T) { }, PositionNotional: sdk.NewDec(1000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), BlockHeight: 2, MarginToUser: sdk.NewInt(500), ChangeReason: types.ChangeReason_RemoveMargin, ExchangedNotional: sdk.MustNewDecFromStr("0"), ExchangedSize: sdk.MustNewDecFromStr("0"), }), - BalanceEqual(alice, denoms.USDC, sdk.NewInt(500)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.OneInt()), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.OneInt()), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(500)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), ), TC("existing long position, remove almost all margin fails"). @@ -210,7 +210,7 @@ func TestRemoveMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1002)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1002)))), MarketOrder(alice, pairBtcUsdc, types.Direction_LONG, sdk.NewInt(1000), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -227,9 +227,9 @@ func TestRemoveMargin(t *testing.T) { LatestCumulativePremiumFraction: sdk.ZeroDec(), LastUpdatedBlockNumber: 1, })), - BalanceEqual(alice, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.OneInt()), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.OneInt()), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), ), TC("existing short position, remove margin"). @@ -237,7 +237,7 @@ func TestRemoveMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1002)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1002)))), MarketOrder(alice, pairBtcUsdc, types.Direction_SHORT, sdk.NewInt(1000), sdk.OneDec(), sdk.ZeroDec()), ). When( @@ -266,18 +266,18 @@ func TestRemoveMargin(t *testing.T) { }, PositionNotional: sdk.NewDec(1000), RealizedPnl: sdk.ZeroDec(), - BadDebt: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + BadDebt: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), FundingPayment: sdk.ZeroDec(), - TransactionFee: sdk.NewCoin(denoms.USDC, sdk.ZeroInt()), + TransactionFee: sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.ZeroInt()), BlockHeight: 2, MarginToUser: sdk.NewInt(500), ChangeReason: types.ChangeReason_RemoveMargin, ExchangedNotional: sdk.MustNewDecFromStr("0"), ExchangedSize: sdk.MustNewDecFromStr("0"), }), - BalanceEqual(alice, denoms.USDC, sdk.NewInt(500)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.OneInt()), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.OneInt()), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(500)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), ), TC("existing short position, remove almost all margin fails"). @@ -285,7 +285,7 @@ func TestRemoveMargin(t *testing.T) { CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), SetBlockNumber(1), SetBlockTime(startBlockTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1002)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1002)))), MarketOrder(alice, pairBtcUsdc, types.Direction_SHORT, sdk.NewInt(1000), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -302,9 +302,9 @@ func TestRemoveMargin(t *testing.T) { LatestCumulativePremiumFraction: sdk.ZeroDec(), LastUpdatedBlockNumber: 1, })), - BalanceEqual(alice, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.OneInt()), - ModuleBalanceEqual(types.FeePoolModuleAccount, denoms.USDC, sdk.OneInt()), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), + ModuleBalanceEqual(types.FeePoolModuleAccount, types.TestingCollateralDenomNUSD, sdk.OneInt()), ), } diff --git a/x/perp/v2/keeper/msg_server.go b/x/perp/v2/keeper/msg_server.go index efa5a38f33..c8ed657bd9 100644 --- a/x/perp/v2/keeper/msg_server.go +++ b/x/perp/v2/keeper/msg_server.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/NibiruChain/nibiru/x/common" types "github.com/NibiruChain/nibiru/x/perp/v2/types" ) @@ -138,3 +139,21 @@ func (m msgServer) DonateToEcosystemFund(ctx context.Context, msg *types.MsgDona return &types.MsgDonateToEcosystemFundResponse{}, nil } + +// ChangeCollateralDenom: Updates the collateral denom. A denom is valid if it is +// possible to make an sdk.Coin using it. [Admin] Only callable by sudoers. +func (m msgServer) ChangeCollateralDenom( + goCtx context.Context, txMsg *types.MsgChangeCollateralDenom, +) (resp *types.MsgChangeCollateralDenomResponse, err error) { + if txMsg == nil { + return resp, common.ErrNilMsg() + } + if err := txMsg.ValidateBasic(); err != nil { + return resp, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + err = m.k.Admin.ChangeCollateralDenom(ctx, txMsg.NewDenom, txMsg.GetSigners()[0]) + + return &types.MsgChangeCollateralDenomResponse{}, err +} diff --git a/x/perp/v2/keeper/msg_server_test.go b/x/perp/v2/keeper/msg_server_test.go index 0c6e8377ac..8b135765ab 100644 --- a/x/perp/v2/keeper/msg_server_test.go +++ b/x/perp/v2/keeper/msg_server_test.go @@ -27,7 +27,7 @@ func TestMsgServerMarketOrder(t *testing.T) { TC("open long position"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), ). When( MsgServerMarketOrder(alice, pair, types.Direction_LONG, sdk.OneInt(), sdk.OneDec(), sdk.ZeroInt()), @@ -44,13 +44,13 @@ func TestMsgServerMarketOrder(t *testing.T) { LastUpdatedBlockNumber: 1, }), ), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(99)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(99)), ), TC("open short position"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), ). When( MsgServerMarketOrder(alice, pair, types.Direction_SHORT, sdk.OneInt(), sdk.OneDec(), sdk.ZeroInt()), @@ -67,7 +67,7 @@ func TestMsgServerMarketOrder(t *testing.T) { LastUpdatedBlockNumber: 1, }), ), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(99)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(99)), ), } @@ -82,7 +82,7 @@ func TestMsgServerClosePosition(t *testing.T) { TC("close long position"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), MarketOrder(alice, pair, types.Direction_LONG, sdk.OneInt(), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -91,13 +91,13 @@ func TestMsgServerClosePosition(t *testing.T) { ). Then( PositionShouldNotExist(alice, pair, 1), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(100)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(100)), ), TC("close short position"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), MarketOrder(alice, pair, types.Direction_LONG, sdk.OneInt(), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -106,7 +106,7 @@ func TestMsgServerClosePosition(t *testing.T) { ). Then( PositionShouldNotExist(alice, pair, 1), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(100)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(100)), ), } @@ -121,7 +121,7 @@ func TestMsgServerAddMargin(t *testing.T) { TC("add margin"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), MarketOrder(alice, pair, types.Direction_LONG, sdk.OneInt(), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -140,12 +140,12 @@ func TestMsgServerAddMargin(t *testing.T) { LastUpdatedBlockNumber: 2, }), ), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(98)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(98)), ), TC("partial close"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), MarketOrder(alice, pair, types.Direction_LONG, sdk.OneInt(), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -164,7 +164,7 @@ func TestMsgServerAddMargin(t *testing.T) { LastUpdatedBlockNumber: 2, }), ), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(98)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(98)), ), } @@ -179,7 +179,7 @@ func TestMsgServerRemoveMargin(t *testing.T) { TC("add margin"). Given( CreateCustomMarket(pair, WithEnabled(true)), - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), MarketOrder(alice, pair, types.Direction_LONG, sdk.NewInt(2), sdk.OneDec(), sdk.ZeroDec()), MoveToNextBlock(), ). @@ -198,7 +198,7 @@ func TestMsgServerRemoveMargin(t *testing.T) { LastUpdatedBlockNumber: 2, }), ), - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(99)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(99)), ), } @@ -211,14 +211,15 @@ func TestMsgServerDonateToPerpEf(t *testing.T) { tests := TestCases{ TC("success"). Given( - FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(denoms.NUSD, 100))), + SetCollateral(types.TestingCollateralDenomNUSD), + FundAccount(alice, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 100))), ). When( MsgServerDonateToPerpEf(alice, sdk.NewInt(50)), ). Then( - BalanceEqual(alice, denoms.NUSD, sdk.NewInt(50)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.NUSD, sdk.NewInt(50)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(50)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(50)), ), } @@ -238,7 +239,7 @@ func TestMsgServerMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10400))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -247,9 +248,9 @@ func TestMsgServerMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(750)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(125)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(125)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(750)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(125)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(125)), PositionShouldBeEqual(alice, pairBtcUsdc, Position_PositionShouldBeEqualTo( types.Position{ @@ -271,7 +272,7 @@ func TestMsgServerMultiLiquidate(t *testing.T) { SetBlockTime(startTime), CreateCustomMarket(pairBtcUsdc, WithEnabled(true)), InsertPosition(WithTrader(alice), WithPair(pairBtcUsdc), WithSize(sdk.NewDec(10000)), WithMargin(sdk.NewDec(1000)), WithOpenNotional(sdk.NewDec(10600))), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(denoms.USDC, 1000))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(types.TestingCollateralDenomNUSD, 1000))), ). When( MoveToNextBlock(), @@ -280,9 +281,9 @@ func TestMsgServerMultiLiquidate(t *testing.T) { ), ). Then( - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.NewInt(600)), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.NewInt(150)), - BalanceEqual(liquidator, denoms.USDC, sdk.NewInt(250)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(600)), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.NewInt(150)), + BalanceEqual(liquidator, types.TestingCollateralDenomNUSD, sdk.NewInt(250)), PositionShouldNotExist(alice, pairBtcUsdc, 1), ), } @@ -294,10 +295,12 @@ func TestFailMsgServer(t *testing.T) { pair := asset.Registry.Pair(denoms.BTC, denoms.NUSD) app, ctx := testapp.NewNibiruTestAppAndContext() + sender := testutil.AccAddress().String() + msgServer := keeper.NewMsgServerImpl(app.PerpKeeperV2) _, err := msgServer.MarketOrder(ctx, &types.MsgMarketOrder{ - Sender: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Sender: sender, Pair: pair, Side: types.Direction_LONG, QuoteAssetAmount: sdk.OneInt(), @@ -307,31 +310,31 @@ func TestFailMsgServer(t *testing.T) { require.ErrorContains(t, err, "pair ubtc:unusd not found") _, err = msgServer.ClosePosition(ctx, &types.MsgClosePosition{ - Sender: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Sender: sender, Pair: pair, }) require.ErrorContains(t, err, types.ErrPairNotFound.Error()) _, err = msgServer.PartialClose(ctx, &types.MsgPartialClose{ - Sender: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Sender: sender, Pair: pair, Size_: sdk.OneDec(), }) require.ErrorContains(t, err, types.ErrPairNotFound.Error()) _, err = msgServer.MultiLiquidate(ctx, &types.MsgMultiLiquidate{ - Sender: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Sender: sender, Liquidations: []*types.MsgMultiLiquidate_Liquidation{ { Pair: pair, - Trader: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Trader: sender, }, }, }) require.ErrorContains(t, err, types.ErrPairNotFound.Error()) _, err = msgServer.DonateToEcosystemFund(ctx, &types.MsgDonateToEcosystemFund{ - Sender: "cosmos1zaavvzxez0elundtn32qnk9lkm8kmcszzsv80v", + Sender: sender, Donation: sdk.NewCoin("luna", sdk.OneInt()), }) require.ErrorContains(t, err, "spendable balance is smaller than 1luna") diff --git a/x/perp/v2/keeper/settlement_test.go b/x/perp/v2/keeper/settlement_test.go index 74b7484575..2da09148df 100644 --- a/x/perp/v2/keeper/settlement_test.go +++ b/x/perp/v2/keeper/settlement_test.go @@ -33,7 +33,7 @@ func TestSettlePosition(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), MarketOrder( alice, pairBtcUsdc, @@ -58,8 +58,8 @@ func TestSettlePosition(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(104)))), // need 4 because we need to pay for the close position fee - FundAccount(bob, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(1_020)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(104)))), // need 4 because we need to pay for the close position fee + FundAccount(bob, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1_020)))), MarketOrder( alice, pairBtcUsdc, @@ -114,8 +114,8 @@ func TestSettlePosition(t *testing.T) { PositionShouldNotExist(alice, pairBtcUsdc, 1), PositionShouldNotExist(bob, pairBtcUsdc, 1), SetBlockNumber(2), - BalanceEqual(alice, "unusd", sdk.NewInt(0)), - BalanceEqual(bob, "unusd", sdk.NewInt(1101-20)), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(0)), + BalanceEqual(bob, types.TestingCollateralDenomNUSD, sdk.NewInt(1101-20)), ), TC("Error: can't settle on enabled market").When( @@ -127,7 +127,7 @@ func TestSettlePosition(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(10_200)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(10_200)))), MarketOrder( alice, pairBtcUsdc, @@ -150,7 +150,7 @@ func TestSettlePosition(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_400)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_400)))), MarketOrder( alice, pairBtcUsdc, @@ -196,7 +196,7 @@ func TestSettlePosition(t *testing.T) { ), SetBlockNumber(1), SetBlockTime(startTime), - FundAccount(alice, sdk.NewCoins(sdk.NewCoin(denoms.NUSD, sdk.NewInt(20_400)))), + FundAccount(alice, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(20_400)))), MarketOrder( alice, pairBtcUsdc, diff --git a/x/perp/v2/keeper/withdraw.go b/x/perp/v2/keeper/withdraw.go index 7d12a4465d..f39f4ab713 100644 --- a/x/perp/v2/keeper/withdraw.go +++ b/x/perp/v2/keeper/withdraw.go @@ -40,10 +40,15 @@ func (k Keeper) WithdrawFromVault( return nil } + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return err + } + vaultQuoteBalance := k.BankKeeper.GetBalance( ctx, k.AccountKeeper.GetModuleAddress(types.VaultModuleAccount), - market.Pair.QuoteDenom(), + collateral, ) if vaultQuoteBalance.Amount.LT(amountToWithdraw) { // if withdraw amount is larger than entire balance of vault @@ -60,7 +65,7 @@ func (k Keeper) WithdrawFromVault( types.PerpEFModuleAccount, types.VaultModuleAccount, sdk.NewCoins( - sdk.NewCoin(market.Pair.QuoteDenom(), shortage), + sdk.NewCoin(collateral, shortage), ), ); err != nil { return err @@ -73,7 +78,7 @@ func (k Keeper) WithdrawFromVault( /* from */ types.VaultModuleAccount, /* to */ receiver, sdk.NewCoins( - sdk.NewCoin(market.Pair.QuoteDenom(), amountToWithdraw), + sdk.NewCoin(collateral, amountToWithdraw), ), ) } @@ -114,12 +119,17 @@ func (k Keeper) realizeBadDebt(ctx sdk.Context, market types.Market, badDebtToRe // badDebtToRealize > prepaidBadDebtBalance k.ZeroPrepaidBadDebt(ctx, market) + collateral, err := k.Collateral.Get(ctx) + if err != nil { + return err + } + return k.BankKeeper.SendCoinsFromModuleToModule(ctx, /*from=*/ types.PerpEFModuleAccount, /*to=*/ types.VaultModuleAccount, sdk.NewCoins( sdk.NewCoin( - market.Pair.QuoteDenom(), + collateral, badDebtToRealize.Sub(market.PrepaidBadDebt.Amount), ), ), diff --git a/x/perp/v2/keeper/withdraw_test.go b/x/perp/v2/keeper/withdraw_test.go index 5f0d60a7fe..5415c6b5c1 100644 --- a/x/perp/v2/keeper/withdraw_test.go +++ b/x/perp/v2/keeper/withdraw_test.go @@ -27,15 +27,15 @@ func TestWithdrawFromVault(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), CreateCustomMarket(pairBtcUsdc), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1000)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1000)))), ). When( WithdrawFromVault(pairBtcUsdc, alice, sdk.NewInt(1000)), ). Then( - BalanceEqual(alice, denoms.USDC, sdk.NewInt(1000)), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.ZeroInt()), - MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.ZeroInt())), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(1000)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.ZeroInt(), types.TestingCollateralDenomNUSD)), ), TC("successful withdraw, some bad debt"). @@ -43,17 +43,17 @@ func TestWithdrawFromVault(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), CreateCustomMarket(pairBtcUsdc), - FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(500)))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(500)))), + FundModule(types.VaultModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(500)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(500)))), ). When( WithdrawFromVault(pairBtcUsdc, alice, sdk.NewInt(1000)), ). Then( - BalanceEqual(alice, denoms.USDC, sdk.NewInt(1000)), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(500))), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(1000)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(500), types.TestingCollateralDenomNUSD)), ), TC("successful withdraw, all bad debt"). @@ -61,33 +61,33 @@ func TestWithdrawFromVault(t *testing.T) { SetBlockNumber(1), SetBlockTime(startBlockTime), CreateCustomMarket(pairBtcUsdc), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1000)))), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1000)))), ). When( WithdrawFromVault(pairBtcUsdc, alice, sdk.NewInt(1000)), ). Then( - BalanceEqual(alice, denoms.USDC, sdk.NewInt(1000)), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(1000))), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(1000)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(1000), types.TestingCollateralDenomNUSD)), ), TC("successful withdraw, existing bad debt"). Given( SetBlockNumber(1), SetBlockTime(startBlockTime), - CreateCustomMarket(pairBtcUsdc, WithPrepaidBadDebt(sdk.NewInt(1000))), - FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(denoms.USDC, sdk.NewInt(1000)))), + CreateCustomMarket(pairBtcUsdc, WithPrepaidBadDebt(sdk.NewInt(1000), types.TestingCollateralDenomNUSD)), + FundModule(types.PerpEFModuleAccount, sdk.NewCoins(sdk.NewCoin(types.TestingCollateralDenomNUSD, sdk.NewInt(1000)))), ). When( WithdrawFromVault(pairBtcUsdc, alice, sdk.NewInt(1000)), ). Then( - BalanceEqual(alice, denoms.USDC, sdk.NewInt(1000)), - ModuleBalanceEqual(types.VaultModuleAccount, denoms.USDC, sdk.ZeroInt()), - ModuleBalanceEqual(types.PerpEFModuleAccount, denoms.USDC, sdk.ZeroInt()), - MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(2000))), + BalanceEqual(alice, types.TestingCollateralDenomNUSD, sdk.NewInt(1000)), + ModuleBalanceEqual(types.VaultModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + ModuleBalanceEqual(types.PerpEFModuleAccount, types.TestingCollateralDenomNUSD, sdk.ZeroInt()), + MarketShouldBeEqual(pairBtcUsdc, Market_PrepaidBadDebtShouldBeEqualTo(sdk.NewInt(2000), types.TestingCollateralDenomNUSD)), ), } diff --git a/x/perp/v2/module/genesis.go b/x/perp/v2/module/genesis.go index a884058a05..b22b5e9350 100644 --- a/x/perp/v2/module/genesis.go +++ b/x/perp/v2/module/genesis.go @@ -70,6 +70,13 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) customDiscount.Discount.Fee, ) } + + if genState.CollateralDenom != "" { + err := k.Admin.UnsafeChangeCollateralDenom(ctx, genState.CollateralDenom) + if err != nil { + panic(err) + } + } } // ExportGenesis returns the capability module's exported genesis. @@ -134,5 +141,11 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { }, }) } + + collateral, err := k.Collateral.Get(ctx) + if err != nil { + panic(err) + } + genesis.CollateralDenom = collateral return genesis } diff --git a/x/perp/v2/module/genesis_test.go b/x/perp/v2/module/genesis_test.go index d2092f218f..08425f5a27 100644 --- a/x/perp/v2/module/genesis_test.go +++ b/x/perp/v2/module/genesis_test.go @@ -11,6 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/common/asset" "github.com/NibiruChain/nibiru/x/common/denoms" "github.com/NibiruChain/nibiru/x/common/testutil" @@ -18,6 +19,7 @@ import ( "github.com/NibiruChain/nibiru/x/common/testutil/testapp" perp "github.com/NibiruChain/nibiru/x/perp/v2/module" types "github.com/NibiruChain/nibiru/x/perp/v2/types" + sudotypes "github.com/NibiruChain/nibiru/x/sudo/types" ) type TestCase struct { @@ -25,7 +27,12 @@ type TestCase struct { positions []types.Position } +func init() { + testapp.EnsureNibiruPrefix() +} + func TestGenesis(t *testing.T) { + testapp.EnsureNibiruPrefix() testCases := []TestCase{ { name: "empty positions genesis", @@ -61,13 +68,31 @@ func TestGenesis(t *testing.T) { } } +func PerpSudoers() sudotypes.Sudoers { + _, addrs := testutil.PrivKeyAddressPairs(2) + return sudotypes.Sudoers{ + Root: addrs[0].String(), + Contracts: []string{addrs[1].String()}, + } +} + func RunTestGenesis(t *testing.T, tc TestCase) { + testapp.EnsureNibiruPrefix() app, ctxUncached := testapp.NewNibiruTestAppAndContext() ctx, _ := ctxUncached.CacheContext() pair := asset.Registry.Pair(denoms.BTC, denoms.NUSD) + // Initialize sudo state + nibiruTeam := common.NibiruTeam + sudoers := PerpSudoers() + sudoersRoot := sdk.MustAccAddressFromBech32(nibiruTeam) + sudoers.Root = sudoersRoot.String() + app.SudoKeeper.Sudoers.Set(ctx, sudoers) + // create some params + require.NoError(t, app.PerpKeeperV2.Admin.ChangeCollateralDenom( + ctx, "unusd", sudoersRoot)) app.PerpKeeperV2.SaveMarket(ctx, *mock.TestMarket()) app.PerpKeeperV2.MarketLastVersion.Insert(ctx, pair, types.MarketLastVersion{Version: 1}) app.PerpKeeperV2.SaveAMM(ctx, *mock.TestAMMDefault()) @@ -118,6 +143,7 @@ func RunTestGenesis(t *testing.T, tc TestCase) { require.Equal(t, genState.CustomDiscounts, genStateAfterInit.CustomDiscounts) require.Equal(t, genState.GlobalDiscount, genStateAfterInit.GlobalDiscount) require.Equal(t, genState.TraderVolumes, genStateAfterInit.TraderVolumes) + require.Equal(t, genState.CollateralDenom, genStateAfterInit.CollateralDenom) } func TestNewAppModuleBasic(t *testing.T) { diff --git a/x/perp/v2/types/codec.go b/x/perp/v2/types/codec.go index 4a77025b1d..b35212a01c 100644 --- a/x/perp/v2/types/codec.go +++ b/x/perp/v2/types/codec.go @@ -15,6 +15,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgPartialClose{}, "perpv2/partial_close", nil) cdc.RegisterConcrete(&MsgDonateToEcosystemFund{}, "perpv2/donate_to_ef", nil) cdc.RegisterConcrete(&MsgMultiLiquidate{}, "perpv2/multi_liquidate", nil) + cdc.RegisterConcrete(&MsgChangeCollateralDenom{}, "perpv2/change_collateral_denom", nil) } func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { @@ -27,6 +28,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgClosePosition{}, &MsgPartialClose{}, &MsgMultiLiquidate{}, + &MsgChangeCollateralDenom{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/perp/v2/types/collateral.go b/x/perp/v2/types/collateral.go new file mode 100644 index 0000000000..8b6eb32969 --- /dev/null +++ b/x/perp/v2/types/collateral.go @@ -0,0 +1,11 @@ +package types + +import ( + tftypes "github.com/NibiruChain/nibiru/x/tokenfactory/types" +) + +// TestingCollateralDenomNUSD: For testing only +var TestingCollateralDenomNUSD string = tftypes.TFDenom{ + Creator: "nibi14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9ssa9gcs", + Subdenom: "unusd", +}.String() diff --git a/x/perp/v2/types/errors.go b/x/perp/v2/types/errors.go index 48dfe0bda7..4c49842fc7 100644 --- a/x/perp/v2/types/errors.go +++ b/x/perp/v2/types/errors.go @@ -46,5 +46,7 @@ var ( ErrNilSwapInvariant = sdkerrors.Register(ModuleName, 28, "swap multiplier must be not nil") ErrNotEnoughFundToPayAction = sdkerrors.Register(ModuleName, 29, "not enough fund in perp EF to pay for action") - ErrSettlementPositionMarketEnabled = sdkerrors.Register(ModuleName, 32, "market is enabled, you can only settle position on disabled market") + ErrSettlementPositionMarketEnabled = sdkerrors.Register(ModuleName, 32, "market is enabled, you can only settle position on disabled market") + ErrCollateralTokenFactoryDenomNotSet = sdkerrors.Register(ModuleName, 36, "no collateral denom set for the perp keeper") + ErrInvalidCollateral = sdkerrors.Register(ModuleName, 37, "invalid collateral denom") ) diff --git a/x/perp/v2/types/expected_keepers.go b/x/perp/v2/types/expected_keepers.go index 19aa6b590e..38df68b352 100644 --- a/x/perp/v2/types/expected_keepers.go +++ b/x/perp/v2/types/expected_keepers.go @@ -48,3 +48,10 @@ type EpochKeeper interface { // GetEpochInfo returns epoch info by identifier. GetEpochInfo(ctx sdk.Context, identifier string) (types.EpochInfo, error) } + +type SudoKeeper interface { + // CheckPermissions Checks if a contract is contained within the set of sudo + // contracts defined in the x/sudo module. These smart contracts are able to + // execute certain permissioned functions. + CheckPermissions(contract sdk.AccAddress, ctx sdk.Context) error +} diff --git a/x/perp/v2/types/genesis.go b/x/perp/v2/types/genesis.go index ae9628a9d2..6ad3e75e6f 100644 --- a/x/perp/v2/types/genesis.go +++ b/x/perp/v2/types/genesis.go @@ -60,7 +60,7 @@ func DefaultMarket(pair asset.Pair) Market { FundingRateEpochId: epochstypes.ThirtyMinuteEpochID, MaxFundingRate: sdk.NewDec(1), TwapLookbackWindow: time.Minute * 30, - PrepaidBadDebt: sdk.NewCoin(pair.QuoteDenom(), sdk.ZeroInt()), + PrepaidBadDebt: sdk.NewCoin(TestingCollateralDenomNUSD, sdk.ZeroInt()), MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"), MaxLeverage: sdk.NewDec(10), } diff --git a/x/perp/v2/types/genesis.pb.go b/x/perp/v2/types/genesis.pb.go index aacf854cca..b46ab116eb 100644 --- a/x/perp/v2/types/genesis.pb.go +++ b/x/perp/v2/types/genesis.pb.go @@ -31,11 +31,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Thge genesis state is used not only to start the network but also useful for // exporting and importing state during network upgrades. type GenesisState struct { - Markets []Market `protobuf:"bytes,2,rep,name=markets,proto3" json:"markets"` - Amms []AMM `protobuf:"bytes,3,rep,name=amms,proto3" json:"amms"` - Positions []GenesisPosition `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions"` - ReserveSnapshots []ReserveSnapshot `protobuf:"bytes,5,rep,name=reserve_snapshots,json=reserveSnapshots,proto3" json:"reserve_snapshots"` - DnrEpoch uint64 `protobuf:"varint,6,opt,name=dnr_epoch,json=dnrEpoch,proto3" json:"dnr_epoch,omitempty"` + Markets []Market `protobuf:"bytes,2,rep,name=markets,proto3" json:"markets"` + Amms []AMM `protobuf:"bytes,3,rep,name=amms,proto3" json:"amms"` + Positions []GenesisPosition `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions"` + ReserveSnapshots []ReserveSnapshot `protobuf:"bytes,5,rep,name=reserve_snapshots,json=reserveSnapshots,proto3" json:"reserve_snapshots"` + DnrEpoch uint64 `protobuf:"varint,6,opt,name=dnr_epoch,json=dnrEpoch,proto3" json:"dnr_epoch,omitempty"` + // For testing purposes, we allow the collateral to be set at genesis + CollateralDenom string `protobuf:"bytes,11,opt,name=collateral_denom,json=collateralDenom,proto3" json:"collateral_denom,omitempty"` TraderVolumes []GenesisState_TraderVolume `protobuf:"bytes,7,rep,name=trader_volumes,json=traderVolumes,proto3" json:"trader_volumes"` GlobalDiscount []GenesisState_Discount `protobuf:"bytes,8,rep,name=global_discount,json=globalDiscount,proto3" json:"global_discount"` CustomDiscounts []GenesisState_CustomDiscount `protobuf:"bytes,9,rep,name=custom_discounts,json=customDiscounts,proto3" json:"custom_discounts"` @@ -110,6 +112,13 @@ func (m *GenesisState) GetDnrEpoch() uint64 { return 0 } +func (m *GenesisState) GetCollateralDenom() string { + if m != nil { + return m.CollateralDenom + } + return "" +} + func (m *GenesisState) GetTraderVolumes() []GenesisState_TraderVolume { if m != nil { return m.TraderVolumes @@ -393,50 +402,51 @@ func init() { func init() { proto.RegisterFile("nibiru/perp/v2/genesis.proto", fileDescriptor_c2c7acfef3993fde) } var fileDescriptor_c2c7acfef3993fde = []byte{ - // 678 bytes of a gzipped FileDescriptorProto + // 700 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xdf, 0x6a, 0x13, 0x4d, - 0x14, 0xcf, 0x36, 0x69, 0x9a, 0x4c, 0xfb, 0xa5, 0xfd, 0xc6, 0x52, 0x96, 0x58, 0xd2, 0x52, 0x50, - 0x22, 0xd2, 0x1d, 0x1a, 0x41, 0xd0, 0x2b, 0x9b, 0x56, 0x8b, 0x60, 0xa4, 0x6c, 0x4b, 0x2f, 0x44, - 0x88, 0x93, 0xcd, 0xb8, 0x59, 0x9a, 0x9d, 0x59, 0xe6, 0x4c, 0x82, 0x5e, 0xeb, 0x03, 0x78, 0xe1, - 0x23, 0xf8, 0x0c, 0x3e, 0x43, 0x2f, 0x7b, 0x29, 0x5e, 0x14, 0x69, 0x5f, 0x44, 0x76, 0x66, 0x12, - 0x93, 0xc5, 0x54, 0x45, 0xf0, 0x2a, 0x99, 0x39, 0xbf, 0x3f, 0x67, 0xce, 0x39, 0x7b, 0xd0, 0x3a, - 0x8f, 0x3a, 0x91, 0x1c, 0x90, 0x84, 0xc9, 0x84, 0x0c, 0x1b, 0x24, 0x64, 0x9c, 0x41, 0x04, 0x5e, - 0x22, 0x85, 0x12, 0xb8, 0x62, 0xa2, 0x5e, 0x1a, 0xf5, 0x86, 0x8d, 0xea, 0x6a, 0x28, 0x42, 0xa1, - 0x43, 0x24, 0xfd, 0x67, 0x50, 0xd5, 0xf5, 0x50, 0x88, 0xb0, 0xcf, 0x08, 0x4d, 0x22, 0x42, 0x39, - 0x17, 0x8a, 0xaa, 0x48, 0x70, 0xab, 0x51, 0xad, 0x05, 0x02, 0x62, 0x01, 0xa4, 0x43, 0x81, 0x91, - 0xe1, 0x4e, 0x87, 0x29, 0xba, 0x43, 0x02, 0x11, 0x71, 0x1b, 0xaf, 0x66, 0x32, 0x00, 0x45, 0x15, - 0x33, 0xb1, 0xad, 0x4f, 0x25, 0xb4, 0x74, 0x60, 0x32, 0x3a, 0x4a, 0xaf, 0xf1, 0x7d, 0xb4, 0x10, - 0x53, 0x79, 0xca, 0x14, 0xb8, 0x73, 0x9b, 0xf9, 0xfa, 0x62, 0x63, 0xcd, 0x9b, 0x4e, 0xd1, 0x6b, - 0xe9, 0x70, 0xb3, 0x70, 0x76, 0xb1, 0x91, 0xf3, 0x47, 0x60, 0xbc, 0x8d, 0x0a, 0x34, 0x8e, 0xc1, - 0xcd, 0x6b, 0xd2, 0x8d, 0x2c, 0x69, 0xb7, 0xd5, 0xb2, 0x0c, 0x0d, 0xc3, 0x7b, 0xa8, 0x9c, 0x08, - 0x88, 0xf4, 0x33, 0xdc, 0x82, 0xe6, 0x6c, 0x64, 0x39, 0x36, 0xaf, 0x43, 0x8b, 0xb3, 0xfc, 0x1f, - 0x3c, 0xec, 0xa3, 0xff, 0x25, 0x03, 0x26, 0x87, 0xac, 0x0d, 0x9c, 0x26, 0xd0, 0x13, 0x0a, 0xdc, - 0xf9, 0x9f, 0x8b, 0xf9, 0x06, 0x78, 0x64, 0x71, 0x56, 0x6c, 0x45, 0x4e, 0x5f, 0x03, 0xbe, 0x89, - 0xca, 0x5d, 0x2e, 0xdb, 0x2c, 0x11, 0x41, 0xcf, 0x2d, 0x6e, 0x3a, 0xf5, 0x82, 0x5f, 0xea, 0x72, - 0xf9, 0x38, 0x3d, 0xe3, 0x13, 0x54, 0x51, 0x92, 0x76, 0x99, 0x6c, 0x0f, 0x45, 0x7f, 0x10, 0x33, - 0x70, 0x17, 0xb4, 0xdb, 0x9d, 0x19, 0xa9, 0xeb, 0x92, 0x7a, 0xc7, 0x9a, 0x72, 0xa2, 0x19, 0xd6, - 0xf7, 0x3f, 0x35, 0x71, 0x07, 0xf8, 0x18, 0x2d, 0x87, 0x7d, 0xd1, 0xa1, 0xfd, 0x76, 0x37, 0x82, - 0x40, 0x0c, 0xb8, 0x72, 0x4b, 0x5a, 0xf8, 0xd6, 0xb5, 0xc2, 0xfb, 0x16, 0x6c, 0x45, 0x2b, 0x46, - 0x63, 0x74, 0x8b, 0x5f, 0xa2, 0x95, 0x60, 0x00, 0x4a, 0xc4, 0x63, 0x55, 0x70, 0xcb, 0x5a, 0xf6, - 0xee, 0xb5, 0xb2, 0x7b, 0x9a, 0x94, 0x11, 0x5f, 0x0e, 0xa6, 0x6e, 0x01, 0xbf, 0x42, 0xab, 0xa6, - 0xf7, 0xed, 0x3e, 0x05, 0xd5, 0x1e, 0x32, 0x09, 0xba, 0x99, 0x48, 0x3b, 0xd4, 0x67, 0x38, 0x98, - 0xe1, 0x79, 0x46, 0x41, 0x9d, 0x18, 0x82, 0x95, 0xc7, 0x71, 0x36, 0x00, 0xd5, 0xf7, 0x0e, 0x5a, - 0x9a, 0xac, 0x1d, 0x5e, 0x43, 0x45, 0x53, 0x37, 0xd7, 0xd9, 0x74, 0xea, 0x65, 0xdf, 0x9e, 0xf0, - 0x2a, 0x9a, 0x37, 0xfd, 0x9a, 0xd3, 0xfd, 0x32, 0x07, 0xfc, 0x04, 0x15, 0x4d, 0x97, 0xdc, 0x7c, - 0x8a, 0x6e, 0x7a, 0xa9, 0xd1, 0xd7, 0x8b, 0x8d, 0xdb, 0x61, 0xa4, 0x7a, 0x83, 0x8e, 0x17, 0x88, - 0x98, 0xd8, 0x2f, 0xc7, 0xfc, 0x6c, 0x43, 0xf7, 0x94, 0xa8, 0xb7, 0x09, 0x03, 0xef, 0x29, 0x57, - 0xbe, 0x65, 0x57, 0x3f, 0x3a, 0xa8, 0x34, 0xae, 0xe9, 0x23, 0x94, 0x7f, 0xcd, 0x98, 0xf1, 0xff, - 0x23, 0xc5, 0x7d, 0x16, 0xf8, 0x29, 0x75, 0x22, 0xad, 0xb9, 0xbf, 0x4a, 0xeb, 0x14, 0x55, 0xa6, - 0x1b, 0x35, 0xb3, 0x3c, 0xbb, 0xa8, 0x34, 0x1e, 0xab, 0xd4, 0xf3, 0x77, 0xc7, 0xca, 0x1f, 0xd3, - 0xb6, 0xde, 0x39, 0xc8, 0x9d, 0xd5, 0x41, 0xdc, 0x42, 0x85, 0x84, 0x46, 0xd6, 0xb5, 0xf9, 0xc0, - 0xbe, 0x67, 0x67, 0xe2, 0x3d, 0xcf, 0xb5, 0xdb, 0x5e, 0x8f, 0x46, 0x9c, 0xd8, 0x65, 0xf4, 0x86, - 0x04, 0x22, 0x8e, 0x05, 0x27, 0x14, 0x80, 0x29, 0xef, 0x90, 0x46, 0xd2, 0xd7, 0x32, 0xd8, 0x45, - 0x0b, 0x76, 0x98, 0x6c, 0x3f, 0x47, 0xc7, 0xad, 0xcf, 0x0e, 0x5a, 0xce, 0x2c, 0x85, 0x7f, 0x66, - 0x8e, 0x1f, 0xa2, 0xd2, 0x68, 0xf3, 0xe8, 0x81, 0x5a, 0x6c, 0xb8, 0xd9, 0x2a, 0x66, 0x36, 0xd5, - 0x18, 0xdf, 0x3c, 0x38, 0xbb, 0xac, 0x39, 0xe7, 0x97, 0x35, 0xe7, 0xdb, 0x65, 0xcd, 0xf9, 0x70, - 0x55, 0xcb, 0x9d, 0x5f, 0xd5, 0x72, 0x5f, 0xae, 0x6a, 0xb9, 0x17, 0xdb, 0xbf, 0x4a, 0x74, 0xb4, - 0xb4, 0xf5, 0x00, 0x74, 0x8a, 0x7a, 0x6b, 0xdf, 0xfb, 0x1e, 0x00, 0x00, 0xff, 0xff, 0x86, 0x40, - 0x11, 0x89, 0x55, 0x06, 0x00, 0x00, + 0x14, 0xcf, 0x36, 0x69, 0x9a, 0x4c, 0xfb, 0x25, 0xfd, 0xc6, 0x52, 0x96, 0x58, 0xd2, 0x52, 0x50, + 0x52, 0xa4, 0x3b, 0x34, 0x82, 0xa0, 0x57, 0x36, 0xad, 0x16, 0xc1, 0x48, 0xd9, 0x96, 0x5e, 0x88, + 0x10, 0x27, 0x9b, 0x31, 0x59, 0x9a, 0x9d, 0x59, 0xe6, 0x4c, 0x82, 0x5e, 0xeb, 0x03, 0x78, 0xe1, + 0xb3, 0xf8, 0x0c, 0xbd, 0xb3, 0x97, 0xe2, 0x45, 0x91, 0xf6, 0x45, 0x64, 0x67, 0x26, 0x69, 0xb2, + 0x98, 0xaa, 0x08, 0x5e, 0x65, 0xe7, 0xcc, 0xf9, 0xfd, 0x99, 0x73, 0x4e, 0x0e, 0x5a, 0xe3, 0x61, + 0x3b, 0x94, 0x03, 0x12, 0x33, 0x19, 0x93, 0x61, 0x9d, 0x74, 0x19, 0x67, 0x10, 0x82, 0x17, 0x4b, + 0xa1, 0x04, 0x2e, 0x99, 0x5b, 0x2f, 0xb9, 0xf5, 0x86, 0xf5, 0x4a, 0x35, 0x10, 0x10, 0x09, 0x20, + 0x6d, 0x0a, 0x8c, 0x0c, 0x77, 0xda, 0x4c, 0xd1, 0x1d, 0x12, 0x88, 0x90, 0x9b, 0xfc, 0xca, 0x5a, + 0x57, 0x88, 0x6e, 0x9f, 0x11, 0x1a, 0x87, 0x84, 0x72, 0x2e, 0x14, 0x55, 0xa1, 0xe0, 0x96, 0xad, + 0xb2, 0xd2, 0x15, 0x5d, 0xa1, 0x3f, 0x49, 0xf2, 0x65, 0xa3, 0x95, 0x94, 0x03, 0x50, 0x54, 0x31, + 0x73, 0xb7, 0xf9, 0xa5, 0x80, 0x96, 0x0e, 0x8c, 0xa3, 0xa3, 0x24, 0x8c, 0x1f, 0xa0, 0x85, 0x88, + 0xca, 0x53, 0xa6, 0xc0, 0x9d, 0xdb, 0xc8, 0xd6, 0x16, 0xeb, 0xab, 0xde, 0xb4, 0x45, 0xaf, 0xa9, + 0xaf, 0x1b, 0xb9, 0xb3, 0x8b, 0xf5, 0x8c, 0x3f, 0x4a, 0xc6, 0xdb, 0x28, 0x47, 0xa3, 0x08, 0xdc, + 0xac, 0x06, 0xdd, 0x4a, 0x83, 0x76, 0x9b, 0x4d, 0x8b, 0xd0, 0x69, 0x78, 0x0f, 0x15, 0x63, 0x01, + 0xa1, 0x36, 0xef, 0xe6, 0x34, 0x66, 0x3d, 0x8d, 0xb1, 0xbe, 0x0e, 0x6d, 0x9e, 0xc5, 0x5f, 0xe3, + 0xb0, 0x8f, 0xfe, 0x97, 0x0c, 0x98, 0x1c, 0xb2, 0x16, 0x70, 0x1a, 0x43, 0x4f, 0x28, 0x70, 0xe7, + 0x7f, 0x4e, 0xe6, 0x9b, 0xc4, 0x23, 0x9b, 0x67, 0xc9, 0x96, 0xe5, 0x74, 0x18, 0xf0, 0x6d, 0x54, + 0xec, 0x70, 0xd9, 0x62, 0xb1, 0x08, 0x7a, 0x6e, 0x7e, 0xc3, 0xa9, 0xe5, 0xfc, 0x42, 0x87, 0xcb, + 0x27, 0xc9, 0x19, 0x6f, 0xa1, 0xe5, 0x40, 0xf4, 0xfb, 0x54, 0x31, 0x49, 0xfb, 0xad, 0x0e, 0xe3, + 0x22, 0x72, 0x17, 0x37, 0x9c, 0x5a, 0xd1, 0x2f, 0x5f, 0xc7, 0xf7, 0x93, 0x30, 0x3e, 0x41, 0x25, + 0x25, 0x69, 0x87, 0xc9, 0xd6, 0x50, 0xf4, 0x07, 0x11, 0x03, 0x77, 0x41, 0x1b, 0xdb, 0x9a, 0xf1, + 0x4a, 0x5d, 0x7d, 0xef, 0x58, 0x43, 0x4e, 0x34, 0xc2, 0x5a, 0xfc, 0x4f, 0x4d, 0xc4, 0x00, 0x1f, + 0xa3, 0x72, 0xb7, 0x2f, 0xda, 0x89, 0x7c, 0x08, 0x81, 0x18, 0x70, 0xe5, 0x16, 0x34, 0xf1, 0x9d, + 0x1b, 0x89, 0xf7, 0x6d, 0xb2, 0x25, 0x2d, 0x19, 0x8e, 0x51, 0x14, 0xbf, 0x42, 0xcb, 0xc1, 0x00, + 0x94, 0x88, 0xc6, 0xac, 0xe0, 0x16, 0x35, 0xed, 0xbd, 0x1b, 0x69, 0xf7, 0x34, 0x28, 0x45, 0x5e, + 0x0e, 0xa6, 0xa2, 0x80, 0x5f, 0xa3, 0x15, 0x33, 0x26, 0xad, 0x3e, 0x05, 0xd5, 0x1a, 0x32, 0x09, + 0xba, 0xef, 0x48, 0x2b, 0xd4, 0x66, 0x28, 0x98, 0x39, 0x7b, 0x4e, 0x41, 0x9d, 0x18, 0x80, 0xa5, + 0xc7, 0x51, 0xfa, 0x02, 0x2a, 0x1f, 0x1c, 0xb4, 0x34, 0x59, 0x3b, 0xbc, 0x8a, 0xf2, 0xa6, 0x6e, + 0xae, 0xa3, 0xfb, 0x63, 0x4f, 0x78, 0x05, 0xcd, 0x9b, 0xd6, 0xce, 0xe9, 0xd6, 0x9a, 0x03, 0x7e, + 0x8a, 0xf2, 0xa6, 0x4b, 0x6e, 0x36, 0xc9, 0x6e, 0x78, 0x89, 0xd0, 0xb7, 0x8b, 0xf5, 0xbb, 0xdd, + 0x50, 0xf5, 0x06, 0x6d, 0x2f, 0x10, 0x11, 0xb1, 0x7f, 0x4c, 0xf3, 0xb3, 0x0d, 0x9d, 0x53, 0xa2, + 0xde, 0xc5, 0x0c, 0xbc, 0x67, 0x5c, 0xf9, 0x16, 0x5d, 0xf9, 0xe4, 0xa0, 0xc2, 0xb8, 0xa6, 0x8f, + 0x51, 0xf6, 0x0d, 0x63, 0x46, 0xff, 0x8f, 0x18, 0xf7, 0x59, 0xe0, 0x27, 0xd0, 0x09, 0x5b, 0x73, + 0x7f, 0x65, 0xeb, 0x14, 0x95, 0xa6, 0x1b, 0x35, 0xb3, 0x3c, 0xbb, 0xa8, 0x30, 0x1e, 0xab, 0x44, + 0xf3, 0x77, 0xc7, 0xca, 0x1f, 0xc3, 0x36, 0xdf, 0x3b, 0xc8, 0x9d, 0xd5, 0x41, 0xdc, 0x44, 0xb9, + 0x98, 0x86, 0x56, 0xb5, 0xf1, 0xd0, 0xbe, 0x67, 0x67, 0xe2, 0x3d, 0x2f, 0xb4, 0xda, 0x5e, 0x8f, + 0x86, 0x9c, 0xd8, 0xbd, 0xf5, 0x96, 0x04, 0x22, 0x8a, 0x04, 0x27, 0x14, 0x80, 0x29, 0xef, 0x90, + 0x86, 0xd2, 0xd7, 0x34, 0xd8, 0x45, 0x0b, 0x76, 0x98, 0x6c, 0x3f, 0x47, 0xc7, 0xcd, 0xcf, 0x0e, + 0x2a, 0xa7, 0xf6, 0xc7, 0x3f, 0x13, 0xc7, 0x8f, 0x50, 0x61, 0xb4, 0xa4, 0xf4, 0x40, 0x2d, 0xd6, + 0xdd, 0x74, 0x15, 0x53, 0x4b, 0x6d, 0x9c, 0xdf, 0x38, 0x38, 0xbb, 0xac, 0x3a, 0xe7, 0x97, 0x55, + 0xe7, 0xfb, 0x65, 0xd5, 0xf9, 0x78, 0x55, 0xcd, 0x9c, 0x5f, 0x55, 0x33, 0x5f, 0xaf, 0xaa, 0x99, + 0x97, 0xdb, 0xbf, 0x32, 0x3a, 0xda, 0xef, 0x7a, 0x00, 0xda, 0x79, 0xbd, 0xe0, 0xef, 0xff, 0x08, + 0x00, 0x00, 0xff, 0xff, 0xa2, 0xa1, 0x80, 0x9e, 0x80, 0x06, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -459,6 +469,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CollateralDenom) > 0 { + i -= len(m.CollateralDenom) + copy(dAtA[i:], m.CollateralDenom) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.CollateralDenom))) + i-- + dAtA[i] = 0x5a + } if len(m.MarketLastVersions) > 0 { for iNdEx := len(m.MarketLastVersions) - 1; iNdEx >= 0; iNdEx-- { { @@ -863,6 +880,10 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + l = len(m.CollateralDenom) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -1270,6 +1291,38 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CollateralDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CollateralDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/perp/v2/types/genesis_test.go b/x/perp/v2/types/genesis_test.go index eac7b28107..5cb52191b1 100644 --- a/x/perp/v2/types/genesis_test.go +++ b/x/perp/v2/types/genesis_test.go @@ -25,6 +25,7 @@ func TestDefaultGenesis(t *testing.T) { require.Empty(t, genesis.Amms) require.Empty(t, genesis.Positions) require.Empty(t, genesis.ReserveSnapshots) + require.Empty(t, genesis.CollateralDenom) } func TestGenesisValidate(t *testing.T) { diff --git a/x/perp/v2/types/market_test.go b/x/perp/v2/types/market_test.go index 506d0299de..c7fd66eeb1 100644 --- a/x/perp/v2/types/market_test.go +++ b/x/perp/v2/types/market_test.go @@ -138,7 +138,9 @@ func TestMarketEqual(t *testing.T) { requiredError: "expected market liquidation fee ratio", }, { - modifier: func(m Market) Market { return m.WithPrepaidBadDebt(sdk.NewCoin("ubtc", sdk.OneInt())) }, + modifier: func(m Market) Market { + return m.WithPrepaidBadDebt(sdk.NewCoin(TestingCollateralDenomNUSD, sdk.OneInt())) + }, requiredError: "expected market prepaid bad debt", }, { diff --git a/x/perp/v2/types/msgs.go b/x/perp/v2/types/msgs.go index 3378b0bc48..551ad0baac 100644 --- a/x/perp/v2/types/msgs.go +++ b/x/perp/v2/types/msgs.go @@ -38,10 +38,6 @@ func (m MsgRemoveMargin) ValidateBasic() error { return fmt.Errorf("margin must be positive, not: %v", m.Margin.Amount.String()) } - if m.Margin.Denom != m.Pair.QuoteDenom() { - return fmt.Errorf("invalid margin denom, expected %s, got %s", m.Pair.QuoteDenom(), m.Margin.Denom) - } - return nil } @@ -76,10 +72,6 @@ func (m MsgAddMargin) ValidateBasic() error { return fmt.Errorf("margin must be positive, not: %v", m.Margin.Amount.String()) } - if m.Margin.Denom != m.Pair.QuoteDenom() { - return fmt.Errorf("invalid margin denom, expected %s, got %s", m.Pair.QuoteDenom(), m.Margin.Denom) - } - return nil } @@ -282,3 +274,30 @@ func (m MsgPartialClose) GetSigners() []sdk.AccAddress { } return []sdk.AccAddress{signer} } + +// MsgChangeCollateralDenom + +func (m MsgChangeCollateralDenom) Route() string { return "perp" } +func (m MsgChangeCollateralDenom) Type() string { return "partial_close_msg" } + +func (m MsgChangeCollateralDenom) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Sender); err != nil { + return sdkerrors.Wrapf(errors.ErrInvalidAddress, "invalid sender address (%s)", err) + } + if err := sdk.ValidateDenom(m.NewDenom); err != nil { + return err + } + return nil +} + +func (m MsgChangeCollateralDenom) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgChangeCollateralDenom) GetSigners() []sdk.AccAddress { + signer, err := sdk.AccAddressFromBech32(m.Sender) + if err != nil { + panic(err) + } + return []sdk.AccAddress{signer} +} diff --git a/x/perp/v2/types/msgs_test.go b/x/perp/v2/types/msgs_test.go index 8a3a146fe3..083e5b1376 100644 --- a/x/perp/v2/types/msgs_test.go +++ b/x/perp/v2/types/msgs_test.go @@ -61,16 +61,6 @@ func TestMsgValidateBasic(t *testing.T) { true, "margin must be positive", }, - { - "Test MsgRemoveMargin: Invalid margin", - &MsgRemoveMargin{ - Sender: validSender, - Pair: validPair, - Margin: sdk.NewCoin("denom", sdk.OneInt()), - }, - true, - "invalid margin denom", - }, // MsgAddMargin test cases { @@ -113,16 +103,6 @@ func TestMsgValidateBasic(t *testing.T) { true, "margin must be positive", }, - { - "Test MsgAddMargin: Invalid margin", - &MsgAddMargin{ - Sender: validSender, - Pair: validPair, - Margin: sdk.NewCoin("denom", sdk.OneInt()), - }, - true, - "invalid margin denom", - }, // MsgMarketOrder test cases { "Test MsgMarketOrder: Valid input", diff --git a/x/perp/v2/types/tx.pb.go b/x/perp/v2/types/tx.pb.go index 77abdd52ca..31ed8fd93e 100644 --- a/x/perp/v2/types/tx.pb.go +++ b/x/perp/v2/types/tx.pb.go @@ -914,6 +914,96 @@ func (m *MsgDonateToEcosystemFundResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgDonateToEcosystemFundResponse proto.InternalMessageInfo +// MsgChangeCollateralDenom: Changes the collateral denom for the module. +// [Admin] Only callable by sudoers. +type MsgChangeCollateralDenom struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + NewDenom string `protobuf:"bytes,2,opt,name=new_denom,json=newDenom,proto3" json:"new_denom,omitempty"` +} + +func (m *MsgChangeCollateralDenom) Reset() { *m = MsgChangeCollateralDenom{} } +func (m *MsgChangeCollateralDenom) String() string { return proto.CompactTextString(m) } +func (*MsgChangeCollateralDenom) ProtoMessage() {} +func (*MsgChangeCollateralDenom) Descriptor() ([]byte, []int) { + return fileDescriptor_b95cda40bf0a0f91, []int{15} +} +func (m *MsgChangeCollateralDenom) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeCollateralDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeCollateralDenom.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgChangeCollateralDenom) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeCollateralDenom.Merge(m, src) +} +func (m *MsgChangeCollateralDenom) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeCollateralDenom) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeCollateralDenom.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeCollateralDenom proto.InternalMessageInfo + +func (m *MsgChangeCollateralDenom) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgChangeCollateralDenom) GetNewDenom() string { + if m != nil { + return m.NewDenom + } + return "" +} + +type MsgChangeCollateralDenomResponse struct { +} + +func (m *MsgChangeCollateralDenomResponse) Reset() { *m = MsgChangeCollateralDenomResponse{} } +func (m *MsgChangeCollateralDenomResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChangeCollateralDenomResponse) ProtoMessage() {} +func (*MsgChangeCollateralDenomResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_b95cda40bf0a0f91, []int{16} +} +func (m *MsgChangeCollateralDenomResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeCollateralDenomResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeCollateralDenomResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgChangeCollateralDenomResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeCollateralDenomResponse.Merge(m, src) +} +func (m *MsgChangeCollateralDenomResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeCollateralDenomResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeCollateralDenomResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeCollateralDenomResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgSettlePosition)(nil), "nibiru.perp.v2.MsgSettlePosition") proto.RegisterType((*MsgRemoveMargin)(nil), "nibiru.perp.v2.MsgRemoveMargin") @@ -932,90 +1022,95 @@ func init() { proto.RegisterType((*MsgPartialCloseResponse)(nil), "nibiru.perp.v2.MsgPartialCloseResponse") proto.RegisterType((*MsgDonateToEcosystemFund)(nil), "nibiru.perp.v2.MsgDonateToEcosystemFund") proto.RegisterType((*MsgDonateToEcosystemFundResponse)(nil), "nibiru.perp.v2.MsgDonateToEcosystemFundResponse") + proto.RegisterType((*MsgChangeCollateralDenom)(nil), "nibiru.perp.v2.MsgChangeCollateralDenom") + proto.RegisterType((*MsgChangeCollateralDenomResponse)(nil), "nibiru.perp.v2.MsgChangeCollateralDenomResponse") } func init() { proto.RegisterFile("nibiru/perp/v2/tx.proto", fileDescriptor_b95cda40bf0a0f91) } var fileDescriptor_b95cda40bf0a0f91 = []byte{ - // 1234 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0x4d, 0x6f, 0x1b, 0xc5, - 0x1b, 0xf7, 0xda, 0xae, 0x9b, 0x3c, 0x4e, 0x9d, 0x74, 0xfe, 0x69, 0xe2, 0x5a, 0x95, 0x93, 0xff, - 0x0a, 0x95, 0x70, 0xc8, 0x2e, 0x35, 0x48, 0x08, 0x24, 0x40, 0x49, 0x5f, 0x10, 0xa8, 0x6e, 0xdd, - 0x6d, 0xd5, 0xa2, 0x02, 0xda, 0x4e, 0xec, 0xf1, 0x66, 0xd4, 0xf5, 0x8c, 0xbb, 0x33, 0x6b, 0x35, - 0x3d, 0xf6, 0x13, 0x70, 0xe0, 0x2b, 0x70, 0x45, 0xe2, 0x00, 0x5c, 0xf8, 0x00, 0x3d, 0xf6, 0x88, - 0x38, 0x54, 0xa8, 0xb9, 0x70, 0xa5, 0xe2, 0x03, 0xa0, 0xd9, 0x37, 0xaf, 0xdd, 0x6d, 0x62, 0x9b, - 0x34, 0x12, 0x88, 0x93, 0x3d, 0xfb, 0x3c, 0xcf, 0xef, 0x79, 0x7f, 0xe6, 0x05, 0x56, 0x19, 0xdd, - 0xa1, 0x9e, 0x6f, 0xf6, 0x89, 0xd7, 0x37, 0x07, 0x0d, 0x53, 0x3e, 0x34, 0xfa, 0x1e, 0x97, 0x1c, - 0x55, 0x42, 0x82, 0xa1, 0x08, 0xc6, 0xa0, 0x51, 0x3b, 0xe7, 0x70, 0xee, 0xb8, 0xc4, 0xc4, 0x7d, - 0x6a, 0x62, 0xc6, 0xb8, 0xc4, 0x92, 0x72, 0x26, 0x42, 0xee, 0x5a, 0xbd, 0xcd, 0x45, 0x8f, 0x0b, - 0x73, 0x07, 0x0b, 0x62, 0x0e, 0x2e, 0xec, 0x10, 0x89, 0x2f, 0x98, 0x6d, 0x4e, 0x59, 0x44, 0x5f, - 0x76, 0xb8, 0xc3, 0x83, 0xbf, 0xa6, 0xfa, 0x17, 0x7d, 0xad, 0x8d, 0x29, 0x17, 0x12, 0x4b, 0x12, - 0xd2, 0xf4, 0x6f, 0x34, 0x38, 0xdd, 0x14, 0xce, 0x4d, 0x22, 0xa5, 0x4b, 0x5a, 0x5c, 0x50, 0xa5, - 0x0e, 0xad, 0x40, 0x49, 0x10, 0xd6, 0x21, 0x5e, 0x55, 0x5b, 0xd7, 0x36, 0xe6, 0xad, 0x68, 0x85, - 0x9a, 0x50, 0xec, 0x63, 0xea, 0x55, 0xf3, 0xea, 0xeb, 0xf6, 0xfb, 0x4f, 0x9e, 0xad, 0xe5, 0x7e, - 0x7d, 0xb6, 0x76, 0xc1, 0xa1, 0x72, 0xd7, 0xdf, 0x31, 0xda, 0xbc, 0x67, 0x5e, 0x0b, 0x54, 0x5d, - 0xdc, 0xc5, 0x94, 0x99, 0x91, 0xda, 0x87, 0x66, 0x9b, 0xf7, 0x7a, 0x9c, 0x99, 0x58, 0x08, 0x22, - 0x8d, 0x16, 0xa6, 0x9e, 0x15, 0xc0, 0xa0, 0x2a, 0x9c, 0x1c, 0x10, 0x4f, 0x50, 0xce, 0xaa, 0x85, - 0x75, 0x6d, 0xa3, 0x68, 0xc5, 0x4b, 0xfd, 0x7b, 0x0d, 0x16, 0x9b, 0xc2, 0xb1, 0x48, 0x8f, 0x0f, - 0x48, 0x13, 0x7b, 0x0e, 0x3d, 0x36, 0xa3, 0xde, 0x83, 0x52, 0x2f, 0x50, 0x18, 0xd8, 0x54, 0x6e, - 0x9c, 0x35, 0xc2, 0xa0, 0x1b, 0x2a, 0xe8, 0x46, 0x14, 0x74, 0xe3, 0x22, 0xa7, 0x6c, 0xbb, 0xa8, - 0x74, 0x59, 0x11, 0xbb, 0xfe, 0xbb, 0x06, 0xab, 0x63, 0x36, 0x5b, 0x44, 0xf4, 0x39, 0x13, 0x04, - 0x7d, 0x04, 0x10, 0x72, 0xd9, 0xdc, 0x97, 0x81, 0xfd, 0x13, 0x00, 0xcf, 0x87, 0x22, 0xd7, 0x7d, - 0x89, 0xee, 0xc0, 0x62, 0xd7, 0x67, 0x1d, 0xca, 0x1c, 0xbb, 0x8f, 0xf7, 0x7a, 0x84, 0xc9, 0xc8, - 0x5d, 0x23, 0x72, 0xf7, 0x7c, 0xca, 0xdd, 0xa8, 0x48, 0xc2, 0x9f, 0x4d, 0xd1, 0xb9, 0x6f, 0xca, - 0xbd, 0x3e, 0x11, 0xc6, 0x25, 0xd2, 0xb6, 0x2a, 0x11, 0x4c, 0x2b, 0x44, 0x41, 0xef, 0xc2, 0x5c, - 0x3f, 0xca, 0x7a, 0xe4, 0x6f, 0xd5, 0x18, 0x2d, 0x49, 0x23, 0xae, 0x0a, 0x2b, 0xe1, 0xd4, 0xbf, - 0xd3, 0x60, 0xa1, 0x29, 0x9c, 0xad, 0x4e, 0xe7, 0x1f, 0x92, 0x9b, 0x6f, 0x35, 0x58, 0x4e, 0x1b, - 0x9c, 0x24, 0x26, 0x23, 0xb0, 0xda, 0x91, 0x07, 0x36, 0x3f, 0x71, 0x60, 0xff, 0x0c, 0xdb, 0xb1, - 0xe9, 0xbb, 0x92, 0x5e, 0xa5, 0x0f, 0x7c, 0xda, 0xc1, 0x92, 0xbc, 0x32, 0xba, 0x37, 0x60, 0xc1, - 0x8d, 0x98, 0xd4, 0x90, 0xa8, 0xe6, 0xd7, 0x0b, 0x1b, 0xe5, 0xc6, 0xe6, 0xb8, 0x9e, 0x97, 0x00, - 0x8d, 0xab, 0x43, 0x29, 0x6b, 0x04, 0xa2, 0x26, 0xa1, 0x9c, 0x22, 0x26, 0xf9, 0xd3, 0x8e, 0x26, - 0x7f, 0x2b, 0x50, 0x92, 0x1e, 0x56, 0x8e, 0xe4, 0x43, 0x47, 0xc2, 0x95, 0xfe, 0x63, 0x01, 0xce, - 0xbe, 0x64, 0x65, 0x92, 0x23, 0x3c, 0xe6, 0xa6, 0x16, 0xb8, 0xf9, 0xe1, 0xa1, 0x6e, 0xc6, 0x00, - 0x23, 0xee, 0x46, 0xdf, 0xc6, 0xdc, 0xfe, 0x21, 0x0f, 0xff, 0xcb, 0xe0, 0x52, 0x13, 0x4a, 0xf8, - 0xed, 0x36, 0x11, 0x22, 0x08, 0xc1, 0x9c, 0x15, 0x2f, 0xd1, 0x32, 0x9c, 0x20, 0x9e, 0xc7, 0x63, - 0x4f, 0xc2, 0x05, 0xba, 0x02, 0x95, 0x18, 0x97, 0x7b, 0x76, 0x97, 0x90, 0xc9, 0x0a, 0x55, 0xb3, - 0x4e, 0x0d, 0xc5, 0xae, 0x10, 0x82, 0x3e, 0x86, 0xb2, 0x72, 0xcb, 0x26, 0xdd, 0x00, 0xa4, 0x38, - 0x19, 0xc8, 0xbc, 0x92, 0xb9, 0xdc, 0x55, 0x00, 0xc3, 0x48, 0x9f, 0x48, 0x47, 0x3a, 0x49, 0x68, - 0xe9, 0x48, 0x12, 0xaa, 0xff, 0x54, 0x80, 0x8a, 0x8a, 0x3b, 0xf6, 0xee, 0x13, 0x79, 0xdd, 0x53, - 0x1a, 0x8e, 0x69, 0x14, 0x6c, 0x42, 0x51, 0xd0, 0x4e, 0x18, 0xdf, 0x4a, 0xe3, 0xec, 0x78, 0x31, - 0x5c, 0xa2, 0x1e, 0x69, 0x07, 0xa9, 0x0c, 0xd8, 0xd0, 0x97, 0x80, 0x1e, 0xf8, 0x5c, 0x12, 0x3b, - 0x00, 0xb2, 0x71, 0x8f, 0xfb, 0x4c, 0x06, 0x71, 0x9d, 0xae, 0xd5, 0x3f, 0x65, 0xd2, 0x5a, 0x0a, - 0x90, 0xb6, 0x14, 0xd0, 0x56, 0x80, 0x83, 0x3e, 0x83, 0x39, 0x97, 0x0c, 0x88, 0x87, 0x1d, 0x12, - 0xc6, 0x7b, 0xea, 0xf1, 0x91, 0xc8, 0x23, 0x02, 0xab, 0x2a, 0xbf, 0x23, 0x86, 0xda, 0x2e, 0xed, - 0x51, 0x19, 0x25, 0x6d, 0x5a, 0x73, 0x97, 0x15, 0x5c, 0xca, 0xda, 0xab, 0x0a, 0x4b, 0xdf, 0x3f, - 0x01, 0x2b, 0xa3, 0x99, 0x4b, 0x8a, 0x3e, 0x3d, 0xba, 0xb4, 0x49, 0x47, 0x17, 0xda, 0x85, 0x2a, - 0x79, 0xd8, 0xde, 0xc5, 0xcc, 0x21, 0x1d, 0x9b, 0x71, 0xf5, 0x0d, 0xbb, 0xf6, 0x00, 0xbb, 0x3e, - 0x99, 0x71, 0xaf, 0x5a, 0x49, 0xf0, 0xae, 0x45, 0x70, 0xb7, 0x15, 0x1a, 0xea, 0xc2, 0xea, 0x50, - 0x53, 0xac, 0xdf, 0x16, 0xf4, 0x51, 0x58, 0x0d, 0xd3, 0x2b, 0x3a, 0x93, 0xc0, 0xc5, 0x7e, 0xdd, - 0xa4, 0x8f, 0x32, 0xf7, 0x86, 0xe2, 0x91, 0xec, 0x0d, 0x37, 0x60, 0xc1, 0x23, 0xd8, 0xa5, 0x8f, - 0x94, 0xfd, 0xcc, 0x9d, 0xb1, 0x64, 0xca, 0x31, 0x46, 0x8b, 0xb9, 0xe8, 0x1e, 0x2c, 0xfb, 0x2c, - 0x0d, 0x6a, 0xe3, 0xae, 0x24, 0xde, 0x0c, 0x25, 0xa3, 0xa0, 0xd1, 0x10, 0xab, 0xc5, 0xdc, 0x2d, - 0x85, 0x84, 0x6e, 0xc3, 0x62, 0x74, 0x84, 0x91, 0xdc, 0x1e, 0x60, 0xdf, 0x95, 0xd5, 0x93, 0x33, - 0x81, 0x9f, 0x0a, 0x61, 0x6e, 0xf1, 0xdb, 0x0a, 0x04, 0x7d, 0x01, 0xa7, 0x93, 0x1c, 0xc6, 0x65, - 0x53, 0x9d, 0x9b, 0x09, 0x79, 0x29, 0x06, 0x8a, 0xeb, 0x45, 0xdf, 0x83, 0xa5, 0xa6, 0x70, 0x2e, - 0xba, 0x5c, 0x1c, 0xf7, 0xe1, 0x56, 0x7f, 0x51, 0x80, 0xea, 0xb8, 0xee, 0xa4, 0xc5, 0x0e, 0x6a, - 0x16, 0xed, 0xb8, 0x9a, 0x25, 0xff, 0x9a, 0x9b, 0xa5, 0xf0, 0x5a, 0x9a, 0xa5, 0xf8, 0xf7, 0x9b, - 0xe5, 0x73, 0x58, 0x1a, 0x96, 0x72, 0x7a, 0x9b, 0x9c, 0xde, 0xd8, 0xb8, 0x96, 0x6f, 0x85, 0x07, - 0x99, 0x9f, 0xc3, 0x7b, 0x4b, 0x0b, 0x7b, 0x92, 0x62, 0x37, 0xc8, 0xfd, 0x71, 0x6d, 0x88, 0xdb, - 0x6a, 0x43, 0x9c, 0x79, 0x04, 0x06, 0xb2, 0xfa, 0x1f, 0x85, 0xe0, 0x0a, 0x93, 0x36, 0xff, 0xbf, - 0x92, 0xfd, 0x97, 0x97, 0xec, 0x63, 0x2d, 0x98, 0x53, 0x97, 0x38, 0xc3, 0x92, 0xdc, 0xe2, 0x97, - 0xdb, 0x5c, 0xec, 0x09, 0x49, 0x7a, 0x57, 0x7c, 0xd6, 0x79, 0x65, 0xed, 0x5e, 0x83, 0xb9, 0x8e, - 0x12, 0x18, 0xde, 0x6e, 0x0e, 0x38, 0x9c, 0xae, 0x2a, 0x0b, 0x5f, 0x3c, 0x5b, 0x5b, 0xdc, 0xc3, - 0x3d, 0xf7, 0x03, 0x3d, 0x16, 0xd4, 0xad, 0x04, 0x43, 0xd7, 0x61, 0xfd, 0x55, 0x36, 0xc4, 0x05, - 0xd8, 0x78, 0x5c, 0x82, 0x42, 0x53, 0x38, 0xe8, 0x2e, 0x2c, 0x8c, 0xbc, 0x0b, 0xac, 0x65, 0x5c, - 0x04, 0xd2, 0x0c, 0xb5, 0x37, 0x0f, 0x61, 0x88, 0x35, 0xe8, 0x39, 0x74, 0x03, 0xe6, 0x87, 0x97, - 0xda, 0x73, 0x19, 0x72, 0x09, 0xb5, 0xf6, 0xc6, 0x41, 0xd4, 0x14, 0xe4, 0x3d, 0xa8, 0x8c, 0x5d, - 0xe7, 0xfe, 0x7f, 0xe8, 0xcd, 0xa5, 0xf6, 0xd6, 0xc4, 0x97, 0x1b, 0x3d, 0x87, 0xee, 0x40, 0x39, - 0x7d, 0x00, 0xaf, 0x67, 0xc9, 0x0e, 0xe9, 0xb5, 0xf3, 0x07, 0xd3, 0x53, 0xc0, 0x5f, 0xc1, 0xa9, - 0xd1, 0xad, 0x73, 0x3d, 0x43, 0x74, 0x84, 0xa3, 0xb6, 0x71, 0x18, 0x47, 0x0a, 0xfe, 0x2e, 0x2c, - 0x8c, 0x0c, 0xca, 0xac, 0x44, 0xa6, 0x19, 0x32, 0x13, 0x99, 0x35, 0xab, 0xf4, 0x1c, 0xb2, 0xa1, - 0x32, 0xf6, 0xa6, 0x95, 0x15, 0xf5, 0x51, 0x96, 0xa9, 0x8c, 0xf7, 0xe1, 0x4c, 0x76, 0xcb, 0x64, - 0x81, 0x64, 0x72, 0xd6, 0xde, 0x9e, 0x94, 0x73, 0xa8, 0x76, 0xfb, 0x93, 0x27, 0xcf, 0xeb, 0xda, - 0xd3, 0xe7, 0x75, 0xed, 0xb7, 0xe7, 0x75, 0xed, 0xeb, 0xfd, 0x7a, 0xee, 0xe9, 0x7e, 0x3d, 0xf7, - 0xcb, 0x7e, 0x3d, 0x77, 0x77, 0xf3, 0xb0, 0x8d, 0x23, 0x79, 0x7b, 0x54, 0xa3, 0x60, 0xa7, 0x14, - 0xbc, 0xff, 0xbd, 0xf3, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x63, 0xdb, 0xdc, 0xe2, 0x9a, 0x14, - 0x00, 0x00, + // 1287 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcd, 0x6f, 0x1b, 0x45, + 0x14, 0xf7, 0xc6, 0x6e, 0x9a, 0xbc, 0xa4, 0x4e, 0x3a, 0xa4, 0x89, 0x6b, 0x2a, 0x27, 0xac, 0x50, + 0x09, 0x87, 0xec, 0xd2, 0x80, 0x84, 0x40, 0x02, 0x94, 0x8f, 0x16, 0x81, 0xea, 0x36, 0xdd, 0x56, + 0x2d, 0x2a, 0xa0, 0xed, 0xc4, 0x1e, 0x6f, 0x46, 0xdd, 0x9d, 0x71, 0x77, 0x66, 0xdd, 0xa6, 0x47, + 0xfe, 0x02, 0x0e, 0xfc, 0x0b, 0x5c, 0x91, 0x38, 0x00, 0x17, 0xfe, 0x80, 0x1e, 0x7b, 0x44, 0x1c, + 0x2a, 0x94, 0x5c, 0xb8, 0x52, 0x71, 0xe1, 0x86, 0x66, 0xbf, 0xbc, 0x76, 0x37, 0x89, 0x6d, 0xd2, + 0x48, 0x20, 0x4e, 0xf6, 0xec, 0x7b, 0xef, 0xf7, 0xbe, 0xdf, 0x7c, 0xc0, 0x02, 0xa3, 0xdb, 0xd4, + 0x0f, 0xcc, 0x36, 0xf1, 0xdb, 0x66, 0x67, 0xd5, 0x94, 0x8f, 0x8c, 0xb6, 0xcf, 0x25, 0x47, 0xe5, + 0x88, 0x60, 0x28, 0x82, 0xd1, 0x59, 0xad, 0x5e, 0x70, 0x38, 0x77, 0x5c, 0x62, 0xe2, 0x36, 0x35, + 0x31, 0x63, 0x5c, 0x62, 0x49, 0x39, 0x13, 0x11, 0x77, 0xb5, 0xd6, 0xe0, 0xc2, 0xe3, 0xc2, 0xdc, + 0xc6, 0x82, 0x98, 0x9d, 0x4b, 0xdb, 0x44, 0xe2, 0x4b, 0x66, 0x83, 0x53, 0x16, 0xd3, 0xe7, 0x1c, + 0xee, 0xf0, 0xf0, 0xaf, 0xa9, 0xfe, 0xc5, 0x5f, 0xab, 0x7d, 0xca, 0x85, 0xc4, 0x92, 0x44, 0x34, + 0xfd, 0x1b, 0x0d, 0xce, 0xd6, 0x85, 0x73, 0x93, 0x48, 0xe9, 0x92, 0x2d, 0x2e, 0xa8, 0x52, 0x87, + 0xe6, 0x61, 0x5c, 0x10, 0xd6, 0x24, 0x7e, 0x45, 0x5b, 0xd2, 0x96, 0x27, 0xad, 0x78, 0x85, 0xea, + 0x50, 0x6a, 0x63, 0xea, 0x57, 0xc6, 0xd4, 0xd7, 0xf5, 0xf7, 0x9e, 0x3c, 0x5b, 0x2c, 0xfc, 0xfa, + 0x6c, 0xf1, 0x92, 0x43, 0xe5, 0x4e, 0xb0, 0x6d, 0x34, 0xb8, 0x67, 0x5e, 0x0b, 0x55, 0x6d, 0xec, + 0x60, 0xca, 0xcc, 0x58, 0xed, 0x23, 0xb3, 0xc1, 0x3d, 0x8f, 0x33, 0x13, 0x0b, 0x41, 0xa4, 0xb1, + 0x85, 0xa9, 0x6f, 0x85, 0x30, 0xa8, 0x02, 0xa7, 0x3b, 0xc4, 0x17, 0x94, 0xb3, 0x4a, 0x71, 0x49, + 0x5b, 0x2e, 0x59, 0xc9, 0x52, 0xff, 0x5e, 0x83, 0x99, 0xba, 0x70, 0x2c, 0xe2, 0xf1, 0x0e, 0xa9, + 0x63, 0xdf, 0xa1, 0x27, 0x66, 0xd4, 0xbb, 0x30, 0xee, 0x85, 0x0a, 0x43, 0x9b, 0xa6, 0x56, 0xcf, + 0x1b, 0x51, 0xd0, 0x0d, 0x15, 0x74, 0x23, 0x0e, 0xba, 0xb1, 0xc1, 0x29, 0x5b, 0x2f, 0x29, 0x5d, + 0x56, 0xcc, 0xae, 0xff, 0xae, 0xc1, 0x42, 0x9f, 0xcd, 0x16, 0x11, 0x6d, 0xce, 0x04, 0x41, 0x1f, + 0x02, 0x44, 0x5c, 0x36, 0x0f, 0x64, 0x68, 0xff, 0x00, 0xc0, 0x93, 0x91, 0xc8, 0xf5, 0x40, 0xa2, + 0x3b, 0x30, 0xd3, 0x0a, 0x58, 0x93, 0x32, 0xc7, 0x6e, 0xe3, 0x5d, 0x8f, 0x30, 0x19, 0xbb, 0x6b, + 0xc4, 0xee, 0x5e, 0xcc, 0xb8, 0x1b, 0x17, 0x49, 0xf4, 0xb3, 0x22, 0x9a, 0xf7, 0x4d, 0xb9, 0xdb, + 0x26, 0xc2, 0xd8, 0x24, 0x0d, 0xab, 0x1c, 0xc3, 0x6c, 0x45, 0x28, 0xe8, 0x1d, 0x98, 0x68, 0xc7, + 0x59, 0x8f, 0xfd, 0xad, 0x18, 0xbd, 0x25, 0x69, 0x24, 0x55, 0x61, 0xa5, 0x9c, 0xfa, 0x77, 0x1a, + 0x4c, 0xd7, 0x85, 0xb3, 0xd6, 0x6c, 0xfe, 0x4b, 0x72, 0xf3, 0xad, 0x06, 0x73, 0x59, 0x83, 0xd3, + 0xc4, 0xe4, 0x04, 0x56, 0x3b, 0xf6, 0xc0, 0x8e, 0x0d, 0x1c, 0xd8, 0x3f, 0xa3, 0x76, 0xac, 0x07, + 0xae, 0xa4, 0x57, 0xe9, 0x83, 0x80, 0x36, 0xb1, 0x24, 0x07, 0x46, 0xf7, 0x06, 0x4c, 0xbb, 0x31, + 0x93, 0x1a, 0x12, 0x95, 0xb1, 0xa5, 0xe2, 0xf2, 0xd4, 0xea, 0x4a, 0xbf, 0x9e, 0x17, 0x00, 0x8d, + 0xab, 0x5d, 0x29, 0xab, 0x07, 0xa2, 0x2a, 0x61, 0x2a, 0x43, 0x4c, 0xf3, 0xa7, 0x1d, 0x4f, 0xfe, + 0xe6, 0x61, 0x5c, 0xfa, 0x58, 0x39, 0x32, 0x16, 0x39, 0x12, 0xad, 0xf4, 0x1f, 0x8b, 0x70, 0xfe, + 0x05, 0x2b, 0xd3, 0x1c, 0xe1, 0x3e, 0x37, 0xb5, 0xd0, 0xcd, 0x0f, 0x8e, 0x74, 0x33, 0x01, 0xe8, + 0x71, 0x37, 0xfe, 0xd6, 0xe7, 0xf6, 0x0f, 0x63, 0xf0, 0x4a, 0x0e, 0x97, 0x9a, 0x50, 0x22, 0x68, + 0x34, 0x88, 0x10, 0x61, 0x08, 0x26, 0xac, 0x64, 0x89, 0xe6, 0xe0, 0x14, 0xf1, 0x7d, 0x9e, 0x78, + 0x12, 0x2d, 0xd0, 0x15, 0x28, 0x27, 0xb8, 0xdc, 0xb7, 0x5b, 0x84, 0x0c, 0x56, 0xa8, 0x9a, 0x75, + 0xa6, 0x2b, 0x76, 0x85, 0x10, 0xf4, 0x11, 0x4c, 0x29, 0xb7, 0x6c, 0xd2, 0x0a, 0x41, 0x4a, 0x83, + 0x81, 0x4c, 0x2a, 0x99, 0xcb, 0x2d, 0x05, 0xd0, 0x8d, 0xf4, 0xa9, 0x6c, 0xa4, 0xd3, 0x84, 0x8e, + 0x1f, 0x4b, 0x42, 0xf5, 0x9f, 0x8a, 0x50, 0x56, 0x71, 0xc7, 0xfe, 0x7d, 0x22, 0xaf, 0xfb, 0x4a, + 0xc3, 0x09, 0x8d, 0x82, 0x15, 0x28, 0x09, 0xda, 0x8c, 0xe2, 0x5b, 0x5e, 0x3d, 0xdf, 0x5f, 0x0c, + 0x9b, 0xd4, 0x27, 0x8d, 0x30, 0x95, 0x21, 0x1b, 0xfa, 0x02, 0xd0, 0x83, 0x80, 0x4b, 0x62, 0x87, + 0x40, 0x36, 0xf6, 0x78, 0xc0, 0x64, 0x18, 0xd7, 0xe1, 0x5a, 0xfd, 0x13, 0x26, 0xad, 0xd9, 0x10, + 0x69, 0x4d, 0x01, 0xad, 0x85, 0x38, 0xe8, 0x53, 0x98, 0x70, 0x49, 0x87, 0xf8, 0xd8, 0x21, 0x51, + 0xbc, 0x87, 0x1e, 0x1f, 0xa9, 0x3c, 0x22, 0xb0, 0xa0, 0xf2, 0xdb, 0x63, 0xa8, 0xed, 0x52, 0x8f, + 0xca, 0x38, 0x69, 0xc3, 0x9a, 0x3b, 0xa7, 0xe0, 0x32, 0xd6, 0x5e, 0x55, 0x58, 0xfa, 0xfe, 0x29, + 0x98, 0xef, 0xcd, 0x5c, 0x5a, 0xf4, 0xd9, 0xd1, 0xa5, 0x0d, 0x3a, 0xba, 0xd0, 0x0e, 0x54, 0xc8, + 0xa3, 0xc6, 0x0e, 0x66, 0x0e, 0x69, 0xda, 0x8c, 0xab, 0x6f, 0xd8, 0xb5, 0x3b, 0xd8, 0x0d, 0xc8, + 0x88, 0x7b, 0xd5, 0x7c, 0x8a, 0x77, 0x2d, 0x86, 0xbb, 0xad, 0xd0, 0x50, 0x0b, 0x16, 0xba, 0x9a, + 0x12, 0xfd, 0xb6, 0xa0, 0x8f, 0xa3, 0x6a, 0x18, 0x5e, 0xd1, 0xb9, 0x14, 0x2e, 0xf1, 0xeb, 0x26, + 0x7d, 0x9c, 0xbb, 0x37, 0x94, 0x8e, 0x65, 0x6f, 0xb8, 0x01, 0xd3, 0x3e, 0xc1, 0x2e, 0x7d, 0xac, + 0xec, 0x67, 0xee, 0x88, 0x25, 0x33, 0x95, 0x60, 0x6c, 0x31, 0x17, 0xdd, 0x83, 0xb9, 0x80, 0x65, + 0x41, 0x6d, 0xdc, 0x92, 0xc4, 0x1f, 0xa1, 0x64, 0x14, 0x34, 0xea, 0x62, 0x6d, 0x31, 0x77, 0x4d, + 0x21, 0xa1, 0xdb, 0x30, 0x13, 0x1f, 0x61, 0x24, 0xb7, 0x3b, 0x38, 0x70, 0x65, 0xe5, 0xf4, 0x48, + 0xe0, 0x67, 0x22, 0x98, 0x5b, 0xfc, 0xb6, 0x02, 0x41, 0x9f, 0xc3, 0xd9, 0x34, 0x87, 0x49, 0xd9, + 0x54, 0x26, 0x46, 0x42, 0x9e, 0x4d, 0x80, 0x92, 0x7a, 0xd1, 0x77, 0x61, 0xb6, 0x2e, 0x9c, 0x0d, + 0x97, 0x8b, 0x93, 0x3e, 0xdc, 0xea, 0xcf, 0x8b, 0x50, 0xe9, 0xd7, 0x9d, 0xb6, 0xd8, 0x61, 0xcd, + 0xa2, 0x9d, 0x54, 0xb3, 0x8c, 0xbd, 0xe4, 0x66, 0x29, 0xbe, 0x94, 0x66, 0x29, 0xfd, 0xf3, 0x66, + 0xf9, 0x0c, 0x66, 0xbb, 0xa5, 0x9c, 0xdd, 0x26, 0x87, 0x37, 0x36, 0xa9, 0xe5, 0x5b, 0xd1, 0x41, + 0xe6, 0xe7, 0xe8, 0xde, 0xb2, 0x85, 0x7d, 0x49, 0xb1, 0x1b, 0xe6, 0xfe, 0xa4, 0x36, 0xc4, 0x75, + 0xb5, 0x21, 0x8e, 0x3c, 0x02, 0x43, 0x59, 0xfd, 0x8f, 0x62, 0x78, 0x85, 0xc9, 0x9a, 0xff, 0x7f, + 0xc9, 0xfe, 0xc7, 0x4b, 0xf6, 0x2b, 0x2d, 0x9c, 0x53, 0x9b, 0x9c, 0x61, 0x49, 0x6e, 0xf1, 0xcb, + 0x0d, 0x2e, 0x76, 0x85, 0x24, 0xde, 0x95, 0x80, 0x35, 0x0f, 0xac, 0xdd, 0x6b, 0x30, 0xd1, 0x54, + 0x02, 0xdd, 0xdb, 0xcd, 0x21, 0x87, 0xd3, 0x05, 0x65, 0xe1, 0xf3, 0x67, 0x8b, 0x33, 0xbb, 0xd8, + 0x73, 0xdf, 0xd7, 0x13, 0x41, 0xdd, 0x4a, 0x31, 0x74, 0x1d, 0x96, 0x0e, 0xb2, 0x21, 0x29, 0x40, + 0xfd, 0x7a, 0x34, 0x4f, 0xc3, 0x44, 0x6e, 0x70, 0xd7, 0xc5, 0x92, 0xf8, 0xd8, 0xdd, 0x24, 0x8c, + 0x7b, 0x07, 0xda, 0xf9, 0x2a, 0x4c, 0x32, 0xf2, 0xd0, 0x6e, 0x2a, 0xa6, 0xf8, 0xa4, 0x3e, 0xc1, + 0xc8, 0xc3, 0x50, 0x28, 0x56, 0x9a, 0x0b, 0x98, 0x28, 0x5d, 0xfd, 0x6b, 0x1c, 0x8a, 0x75, 0xe1, + 0xa0, 0xbb, 0x30, 0xdd, 0xf3, 0x18, 0xb1, 0x98, 0x73, 0xfb, 0xc8, 0x32, 0x54, 0xdf, 0x38, 0x82, + 0x21, 0x75, 0xab, 0x80, 0x6e, 0xc0, 0x64, 0xf7, 0x26, 0x7d, 0x21, 0x47, 0x2e, 0xa5, 0x56, 0x5f, + 0x3f, 0x8c, 0x9a, 0x81, 0xbc, 0x07, 0xe5, 0xbe, 0x3b, 0xe4, 0x6b, 0x47, 0x5e, 0x97, 0xaa, 0x6f, + 0x0e, 0x7c, 0xa3, 0xd2, 0x0b, 0xe8, 0x0e, 0x4c, 0x65, 0x4f, 0xfd, 0xb5, 0x3c, 0xd9, 0x2e, 0xbd, + 0x7a, 0xf1, 0x70, 0x7a, 0x06, 0xf8, 0x4b, 0x38, 0xd3, 0xbb, 0x5f, 0x2f, 0xe5, 0x88, 0xf6, 0x70, + 0x54, 0x97, 0x8f, 0xe2, 0xc8, 0xc0, 0xdf, 0x85, 0xe9, 0x9e, 0xe9, 0x9c, 0x97, 0xc8, 0x2c, 0x43, + 0x6e, 0x22, 0xf3, 0x06, 0xa4, 0x5e, 0x40, 0x36, 0x94, 0xfb, 0x1e, 0xd2, 0xf2, 0xa2, 0xde, 0xcb, + 0x32, 0x94, 0xf1, 0x01, 0x9c, 0xcb, 0xef, 0xd3, 0x3c, 0x90, 0x5c, 0xce, 0xea, 0x5b, 0x83, 0x72, + 0xf6, 0xaa, 0xcd, 0x6f, 0xbb, 0x5c, 0xdb, 0xf3, 0x38, 0x73, 0xd5, 0x1e, 0xda, 0x79, 0x7a, 0x61, + 0xfd, 0xe3, 0x27, 0x7b, 0x35, 0xed, 0xe9, 0x5e, 0x4d, 0xfb, 0x6d, 0xaf, 0xa6, 0x7d, 0xbd, 0x5f, + 0x2b, 0x3c, 0xdd, 0xaf, 0x15, 0x7e, 0xd9, 0xaf, 0x15, 0xee, 0xae, 0x1c, 0xb5, 0x49, 0xa6, 0xef, + 0xac, 0x6a, 0xec, 0x6d, 0x8f, 0x87, 0x6f, 0x9d, 0x6f, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x38, + 0x87, 0x87, 0xcc, 0x86, 0x15, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1038,6 +1133,7 @@ type MsgClient interface { PartialClose(ctx context.Context, in *MsgPartialClose, opts ...grpc.CallOption) (*MsgPartialCloseResponse, error) SettlePosition(ctx context.Context, in *MsgSettlePosition, opts ...grpc.CallOption) (*MsgClosePositionResponse, error) DonateToEcosystemFund(ctx context.Context, in *MsgDonateToEcosystemFund, opts ...grpc.CallOption) (*MsgDonateToEcosystemFundResponse, error) + ChangeCollateralDenom(ctx context.Context, in *MsgChangeCollateralDenom, opts ...grpc.CallOption) (*MsgChangeCollateralDenomResponse, error) } type msgClient struct { @@ -1120,6 +1216,15 @@ func (c *msgClient) DonateToEcosystemFund(ctx context.Context, in *MsgDonateToEc return out, nil } +func (c *msgClient) ChangeCollateralDenom(ctx context.Context, in *MsgChangeCollateralDenom, opts ...grpc.CallOption) (*MsgChangeCollateralDenomResponse, error) { + out := new(MsgChangeCollateralDenomResponse) + err := c.cc.Invoke(ctx, "/nibiru.perp.v2.Msg/ChangeCollateralDenom", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { RemoveMargin(context.Context, *MsgRemoveMargin) (*MsgRemoveMarginResponse, error) @@ -1130,6 +1235,7 @@ type MsgServer interface { PartialClose(context.Context, *MsgPartialClose) (*MsgPartialCloseResponse, error) SettlePosition(context.Context, *MsgSettlePosition) (*MsgClosePositionResponse, error) DonateToEcosystemFund(context.Context, *MsgDonateToEcosystemFund) (*MsgDonateToEcosystemFundResponse, error) + ChangeCollateralDenom(context.Context, *MsgChangeCollateralDenom) (*MsgChangeCollateralDenomResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1160,6 +1266,9 @@ func (*UnimplementedMsgServer) SettlePosition(ctx context.Context, req *MsgSettl func (*UnimplementedMsgServer) DonateToEcosystemFund(ctx context.Context, req *MsgDonateToEcosystemFund) (*MsgDonateToEcosystemFundResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DonateToEcosystemFund not implemented") } +func (*UnimplementedMsgServer) ChangeCollateralDenom(ctx context.Context, req *MsgChangeCollateralDenom) (*MsgChangeCollateralDenomResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeCollateralDenom not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -1309,6 +1418,24 @@ func _Msg_DonateToEcosystemFund_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _Msg_ChangeCollateralDenom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChangeCollateralDenom) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChangeCollateralDenom(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/nibiru.perp.v2.Msg/ChangeCollateralDenom", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChangeCollateralDenom(ctx, req.(*MsgChangeCollateralDenom)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "nibiru.perp.v2.Msg", HandlerType: (*MsgServer)(nil), @@ -1345,6 +1472,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "DonateToEcosystemFund", Handler: _Msg_DonateToEcosystemFund_Handler, }, + { + MethodName: "ChangeCollateralDenom", + Handler: _Msg_ChangeCollateralDenom_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "nibiru/perp/v2/tx.proto", @@ -2276,6 +2407,66 @@ func (m *MsgDonateToEcosystemFundResponse) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } +func (m *MsgChangeCollateralDenom) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgChangeCollateralDenom) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangeCollateralDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewDenom) > 0 { + i -= len(m.NewDenom) + copy(dAtA[i:], m.NewDenom) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChangeCollateralDenomResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgChangeCollateralDenomResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangeCollateralDenomResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -2595,6 +2786,32 @@ func (m *MsgDonateToEcosystemFundResponse) Size() (n int) { return n } +func (m *MsgChangeCollateralDenom) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewDenom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChangeCollateralDenomResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -5295,6 +5512,170 @@ func (m *MsgDonateToEcosystemFundResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgChangeCollateralDenom) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgChangeCollateralDenom: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangeCollateralDenom: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChangeCollateralDenomResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgChangeCollateralDenomResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangeCollateralDenomResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/sudo/keeper/keeper.go b/x/sudo/keeper/keeper.go index 3b7a6a10b4..f28a9169db 100644 --- a/x/sudo/keeper/keeper.go +++ b/x/sudo/keeper/keeper.go @@ -138,7 +138,7 @@ func (k Keeper) CheckPermissions( } contracts := state.Contracts - hasPermission := set.New(contracts...).Has(contract.String()) + hasPermission := set.New(contracts...).Has(contract.String()) || contract.String() == state.Root if !hasPermission { return fmt.Errorf( "insufficient permissions on smart contract: %s. The sudo contracts are: %s", diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index e8991585f2..9f0a939b1f 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -5,15 +5,15 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - grpccodes "google.golang.org/grpc/codes" - grpcstatus "google.golang.org/grpc/status" + + "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/tokenfactory/types" ) var _ types.MsgServer = (*Keeper)(nil) -var errNilMsg error = grpcstatus.Errorf(grpccodes.InvalidArgument, "nil msg") +var errNilMsg error = common.ErrNilMsg() func (k Keeper) CreateDenom( goCtx context.Context, txMsg *types.MsgCreateDenom, diff --git a/x/tokenfactory/types/state.go b/x/tokenfactory/types/state.go index 782c7c0870..05f0d07741 100644 --- a/x/tokenfactory/types/state.go +++ b/x/tokenfactory/types/state.go @@ -56,6 +56,10 @@ func (tfd TFDenom) DefaultBankMetadata() banktypes.Metadata { } } +func (tfd TFDenom) IsEqual(other TFDenom) bool { + return tfd.Creator == other.Creator && tfd.Subdenom == other.Subdenom +} + // ---------------------------------------------------- // DenomStr functions // ----------------------------------------------------