diff --git a/CHANGELOG.md b/CHANGELOG.md index febb05cc2..51d117b46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,7 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * [#712](https://github.com/NibiruChain/nibiru/pull/712) Add funding rate calculation and `FundingRateChangedEvent`. ### Upgrades - +* [#725](https://github.com/NibiruChain/nibiru/pull/725) Add governance handler for creating new virtual pools. * [#702](https://github.com/NibiruChain/nibiru/pull/702) Add upgrade handler for v0.10.0. ## [v0.9.2](https://github.com/NibiruChain/nibiru/releases/tag/v0.9.2) - 2022-07-11 diff --git a/app/app.go b/app/app.go index 9ec4682a9..0b514ef9b 100644 --- a/app/app.go +++ b/app/app.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" + vpoolcli "github.com/NibiruChain/nibiru/x/vpool/client/cli" + pricefeedcli "github.com/NibiruChain/nibiru/x/pricefeed/client/cli" "github.com/cosmos/cosmos-sdk/baseapp" @@ -154,6 +156,7 @@ var ( upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, pricefeedcli.AddOracleProposalHandler, + vpoolcli.CreatePoolProposalHandler, // pricefeedcli.RemoveOracleProposalHandler, // TODO ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, @@ -481,7 +484,8 @@ func NewNibiruApp( AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)). - AddRoute(pricefeedtypes.RouterKey, pricefeed.NewPricefeedProposalHandler(app.PricefeedKeeper)) + AddRoute(pricefeedtypes.RouterKey, pricefeed.NewPricefeedProposalHandler(app.PricefeedKeeper)). + AddRoute(vpooltypes.RouterKey, vpool.NewCreatePoolProposalHandler(app.VpoolKeeper)) app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, diff --git a/proto/vpool/v1/gov.proto b/proto/vpool/v1/gov.proto new file mode 100644 index 000000000..ed9980c0d --- /dev/null +++ b/proto/vpool/v1/gov.proto @@ -0,0 +1,49 @@ +syntax = "proto3"; + +package nibiru.vpool.v1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/NibiruChain/nibiru/x/vpool/types"; + +message CreatePoolProposal { + string title = 1; + string description = 2; + // pair represents the pair of the vpool. + string pair = 3; + // trade_limit_ratio represents the limit on trading amounts. + string trade_limit_ratio = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // quote_asset_reserve is the amount of quote asset the pool will be initialized with. + string quote_asset_reserve = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + // base_asset_reserve is the amount of base asset the pool will be initialized with. + string base_asset_reserve = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // fluctuation_limit_ratio represents the maximum price + // percentage difference a trade can create on the pool. + string fluctuation_limit_ratio = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // max_oracle_spread_ratio represents the maximum price percentage + // difference that can exist between oracle price and vpool prices after a trade. + string max_oracle_spread_ratio = 8 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + + // maintenance_margin_ratio + string maintenance_margin_ratio = 9 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} \ No newline at end of file diff --git a/x/vpool/client/cli/cli_test.go b/x/vpool/client/cli/cli_test.go new file mode 100644 index 000000000..c0c58773f --- /dev/null +++ b/x/vpool/client/cli/cli_test.go @@ -0,0 +1,231 @@ +package cli_test + +import ( + "context" + "fmt" + "io/ioutil" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdktestutil "github.com/cosmos/cosmos-sdk/testutil" + sdktestutilcli "github.com/cosmos/cosmos-sdk/testutil/cli" + sdk "github.com/cosmos/cosmos-sdk/types" + govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/NibiruChain/nibiru/app" + "github.com/NibiruChain/nibiru/x/common" + testutilcli "github.com/NibiruChain/nibiru/x/testutil/cli" + "github.com/NibiruChain/nibiru/x/testutil/testapp" + "github.com/NibiruChain/nibiru/x/vpool/client/cli" + vpooltypes "github.com/NibiruChain/nibiru/x/vpool/types" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg testutilcli.Config + network *testutilcli.Network +} + +func (s *IntegrationTestSuite) SetupSuite() { + if testing.Short() { + s.T().Skip("skipping integration test suite") + } + + s.T().Log("setting up integration test suite") + + app.SetPrefixes(app.AccountAddressPrefix) + + encCfg := app.MakeTestEncodingConfig() + defaultAppGenesis := app.ModuleBasics.DefaultGenesis(encCfg.Marshaler) + testAppGenesis := testapp.NewTestGenesisState(encCfg.Marshaler, defaultAppGenesis) + s.cfg = testutilcli.BuildNetworkConfig(testAppGenesis) + + s.network = testutilcli.NewNetwork(s.T(), s.cfg) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) + + res, err := testutilcli.QueryPrice( + s.network.Validators[0].ClientCtx, + common.PairGovStable.String(), + ) + s.Require().NoError(err) + s.Assert().Equal(sdk.NewDec(10), res.Price.Price) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s IntegrationTestSuite) TestX_CmdAddOracleProposalAndVote() { + s.Require().Len(s.network.Validators, 1) + val := s.network.Validators[0] + clientCtx := val.ClientCtx.WithOutputFormat("json") + proposer, _, err := val.ClientCtx.Keyring.NewMnemonic( + /* uid */ "proposer", + /* language */ keyring.English, + /* hdPath */ sdk.FullFundraiserPath, + /* bip39Passphrase */ "", + /* algo */ hd.Secp256k1, + ) + s.Require().NoError(err) + + s.T().Log("Fill proposer wallet to pay gas for prosal") + gasTokens := sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 100_000_000)) + oracle := sdk.AccAddress(proposer.GetPubKey().Address()) + _, err = testutilcli.FillWalletFromValidator(oracle, gasTokens, val, s.cfg.BondDenom) + s.Require().NoError(err) + + s.T().Log("load example json as bytes") + proposal := &vpooltypes.CreatePoolProposal{ + Title: "Create ETH:USD pool", + Description: "Creates an ETH:USD pool", + Pair: "ETH:USD", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.05"), + MaxOracleSpreadRatio: sdk.MustNewDecFromStr("0.05"), + } + proposalJSONString := val.ClientCtx.Codec.MustMarshalJSON(proposal) + proposalJSON := sdktestutil.WriteToNewTempFile( + s.T(), string(proposalJSONString), + ) + contents, err := ioutil.ReadFile(proposalJSON.Name()) + s.Assert().NoError(err) + + s.T().Log("Unmarshal json bytes into proposal object; check validity") + proposal = &vpooltypes.CreatePoolProposal{} + val.ClientCtx.Codec.MustUnmarshalJSON(contents, proposal) + s.Require().NoError(proposal.ValidateBasic()) + + s.T().Log("Submit proposal and unmarshal tx response") + args := []string{ + proposalJSON.Name(), + fmt.Sprintf("--%s=1000unibi", govcli.FlagDeposit), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), + fmt.Sprintf("--from=%s", val.Address.String()), + } + cmd := cli.CmdCreatePoolProposal() + flags.AddTxFlagsToCmd(cmd) + out, err := sdktestutilcli.ExecTestCLICmd(clientCtx, cmd, args) + s.Require().NoError(err) + s.Assert().NotContains(out.String(), "fail") + var txRespProtoMessage proto.Message = &sdk.TxResponse{} + s.Assert().NoError( + clientCtx.Codec.UnmarshalJSON(out.Bytes(), txRespProtoMessage), + out.String()) + txResp := txRespProtoMessage.(*sdk.TxResponse) + err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), txResp) + s.Assert().NoError(err) + s.Assert().EqualValues(0, txResp.Code, out.String()) + + s.T().Log(`Check that proposal was correctly submitted with gov client + $ nibid query gov proposal 1`) + // the proposal tx won't be included until next block + s.Assert().NoError(s.network.WaitForNextBlock()) + govQueryClient := govtypes.NewQueryClient(clientCtx) + proposalsQueryResponse, err := govQueryClient.Proposals( + context.Background(), &govtypes.QueryProposalsRequest{}, + ) + s.Require().NoError(err) + s.Assert().NotEmpty(proposalsQueryResponse.Proposals) + s.Assert().EqualValues(1, proposalsQueryResponse.Proposals[0].ProposalId, + "first proposal should have proposal ID of 1") + s.Assert().Equalf( + govtypes.StatusDepositPeriod, + proposalsQueryResponse.Proposals[0].Status, + "proposal should be in deposit period as it hasn't passed min deposit") + s.Assert().EqualValues( + sdk.NewCoins(sdk.NewInt64Coin("unibi", 1_000)), + proposalsQueryResponse.Proposals[0].TotalDeposit, + ) + + s.T().Log(`Move proposal to vote status by meeting min deposit + $ nibid tx gov deposit [proposal-id] [deposit] [flags]`) + govDepositParams, err := govQueryClient.Params( + context.Background(), &govtypes.QueryParamsRequest{ParamsType: govtypes.ParamDeposit}) + s.Assert().NoError(err) + args = []string{ + /*proposal-id=*/ "1", + /*deposit=*/ govDepositParams.DepositParams.MinDeposit.String(), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), + fmt.Sprintf("--from=%s", val.Address.String()), + } + _, err = sdktestutilcli.ExecTestCLICmd(clientCtx, govcli.NewCmdDeposit(), args) + s.Assert().NoError(err) + + s.Assert().NoError(s.network.WaitForNextBlock()) + govQueryClient = govtypes.NewQueryClient(clientCtx) + proposalsQueryResponse, err = govQueryClient.Proposals( + context.Background(), &govtypes.QueryProposalsRequest{}) + s.Require().NoError(err) + s.Assert().Equalf( + govtypes.StatusVotingPeriod, + proposalsQueryResponse.Proposals[0].Status, + "proposal should be in voting period since min deposit has been met") + + s.T().Log(`Vote on the proposal. + $ nibid tx gov vote [proposal-id] [option] [flags] + e.g. $ nibid tx gov vote 1 yes`) + args = []string{ + /*proposal-id=*/ "1", + /*option=*/ "yes", + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), + fmt.Sprintf("--from=%s", val.Address.String()), + } + _, err = sdktestutilcli.ExecTestCLICmd(clientCtx, govcli.NewCmdVote(), args) + s.Assert().NoError(err) + txResp = &sdk.TxResponse{} + err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), txResp) + s.Assert().NoError(err) + s.Assert().EqualValues(0, txResp.Code, out.String()) + + s.Assert().NoError(s.network.WaitForNextBlock()) + s.Require().Eventuallyf(func() bool { + proposalsQueryResponse, err = govQueryClient.Proposals( + context.Background(), &govtypes.QueryProposalsRequest{}) + s.Require().NoError(err) + return govtypes.StatusPassed == proposalsQueryResponse.Proposals[0].Status + }, 20*time.Second, 2*time.Second, + "proposal should pass after voting period") + + s.T().Log("verify that the new proposed pool exists") + cmd = cli.CmdGetVpools() + args = []string{} + queryResp := &vpooltypes.QueryAllPoolsResponse{} + s.Require().NoError(testutilcli.ExecQuery(s.network, cmd, args, queryResp)) + + found := false + for _, pool := range queryResp.Pools { + if pool.Pair.String() == proposal.Pair { + require.Equal(s.T(), pool, &vpooltypes.Pool{ + Pair: common.MustNewAssetPair(proposal.Pair), + BaseAssetReserve: proposal.BaseAssetReserve, + QuoteAssetReserve: proposal.QuoteAssetReserve, + TradeLimitRatio: proposal.TradeLimitRatio, + FluctuationLimitRatio: proposal.FluctuationLimitRatio, + MaxOracleSpreadRatio: proposal.MaxOracleSpreadRatio, + }) + found = true + } + } + + require.True(s.T(), found, "pool does not exist") +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/x/vpool/client/cli/gov_client.go b/x/vpool/client/cli/gov_client.go new file mode 100644 index 000000000..a5c5ea568 --- /dev/null +++ b/x/vpool/client/cli/gov_client.go @@ -0,0 +1,110 @@ +package cli + +import ( + "fmt" + "io/ioutil" + "net/http" + "strings" + + govclientrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" + + "github.com/NibiruChain/nibiru/x/vpool/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/spf13/cobra" +) + +var ( + CreatePoolProposalHandler = govclient.NewProposalHandler( + /* govclient.CLIHandlerFn */ CmdCreatePoolProposal, + /* govclient.RESTHandlerFn */ func(context client.Context) govclientrest.ProposalRESTHandler { + return govclientrest.ProposalRESTHandler{ + SubRoute: "create_pool", + Handler: func(writer http.ResponseWriter, request *http.Request) { + _, _ = writer.Write([]byte("deprecated")) + writer.WriteHeader(http.StatusMethodNotAllowed) + }, + } + }) +) + +// CmdCreatePoolProposal implements the client command to submit a governance +// proposal to whitelist an oracle for specified asset pairs. +func CmdCreatePoolProposal() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-pool [proposal-json] --deposit=[deposit]", + Args: cobra.ExactArgs(1), + Short: "Submit a proposal to create a new vpool", + Example: strings.TrimSpace(fmt.Sprintf(` + Example: + $ %s tx gov submit-proposal create-pool --deposit="1000unibi" --from= + `, version.AppName)), + Long: strings.TrimSpace( + `Submits a proposal to create a new vpool, which in turn create a new x/perp market + + A proposal.json for 'CreatePoolProposal' contains: + { + "title": "Create vpool for ETH:USDT", + "description": "I wanna get liquidated on ETH:USDT", + "pair": "ETH:USDT", + "trade_limit_ratio": "0.2", + ... + } + `), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + from := clientCtx.GetFromAddress() + + proposal := &types.CreatePoolProposal{} + contents, err := ioutil.ReadFile(args[0]) + if err != nil { + return err + } + + // marshals the contents into the proto.Message to which 'proposal' points. + if err = clientCtx.Codec.UnmarshalJSON(contents, proposal); err != nil { + return err + } + + depositStr, err := cmd.Flags().GetString(govcli.FlagDeposit) + if err != nil { + return err + } + deposit, err := sdk.ParseCoinsNormalized(depositStr) + if err != nil { + return err + } + + msg, err := govtypes.NewMsgSubmitProposal(proposal, deposit, from) + if err != nil { + return err + } + if err = msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String( + /*name=*/ govcli.FlagDeposit, + /*defaultValue=*/ "", + /*usage=*/ "governance deposit for proposal") + if err := cmd.MarkFlagRequired(govcli.FlagDeposit); err != nil { + panic(err) + } + + return cmd +} diff --git a/x/vpool/handler.go b/x/vpool/handler.go index fa1c6a684..2fa2b4be4 100644 --- a/x/vpool/handler.go +++ b/x/vpool/handler.go @@ -3,6 +3,10 @@ package vpool import ( "fmt" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/NibiruChain/nibiru/x/common" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -19,3 +23,30 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) } } + +func NewCreatePoolProposalHandler(k keeper.Keeper) govtypes.Handler { + return func(ctx sdk.Context, content govtypes.Content) error { + switch m := content.(type) { + case *types.CreatePoolProposal: + if err := m.ValidateBasic(); err != nil { + return err + } + pair := common.MustNewAssetPair(m.Pair) + k.CreatePool( + ctx, + pair, + m.TradeLimitRatio, + m.QuoteAssetReserve, + m.BaseAssetReserve, + m.FluctuationLimitRatio, + m.MaxOracleSpreadRatio, + m.MaintenanceMarginRatio, + ) + return nil + default: + return sdkerrors.Wrapf( + sdkerrors.ErrUnknownRequest, + "unrecognized %s proposal content type: %T", types.ModuleName, m) + } + } +} diff --git a/x/vpool/types/codec.go b/x/vpool/types/codec.go index 4c12aafed..b24950949 100644 --- a/x/vpool/types/codec.go +++ b/x/vpool/types/codec.go @@ -4,6 +4,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) func RegisterCodec(cdc *codec.LegacyAmino) { @@ -15,6 +16,8 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { /* implementations */ ) + registry.RegisterImplementations((*govtypes.Content)(nil), &CreatePoolProposal{}) + // msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/vpool/types/gov.go b/x/vpool/types/gov.go new file mode 100644 index 000000000..f9ae10a7f --- /dev/null +++ b/x/vpool/types/gov.go @@ -0,0 +1,70 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/NibiruChain/nibiru/x/common" +) + +const ( + ProposalTypeCreatePool = "CreatePool" +) + +var _ govtypes.Content = &CreatePoolProposal{} + +func init() { + govtypes.RegisterProposalType(ProposalTypeCreatePool) + govtypes.RegisterProposalTypeCodec(&CreatePoolProposal{}, "nibiru/CreatePoolProposal") +} + +func (m *CreatePoolProposal) ProposalRoute() string { + return RouterKey +} + +func (m *CreatePoolProposal) ProposalType() string { + return ProposalTypeCreatePool +} + +func (m *CreatePoolProposal) ValidateBasic() error { + if err := govtypes.ValidateAbstract(m); err != nil { + return err + } + + if _, err := common.NewAssetPair(m.Pair); err != nil { + return err + } + + // trade limit ratio always between 0 and 1 + if m.TradeLimitRatio.LT(sdk.ZeroDec()) || m.TradeLimitRatio.GT(sdk.OneDec()) { + return fmt.Errorf("trade limit ratio must be 0 <= ratio <= 1") + } + + // quote asset reserve always > 0 + if !m.QuoteAssetReserve.IsPositive() { + return fmt.Errorf("quote asset reserve must be > 0") + } + + // base asset reserve always > 0 + if !m.BaseAssetReserve.IsPositive() { + return fmt.Errorf("base asset reserve must be > 0") + } + + // fluctuation limit ratio between 0 and 1 + if m.FluctuationLimitRatio.LT(sdk.ZeroDec()) || m.FluctuationLimitRatio.GT(sdk.OneDec()) { + return fmt.Errorf("fluctuation limit ratio must be 0 <= ratio <= 1") + } + + // max oracle spread ratio between 0 and 1 + if m.MaxOracleSpreadRatio.LT(sdk.ZeroDec()) || m.MaxOracleSpreadRatio.GT(sdk.OneDec()) { + return fmt.Errorf("max oracle spread ratio must be 0 <= ratio <= 1") + } + + if m.MaintenanceMarginRatio.LT(sdk.ZeroDec()) || m.MaintenanceMarginRatio.GT(sdk.OneDec()) { + return fmt.Errorf("maintenance margin ratio ratio must be 0 <= ratio <= 1") + } + + return nil +} diff --git a/x/vpool/types/gov.pb.go b/x/vpool/types/gov.pb.go new file mode 100644 index 000000000..d6a0feb02 --- /dev/null +++ b/x/vpool/types/gov.pb.go @@ -0,0 +1,725 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: vpool/v1/gov.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type CreatePoolProposal struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // pair represents the pair of the vpool. + Pair string `protobuf:"bytes,3,opt,name=pair,proto3" json:"pair,omitempty"` + // trade_limit_ratio represents the limit on trading amounts. + TradeLimitRatio github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=trade_limit_ratio,json=tradeLimitRatio,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"trade_limit_ratio"` + // quote_asset_reserve is the amount of quote asset the pool will be initialized with. + QuoteAssetReserve github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=quote_asset_reserve,json=quoteAssetReserve,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quote_asset_reserve"` + // base_asset_reserve is the amount of base asset the pool will be initialized with. + BaseAssetReserve github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=base_asset_reserve,json=baseAssetReserve,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"base_asset_reserve"` + // fluctuation_limit_ratio represents the maximum price + // percentage difference a trade can create on the pool. + FluctuationLimitRatio github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=fluctuation_limit_ratio,json=fluctuationLimitRatio,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"fluctuation_limit_ratio"` + // max_oracle_spread_ratio represents the maximum price percentage + // difference that can exist between oracle price and vpool prices after a trade. + MaxOracleSpreadRatio github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,8,opt,name=max_oracle_spread_ratio,json=maxOracleSpreadRatio,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"max_oracle_spread_ratio"` + // maintenance_margin_ratio + MaintenanceMarginRatio github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,9,opt,name=maintenance_margin_ratio,json=maintenanceMarginRatio,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"maintenance_margin_ratio"` +} + +func (m *CreatePoolProposal) Reset() { *m = CreatePoolProposal{} } +func (m *CreatePoolProposal) String() string { return proto.CompactTextString(m) } +func (*CreatePoolProposal) ProtoMessage() {} +func (*CreatePoolProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_8a393460ab414204, []int{0} +} +func (m *CreatePoolProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CreatePoolProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CreatePoolProposal.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 *CreatePoolProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreatePoolProposal.Merge(m, src) +} +func (m *CreatePoolProposal) XXX_Size() int { + return m.Size() +} +func (m *CreatePoolProposal) XXX_DiscardUnknown() { + xxx_messageInfo_CreatePoolProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_CreatePoolProposal proto.InternalMessageInfo + +func (m *CreatePoolProposal) GetTitle() string { + if m != nil { + return m.Title + } + return "" +} + +func (m *CreatePoolProposal) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *CreatePoolProposal) GetPair() string { + if m != nil { + return m.Pair + } + return "" +} + +func init() { + proto.RegisterType((*CreatePoolProposal)(nil), "nibiru.vpool.v1.CreatePoolProposal") +} + +func init() { proto.RegisterFile("vpool/v1/gov.proto", fileDescriptor_8a393460ab414204) } + +var fileDescriptor_8a393460ab414204 = []byte{ + // 404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0xd3, 0xcf, 0xae, 0x93, 0x40, + 0x14, 0x06, 0x70, 0xd0, 0xdb, 0xab, 0x77, 0x5c, 0x5c, 0x3b, 0x56, 0x4b, 0x5c, 0xd0, 0xc6, 0x85, + 0x31, 0x31, 0x32, 0x69, 0x7c, 0x02, 0x5b, 0xdd, 0xf9, 0xa7, 0xc1, 0x5d, 0x63, 0x24, 0x03, 0x9c, + 0xd2, 0x89, 0x30, 0x07, 0x67, 0x06, 0x52, 0xdf, 0xc2, 0x77, 0xf1, 0x25, 0xba, 0xec, 0xd2, 0xb8, + 0x68, 0x4c, 0xfb, 0x22, 0x86, 0xa1, 0x0b, 0xea, 0x92, 0x15, 0x03, 0x67, 0xf2, 0xfb, 0xc2, 0x49, + 0x3e, 0x42, 0xeb, 0x12, 0x31, 0x67, 0xf5, 0x8c, 0x65, 0x58, 0x07, 0xa5, 0x42, 0x83, 0xf4, 0x56, + 0x8a, 0x58, 0xa8, 0x2a, 0xb0, 0xa3, 0xa0, 0x9e, 0x3d, 0x1d, 0x65, 0x98, 0xa1, 0x9d, 0xb1, 0xe6, + 0xd4, 0x5e, 0x7b, 0xf6, 0x6b, 0x40, 0xe8, 0x42, 0x01, 0x37, 0xb0, 0x44, 0xcc, 0x97, 0x0a, 0x4b, + 0xd4, 0x3c, 0xa7, 0x23, 0x32, 0x30, 0xc2, 0xe4, 0xe0, 0xb9, 0x53, 0xf7, 0xc5, 0x4d, 0xd8, 0xbe, + 0xd0, 0x29, 0x79, 0x90, 0x82, 0x4e, 0x94, 0x28, 0x8d, 0x40, 0xe9, 0xdd, 0xb1, 0xb3, 0xee, 0x27, + 0x4a, 0xc9, 0x55, 0xc9, 0x85, 0xf2, 0xee, 0xda, 0x91, 0x3d, 0xd3, 0x15, 0x19, 0x1a, 0xc5, 0x53, + 0x88, 0x72, 0x51, 0x08, 0x13, 0x29, 0x6e, 0x04, 0x7a, 0x57, 0xcd, 0x85, 0x79, 0xb0, 0x3b, 0x4c, + 0x9c, 0x3f, 0x87, 0xc9, 0xf3, 0x4c, 0x98, 0x4d, 0x15, 0x07, 0x09, 0x16, 0x2c, 0x41, 0x5d, 0xa0, + 0x3e, 0x3f, 0x5e, 0xe9, 0xf4, 0x1b, 0x33, 0x3f, 0x4a, 0xd0, 0xc1, 0x5b, 0x48, 0xc2, 0x5b, 0x0b, + 0xbd, 0x6f, 0x9c, 0xb0, 0x61, 0xe8, 0x57, 0xf2, 0xe8, 0x7b, 0x85, 0x06, 0x22, 0xae, 0x35, 0x98, + 0x48, 0x81, 0x06, 0x55, 0x83, 0x37, 0xe8, 0xa5, 0x0f, 0x2d, 0xf5, 0xa6, 0x91, 0xc2, 0x16, 0xa2, + 0x5f, 0x08, 0x8d, 0xb9, 0xfe, 0x9f, 0xbf, 0xee, 0xc5, 0x3f, 0x6c, 0xa4, 0x0b, 0x7d, 0x4d, 0xc6, + 0xeb, 0xbc, 0x4a, 0x4c, 0xd5, 0xfc, 0x8b, 0xbc, 0xd8, 0xcf, 0xbd, 0x5e, 0x11, 0x8f, 0x3b, 0x5c, + 0x67, 0x4b, 0x40, 0xc6, 0x05, 0xdf, 0x46, 0xa8, 0x78, 0x92, 0x43, 0xa4, 0x4b, 0x05, 0x3c, 0x3d, + 0xe7, 0xdc, 0xef, 0x95, 0x33, 0x2a, 0xf8, 0xf6, 0x93, 0xd5, 0x3e, 0x5b, 0xac, 0x8d, 0xd9, 0x10, + 0xaf, 0xe0, 0x42, 0x1a, 0x90, 0x5c, 0x26, 0x10, 0x15, 0x5c, 0x65, 0x42, 0x9e, 0x73, 0x6e, 0x7a, + 0xe5, 0x3c, 0xe9, 0x78, 0x1f, 0x2c, 0x67, 0x93, 0xe6, 0xef, 0x76, 0x47, 0xdf, 0xdd, 0x1f, 0x7d, + 0xf7, 0xef, 0xd1, 0x77, 0x7f, 0x9e, 0x7c, 0x67, 0x7f, 0xf2, 0x9d, 0xdf, 0x27, 0xdf, 0x59, 0xbd, + 0xec, 0xc8, 0x1f, 0x6d, 0x03, 0x16, 0x1b, 0x2e, 0x24, 0x6b, 0xdb, 0xc0, 0xb6, 0xac, 0xad, 0x8a, + 0x8d, 0x88, 0xaf, 0x6d, 0x07, 0x5e, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xea, 0x61, 0x1d, + 0x40, 0x03, 0x00, 0x00, +} + +func (m *CreatePoolProposal) 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 *CreatePoolProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CreatePoolProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.MaintenanceMarginRatio.Size() + i -= size + if _, err := m.MaintenanceMarginRatio.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + { + size := m.MaxOracleSpreadRatio.Size() + i -= size + if _, err := m.MaxOracleSpreadRatio.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + { + size := m.FluctuationLimitRatio.Size() + i -= size + if _, err := m.FluctuationLimitRatio.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size := m.BaseAssetReserve.Size() + i -= size + if _, err := m.BaseAssetReserve.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size := m.QuoteAssetReserve.Size() + i -= size + if _, err := m.QuoteAssetReserve.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size := m.TradeLimitRatio.Size() + i -= size + if _, err := m.TradeLimitRatio.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.Pair) > 0 { + i -= len(m.Pair) + copy(dAtA[i:], m.Pair) + i = encodeVarintGov(dAtA, i, uint64(len(m.Pair))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintGov(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintGov(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGov(dAtA []byte, offset int, v uint64) int { + offset -= sovGov(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *CreatePoolProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + l = len(m.Pair) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + l = m.TradeLimitRatio.Size() + n += 1 + l + sovGov(uint64(l)) + l = m.QuoteAssetReserve.Size() + n += 1 + l + sovGov(uint64(l)) + l = m.BaseAssetReserve.Size() + n += 1 + l + sovGov(uint64(l)) + l = m.FluctuationLimitRatio.Size() + n += 1 + l + sovGov(uint64(l)) + l = m.MaxOracleSpreadRatio.Size() + n += 1 + l + sovGov(uint64(l)) + l = m.MaintenanceMarginRatio.Size() + n += 1 + l + sovGov(uint64(l)) + return n +} + +func sovGov(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGov(x uint64) (n int) { + return sovGov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *CreatePoolProposal) 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 ErrIntOverflowGov + } + 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: CreatePoolProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CreatePoolProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pair = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TradeLimitRatio", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TradeLimitRatio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QuoteAssetReserve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.QuoteAssetReserve.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseAssetReserve", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.BaseAssetReserve.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FluctuationLimitRatio", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.FluctuationLimitRatio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxOracleSpreadRatio", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxOracleSpreadRatio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaintenanceMarginRatio", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaintenanceMarginRatio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGov(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGov + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGov(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGov + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGov + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGov + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGov + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGov + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGov + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGov = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGov = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGov = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/vpool/types/gov_test.go b/x/vpool/types/gov_test.go new file mode 100644 index 000000000..8a0e6bd34 --- /dev/null +++ b/x/vpool/types/gov_test.go @@ -0,0 +1,172 @@ +package types + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestCreatePoolProposal_ValidateBasic(t *testing.T) { + type test struct { + m *CreatePoolProposal + expectErr bool + } + + cases := map[string]test{ + "invalid pair": {&CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "invalidpair", + }, true}, + "invalid trade limit ratio < 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.NewDec(-1), + }, + expectErr: true, + }, + + "invalid trade limit ratio > 1": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.NewDec(2), + }, + expectErr: true, + }, + + "quote asset reserve 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.ZeroDec(), + }, + expectErr: true, + }, + + "base asset reserve 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.ZeroDec(), + }, + expectErr: true, + }, + + "fluctuation < 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.NewDec(-1), + }, + expectErr: true, + }, + + "fluctuation > 1": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.NewDec(2), + }, + expectErr: true, + }, + + "max oracle spread ratio < 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.10"), + MaxOracleSpreadRatio: sdk.NewDec(-1), + }, + expectErr: true, + }, + "max oracle spread ratio > 1": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.10"), + MaxOracleSpreadRatio: sdk.NewDec(2), + }, + expectErr: true, + }, + "maintenance ratio < 0": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.10"), + MaxOracleSpreadRatio: sdk.MustNewDecFromStr("0.10"), + MaintenanceMarginRatio: sdk.NewDec(-1), + }, + expectErr: true, + }, + "maintenance ratio > 1": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.10"), + MaxOracleSpreadRatio: sdk.MustNewDecFromStr("0.10"), + MaintenanceMarginRatio: sdk.NewDec(2), + }, + expectErr: true, + }, + + "success": { + m: &CreatePoolProposal{ + Title: "add proposal", + Description: "some weird description", + Pair: "valid:pair", + TradeLimitRatio: sdk.MustNewDecFromStr("0.10"), + QuoteAssetReserve: sdk.NewDec(1_000_000), + BaseAssetReserve: sdk.NewDec(1_000_000), + FluctuationLimitRatio: sdk.MustNewDecFromStr("0.10"), + MaxOracleSpreadRatio: sdk.MustNewDecFromStr("0.10"), + MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"), + }, + expectErr: false, + }, + } + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + err := tc.m.ValidateBasic() + if err == nil && tc.expectErr { + t.Fatal("error expected") + } else if err != nil && !tc.expectErr { + t.Fatal("unexpected error") + } + }) + } +}