code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_new_spot_market_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package commands_test
    17  
    18  import (
    19  	"errors"
    20  	"fmt"
    21  	"math"
    22  	"testing"
    23  
    24  	"code.vegaprotocol.io/vega/commands"
    25  	"code.vegaprotocol.io/vega/libs/test"
    26  	protoTypes "code.vegaprotocol.io/vega/protos/vega"
    27  	vegapb "code.vegaprotocol.io/vega/protos/vega"
    28  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func TestCheckProposalSubmissionForNewSpotMarket(t *testing.T) {
    34  	t.Run("Submitting a spot market change with a future product", testNewSpotMarketChangeSubmissionWithFutureProductFails)
    35  	t.Run("Submitting a spot market change without new market fails", testNewSpotMarketChangeSubmissionWithoutNewSpotMarketFails)
    36  	t.Run("Submitting a spot market change without changes fails", testNewSpotMarketChangeSubmissionWithoutChangesFails)
    37  	t.Run("Submitting a spot market change without too many pm trigger fails", testNewSpotMarketChangeSubmissionWithTooManyPMTriggersFails)
    38  	t.Run("Submitting a spot market change without decimal places succeeds", testNewSpotMarketChangeSubmissionWithoutDecimalPlacesSucceeds)
    39  	t.Run("Submitting a spot market change with decimal places equal to 0 succeeds", testNewSpotMarketChangeSubmissionWithDecimalPlacesEqualTo0Succeeds)
    40  	t.Run("Submitting a spot market change with decimal places above or equal to 150 fails", testNewSpotMarketChangeSubmissionWithDecimalPlacesAboveOrEqualTo150Fails)
    41  	t.Run("Submitting a spot market change with decimal places below 150 succeeds", testNewSpotMarketChangeSubmissionWithDecimalPlacesBelow150Succeeds)
    42  	t.Run("Submitting a spot market change with position decimal places equal to 0 succeeds", testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesEqualTo0Succeeds)
    43  	t.Run("Submitting a spot market change with position decimal places above or equal to 6 fails", testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesAboveOrEqualTo7Fails)
    44  	t.Run("Submitting a spot market change with position decimal places below 6 succeeds", testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesBelow7Succeeds)
    45  	t.Run("Submitting a new spot market without price monitoring succeeds", testNewSpotMarketChangeSubmissionWithoutPriceMonitoringSucceeds)
    46  	t.Run("Submitting a new spot market with price monitoring succeeds", testNewSpotMarketChangeSubmissionWithPriceMonitoringSucceeds)
    47  	t.Run("Submitting a price monitoring change without triggers succeeds", testSpotPriceMonitoringChangeSubmissionWithoutTriggersSucceeds)
    48  	t.Run("Submitting a price monitoring change with triggers succeeds", testSpotPriceMonitoringChangeSubmissionWithTriggersSucceeds)
    49  	t.Run("Submitting a price monitoring change without trigger horizon fails", testSpotPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails)
    50  	t.Run("Submitting a price monitoring change with trigger horizon succeeds", testSpotPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds)
    51  	t.Run("Submitting a price monitoring change with wrong trigger probability fails", testSpotPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails)
    52  	t.Run("Submitting a price monitoring change with right trigger probability succeeds", testSpotPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds)
    53  	t.Run("Submitting a price monitoring change without trigger auction extension fails", testSpotPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails)
    54  	t.Run("Submitting a price monitoring change with trigger auction extension succeeds", testSpotPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds)
    55  	t.Run("Submitting a spot market change without instrument name fails", testNewSpotMarketChangeSubmissionWithoutInstrumentNameFails)
    56  	t.Run("Submitting a spot market change with instrument name succeeds", testNewSpotMarketChangeSubmissionWithInstrumentNameSucceeds)
    57  	t.Run("Submitting a spot market change without instrument code fails", testNewSpotMarketChangeSubmissionWithoutInstrumentCodeFails)
    58  	t.Run("Submitting a spot market change with instrument code succeeds", testNewSpotMarketChangeSubmissionWithInstrumentCodeSucceeds)
    59  	t.Run("Submitting a spot market change without product fails", testNewSpotMarketChangeSubmissionWithoutProductFails)
    60  	t.Run("Submitting a spot market change with product succeeds", testNewSpotMarketChangeSubmissionWithProductSucceeds)
    61  	t.Run("Submitting a simple risk parameters change without simple risk parameters fails", testNewSpotSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails)
    62  	t.Run("Submitting a simple risk parameters change with simple risk parameters succeeds", testNewSpotSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds)
    63  	t.Run("Submitting a simple risk parameters change with min move down fails", testNewSpotSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails)
    64  	t.Run("Submitting a simple risk parameters change with min move down succeeds", testNewSpotSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds)
    65  	t.Run("Submitting a simple risk parameters change with max move up fails", testNewSpotSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails)
    66  	t.Run("Submitting a simple risk parameters change with max move up succeeds", testNewSpotSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds)
    67  	t.Run("Submitting a simple risk parameters change with wrong probability of trading fails", testNewSpotSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails)
    68  	t.Run("Submitting a simple risk parameters change with right probability of trading succeeds", testNewSpotSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds)
    69  	t.Run("Submitting a simple risk parameters change with negative max move up fails", testSpotNewSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails)
    70  	t.Run("Submitting a log normal risk parameters change without log normal risk parameters fails", testNewSpotLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails)
    71  	t.Run("Submitting a log normal risk parameters change with log normal risk parameters succeeds", testNewSpotLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds)
    72  	t.Run("Submitting a log normal risk parameters change with params fails", testNewSpotLogNormalRiskParametersChangeSubmissionWithoutParamsFails)
    73  	t.Run("Submitting a log normal risk parameters change with invalid risk aversion", testNewSpotLogNormalRiskParametersChangeSubmissionInvalidRiskAversion)
    74  	t.Run("Submitting a log normal risk parameters change with invalid tau", testNewSpotLogNormalRiskParametersChangeSubmissionInvalidTau)
    75  	t.Run("Submitting a log normal risk parameters change with invalid mu", testNewSpotLogNormalRiskParametersChangeSubmissionInvalidMu)
    76  	t.Run("Submitting a log normal risk parameters change with invalid sigma", testNewSpotLogNormalRiskParametersChangeSubmissionInvalidSigma)
    77  	t.Run("Submitting a log normal risk parameters change with invalid r", testNewSpotLogNormalRiskParametersChangeSubmissionInvalidR)
    78  	t.Run("Submitting a new spot market with a too long reference fails", testNewSpotMarketSubmissionWithTooLongReferenceFails)
    79  	t.Run("Submitting an empty target stake parameters succeeds", testSpotTargetStakeParametersSucceeds)
    80  	t.Run("Submitting target stake parameters with a negative time window fails", testSpotTargetStakeWithNonPositiveTimeWindowFails)
    81  	t.Run("Submitting target stake parameters with a positive time window succeeds", testSpotTargetStakeWithPositiveTimeWindowSucceeds)
    82  	t.Run("Submitting target stake parameters with non positive scaling factor fails ", testSpotTargetStakeWithNonPositiveScalingFactorFails)
    83  	t.Run("Submitting a target stake parameters with positive scaling factor succeeds", testSpotTargetStakeWithPositiveScalingFactorSucceeds)
    84  	t.Run("Submitting a new spot market without target stake parameters succeeds", testNewSpotMarketChangeSubmissionWithoutTargetStakeParamSucceeds)
    85  	t.Run("Submitting a new spot market without spot product definition fails", testNewSpotMarketMarketChangeSubmissionWithoutSpotFails)
    86  	t.Run("Submitting a new spot market with spot product definition succeeds", testNewSpotMarketMarketChangeSubmissionWithSpotSucceeds)
    87  	t.Run("Submitting a new spot market without base or quote asset fails", testNewSpotMarketMarketChangeSubmissionWithoutEitherAssetFails)
    88  	t.Run("Submitting a new spot market with base and quote asset succeeds", testNewSpotMarketMarketChangeSubmissionWithBaseAndQuoteAssetsSucceeds)
    89  	t.Run("Submitting a new spot market with price monitoring without triggers succeeds", testSpotPriceMonitoringChangeSubmissionWithoutTriggersSucceeds)
    90  	t.Run("Submitting a new spot market with price monitoring with triggers succeeds", testSpotPriceMonitoringChangeSubmissionWithTriggersSucceeds)
    91  	t.Run("Submitting a new spot market with price monitoring with probability succeeds", testSpotMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds)
    92  	t.Run("Submitting a new spot market with price monitoring without trigger auction extension fails", testSpotPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails)
    93  	t.Run("Submitting a new spot market with price monitoring with trigger auction extension succeeds", testSpotMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds)
    94  	t.Run("Submitting a new spot market with invalid SLA price range fails", testNewSpotMarketChangeSubmissionWithInvalidLpRangeFails)
    95  	t.Run("Submitting a new spot market with valid SLA price range succeeds", testNewSpotMarketChangeSubmissionWithValidLpRangeSucceeds)
    96  	t.Run("Submitting a new spot market with invalid min time fraction fails", testNewSpotMarketChangeSubmissionWithInvalidMinTimeFractionFails)
    97  	t.Run("Submitting a new spot market with valid min time fraction succeeds", testNewSpotMarketChangeSubmissionWithValidMinTimeFractionSucceeds)
    98  	t.Run("Submitting a new spot market with invalid competition factor fails", testNewSpotMarketChangeSubmissionWithInvalidCompetitionFactorFails)
    99  	t.Run("Submitting a new spot market with valid competition factor succeeds", testNewSpotMarketChangeSubmissionWithValidCompetitionFactorSucceeds)
   100  	t.Run("Submitting a new spot market with invalid hysteresis epochs fails", testNewSpotMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails)
   101  	t.Run("Submitting a new spot market with valid hysteresis epochs succeeds", testNewSpotMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds)
   102  
   103  	t.Run("Submitting a new spot market with invalid tick size fails and valid tick size succeeds", testNewSpotMarketTickSize)
   104  }
   105  
   106  func testNewSpotMarketTickSize(t *testing.T) {
   107  	cases := getTickSizeCases()
   108  	for _, tsc := range cases {
   109  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
   110  			Terms: &vegapb.ProposalTerms{
   111  				Change: &vegapb.ProposalTerms_NewSpotMarket{
   112  					NewSpotMarket: &vegapb.NewSpotMarket{
   113  						Changes: &vegapb.NewSpotMarketConfiguration{
   114  							Instrument: &protoTypes.InstrumentConfiguration{
   115  								Product: &protoTypes.InstrumentConfiguration_Spot{},
   116  							},
   117  							TickSize: tsc.tickSize,
   118  						},
   119  					},
   120  				},
   121  			},
   122  		})
   123  		if tsc.err != nil {
   124  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.tick_size"), tsc.err)
   125  		} else {
   126  			assert.Empty(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.tick_size"))
   127  		}
   128  	}
   129  }
   130  
   131  func testNewSpotMarketChangeSubmissionWithoutNewSpotMarketFails(t *testing.T) {
   132  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   133  		Terms: &protoTypes.ProposalTerms{
   134  			Change: &protoTypes.ProposalTerms_NewSpotMarket{},
   135  		},
   136  	})
   137  
   138  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market"), commands.ErrIsRequired)
   139  }
   140  
   141  func testNewSpotMarketChangeSubmissionWithoutChangesFails(t *testing.T) {
   142  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   143  		Terms: &protoTypes.ProposalTerms{
   144  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   145  				NewSpotMarket: &protoTypes.NewSpotMarket{},
   146  			},
   147  		},
   148  	})
   149  
   150  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes"), commands.ErrIsRequired)
   151  }
   152  
   153  func testNewSpotMarketChangeSubmissionWithoutDecimalPlacesSucceeds(t *testing.T) {
   154  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   155  		Terms: &protoTypes.ProposalTerms{
   156  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   157  				NewSpotMarket: &protoTypes.NewSpotMarket{
   158  					Changes: &protoTypes.NewSpotMarketConfiguration{},
   159  				},
   160  			},
   161  		},
   162  	})
   163  
   164  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero)
   165  }
   166  
   167  func testNewSpotMarketChangeSubmissionWithDecimalPlacesEqualTo0Succeeds(t *testing.T) {
   168  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   169  		Terms: &protoTypes.ProposalTerms{
   170  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   171  				NewSpotMarket: &protoTypes.NewSpotMarket{
   172  					Changes: &protoTypes.NewSpotMarketConfiguration{
   173  						PriceDecimalPlaces: 0,
   174  					},
   175  				},
   176  			},
   177  		},
   178  	})
   179  
   180  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero)
   181  }
   182  
   183  func testNewSpotMarketChangeSubmissionWithDecimalPlacesAboveOrEqualTo150Fails(t *testing.T) {
   184  	testCases := []struct {
   185  		msg   string
   186  		value uint64
   187  	}{
   188  		{
   189  			msg:   "equal to 150",
   190  			value: 150,
   191  		}, {
   192  			msg:   "above 150",
   193  			value: 1000,
   194  		},
   195  	}
   196  	for _, tc := range testCases {
   197  		t.Run(tc.msg, func(t *testing.T) {
   198  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   199  				Terms: &protoTypes.ProposalTerms{
   200  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
   201  						NewSpotMarket: &protoTypes.NewSpotMarket{
   202  							Changes: &protoTypes.NewSpotMarketConfiguration{
   203  								Instrument: &protoTypes.InstrumentConfiguration{
   204  									Product: &protoTypes.InstrumentConfiguration_Spot{},
   205  								},
   206  								PriceDecimalPlaces: tc.value,
   207  							},
   208  						},
   209  					},
   210  				},
   211  			})
   212  
   213  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.decimal_places"), commands.ErrMustBeLessThan150)
   214  		})
   215  	}
   216  }
   217  
   218  func testNewSpotMarketChangeSubmissionWithDecimalPlacesBelow150Succeeds(t *testing.T) {
   219  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   220  		Terms: &protoTypes.ProposalTerms{
   221  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   222  				NewSpotMarket: &protoTypes.NewSpotMarket{
   223  					Changes: &protoTypes.NewSpotMarketConfiguration{
   224  						PriceDecimalPlaces: test.RandomPositiveU64Before(150),
   225  					},
   226  				},
   227  			},
   228  		},
   229  	})
   230  
   231  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.decimal_places"), commands.ErrMustBePositive)
   232  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.decimal_places"), commands.ErrMustBeLessThan150)
   233  }
   234  
   235  func testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesEqualTo0Succeeds(t *testing.T) {
   236  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   237  		Terms: &protoTypes.ProposalTerms{
   238  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   239  				NewSpotMarket: &protoTypes.NewSpotMarket{
   240  					Changes: &protoTypes.NewSpotMarketConfiguration{
   241  						SizeDecimalPlaces: 0,
   242  					},
   243  				},
   244  			},
   245  		},
   246  	})
   247  
   248  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.position_decimal_places"), commands.ErrMustBePositiveOrZero)
   249  }
   250  
   251  func testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesAboveOrEqualTo7Fails(t *testing.T) {
   252  	testCases := []struct {
   253  		msg   string
   254  		value int64
   255  	}{
   256  		{
   257  			msg:   "equal to 7",
   258  			value: 7,
   259  		},
   260  		{
   261  			msg:   "greater than 7",
   262  			value: 8,
   263  		},
   264  		{
   265  			msg:   "equal to -7",
   266  			value: -7,
   267  		},
   268  		{
   269  			msg:   "less than -7",
   270  			value: -8,
   271  		},
   272  	}
   273  	for _, tc := range testCases {
   274  		t.Run(tc.msg, func(t *testing.T) {
   275  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   276  				Terms: &protoTypes.ProposalTerms{
   277  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
   278  						NewSpotMarket: &protoTypes.NewSpotMarket{
   279  							Changes: &protoTypes.NewSpotMarketConfiguration{
   280  								Instrument: &protoTypes.InstrumentConfiguration{
   281  									Product: &protoTypes.InstrumentConfiguration_Spot{},
   282  								},
   283  								SizeDecimalPlaces: tc.value,
   284  							},
   285  						},
   286  					},
   287  				},
   288  			})
   289  
   290  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.position_decimal_places"), commands.ErrMustBeWithinRange7)
   291  		})
   292  	}
   293  }
   294  
   295  func testNewSpotMarketChangeSubmissionWithPositionDecimalPlacesBelow7Succeeds(t *testing.T) {
   296  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   297  		Terms: &protoTypes.ProposalTerms{
   298  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   299  				NewSpotMarket: &protoTypes.NewSpotMarket{
   300  					Changes: &protoTypes.NewSpotMarketConfiguration{
   301  						SizeDecimalPlaces: test.RandomPositiveI64Before(7),
   302  					},
   303  				},
   304  			},
   305  		},
   306  	})
   307  
   308  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.position_decimal_places"), commands.ErrMustBeWithinRange7)
   309  }
   310  
   311  func testNewSpotMarketChangeSubmissionWithoutTargetStakeParamSucceeds(t *testing.T) {
   312  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   313  		Terms: &protoTypes.ProposalTerms{
   314  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   315  				NewSpotMarket: &protoTypes.NewSpotMarket{
   316  					Changes: &protoTypes.NewSpotMarketConfiguration{},
   317  				},
   318  			},
   319  		},
   320  	})
   321  
   322  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters"), commands.ErrIsRequired)
   323  }
   324  
   325  func testSpotTargetStakeParametersSucceeds(t *testing.T) {
   326  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   327  		Terms: &protoTypes.ProposalTerms{
   328  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   329  				NewSpotMarket: &protoTypes.NewSpotMarket{
   330  					Changes: &protoTypes.NewSpotMarketConfiguration{
   331  						Instrument: &protoTypes.InstrumentConfiguration{
   332  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   333  						},
   334  						TargetStakeParameters: &protoTypes.TargetStakeParameters{},
   335  					},
   336  				},
   337  			},
   338  		},
   339  	})
   340  
   341  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters"), commands.ErrIsRequired)
   342  }
   343  
   344  func testSpotTargetStakeWithNonPositiveTimeWindowFails(t *testing.T) {
   345  	testCases := []struct {
   346  		msg   string
   347  		value int64
   348  	}{
   349  		{
   350  			msg:   "with ratio of 0",
   351  			value: 0,
   352  		}, {
   353  			msg:   "with ratio of -1",
   354  			value: test.RandomNegativeI64(),
   355  		},
   356  	}
   357  	for _, tc := range testCases {
   358  		t.Run(tc.msg, func(t *testing.T) {
   359  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   360  				Terms: &protoTypes.ProposalTerms{
   361  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
   362  						NewSpotMarket: &protoTypes.NewSpotMarket{
   363  							Changes: &protoTypes.NewSpotMarketConfiguration{
   364  								Instrument: &protoTypes.InstrumentConfiguration{
   365  									Product: &protoTypes.InstrumentConfiguration_Spot{},
   366  								},
   367  								TargetStakeParameters: &protoTypes.TargetStakeParameters{
   368  									TimeWindow: tc.value,
   369  								},
   370  							},
   371  						},
   372  					},
   373  				},
   374  			})
   375  
   376  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters.time_window"), commands.ErrMustBePositive)
   377  		})
   378  	}
   379  }
   380  
   381  func testSpotTargetStakeWithPositiveTimeWindowSucceeds(t *testing.T) {
   382  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   383  		Terms: &protoTypes.ProposalTerms{
   384  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   385  				NewSpotMarket: &protoTypes.NewSpotMarket{
   386  					Changes: &protoTypes.NewSpotMarketConfiguration{
   387  						Instrument: &protoTypes.InstrumentConfiguration{
   388  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   389  						},
   390  						TargetStakeParameters: &protoTypes.TargetStakeParameters{
   391  							TimeWindow: test.RandomPositiveI64(),
   392  						},
   393  					},
   394  				},
   395  			},
   396  		},
   397  	})
   398  
   399  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters.time_window"), commands.ErrMustBePositive)
   400  }
   401  
   402  func testSpotTargetStakeWithNonPositiveScalingFactorFails(t *testing.T) {
   403  	testCases := []struct {
   404  		msg   string
   405  		value float64
   406  	}{
   407  		{
   408  			msg:   "with ratio of 0",
   409  			value: 0,
   410  		}, {
   411  			msg:   "with ratio of -1.5",
   412  			value: -1.5,
   413  		},
   414  	}
   415  	for _, tc := range testCases {
   416  		t.Run(tc.msg, func(t *testing.T) {
   417  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   418  				Terms: &protoTypes.ProposalTerms{
   419  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
   420  						NewSpotMarket: &protoTypes.NewSpotMarket{
   421  							Changes: &protoTypes.NewSpotMarketConfiguration{
   422  								Instrument: &protoTypes.InstrumentConfiguration{
   423  									Product: &protoTypes.InstrumentConfiguration_Spot{},
   424  								},
   425  								TargetStakeParameters: &protoTypes.TargetStakeParameters{
   426  									ScalingFactor: tc.value,
   427  								},
   428  							},
   429  						},
   430  					},
   431  				},
   432  			})
   433  
   434  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive)
   435  		})
   436  	}
   437  }
   438  
   439  func testSpotTargetStakeWithPositiveScalingFactorSucceeds(t *testing.T) {
   440  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   441  		Terms: &protoTypes.ProposalTerms{
   442  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   443  				NewSpotMarket: &protoTypes.NewSpotMarket{
   444  					Changes: &protoTypes.NewSpotMarketConfiguration{
   445  						Instrument: &protoTypes.InstrumentConfiguration{
   446  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   447  						},
   448  						TargetStakeParameters: &protoTypes.TargetStakeParameters{
   449  							ScalingFactor: 1.5,
   450  						},
   451  					},
   452  				},
   453  			},
   454  		},
   455  	})
   456  
   457  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive)
   458  }
   459  
   460  func testSpotPriceMonitoringChangeSubmissionWithoutTriggersSucceeds(t *testing.T) {
   461  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   462  		Terms: &protoTypes.ProposalTerms{
   463  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   464  				NewSpotMarket: &protoTypes.NewSpotMarket{
   465  					Changes: &protoTypes.NewSpotMarketConfiguration{
   466  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   467  							Triggers: []*protoTypes.PriceMonitoringTrigger{},
   468  						},
   469  					},
   470  				},
   471  			},
   472  		},
   473  	})
   474  
   475  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired)
   476  }
   477  
   478  func testSpotPriceMonitoringChangeSubmissionWithTriggersSucceeds(t *testing.T) {
   479  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   480  		Terms: &protoTypes.ProposalTerms{
   481  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   482  				NewSpotMarket: &protoTypes.NewSpotMarket{
   483  					Changes: &protoTypes.NewSpotMarketConfiguration{
   484  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   485  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   486  								{},
   487  								{},
   488  							},
   489  						},
   490  					},
   491  				},
   492  			},
   493  		},
   494  	})
   495  
   496  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired)
   497  }
   498  
   499  func testNewSpotMarketChangeSubmissionWithTooManyPMTriggersFails(t *testing.T) {
   500  	triggers := []*vegapb.PriceMonitoringTrigger{}
   501  	for i := 0; i <= 100; i++ {
   502  		triggers = append(triggers, &vegapb.PriceMonitoringTrigger{})
   503  	}
   504  
   505  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   506  		Terms: &protoTypes.ProposalTerms{
   507  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   508  				NewSpotMarket: &protoTypes.NewSpotMarket{
   509  					Changes: &protoTypes.NewSpotMarketConfiguration{
   510  						Instrument: &protoTypes.InstrumentConfiguration{
   511  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   512  						},
   513  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   514  							Triggers: triggers,
   515  						},
   516  					},
   517  				},
   518  			},
   519  		},
   520  	})
   521  
   522  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers"), errors.New("maximum 100 triggers allowed"))
   523  }
   524  
   525  func testSpotPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails(t *testing.T) {
   526  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   527  		Terms: &protoTypes.ProposalTerms{
   528  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   529  				NewSpotMarket: &protoTypes.NewSpotMarket{
   530  					Changes: &protoTypes.NewSpotMarketConfiguration{
   531  						Instrument: &protoTypes.InstrumentConfiguration{
   532  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   533  						},
   534  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   535  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   536  								{},
   537  								{},
   538  							},
   539  						},
   540  					},
   541  				},
   542  			},
   543  		},
   544  	})
   545  
   546  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive)
   547  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive)
   548  }
   549  
   550  func testSpotPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds(t *testing.T) {
   551  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   552  		Terms: &protoTypes.ProposalTerms{
   553  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   554  				NewSpotMarket: &protoTypes.NewSpotMarket{
   555  					Changes: &protoTypes.NewSpotMarketConfiguration{
   556  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   557  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   558  								{
   559  									Horizon: test.RandomPositiveI64(),
   560  								},
   561  								{
   562  									Horizon: test.RandomPositiveI64(),
   563  								},
   564  							},
   565  						},
   566  					},
   567  				},
   568  			},
   569  		},
   570  	})
   571  
   572  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive)
   573  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive)
   574  }
   575  
   576  func testSpotPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails(t *testing.T) {
   577  	testCases := []struct {
   578  		msg   string
   579  		value float64
   580  	}{
   581  		{
   582  			msg:   "with probability of -1",
   583  			value: -1,
   584  		}, {
   585  			msg:   "with probability of 0",
   586  			value: 0,
   587  		}, {
   588  			msg:   "with probability of 1",
   589  			value: 1,
   590  		}, {
   591  			msg:   "with probability of 2",
   592  			value: 2,
   593  		},
   594  	}
   595  	for _, tc := range testCases {
   596  		t.Run(tc.msg, func(t *testing.T) {
   597  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   598  				Terms: &protoTypes.ProposalTerms{
   599  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
   600  						NewSpotMarket: &protoTypes.NewSpotMarket{
   601  							Changes: &protoTypes.NewSpotMarketConfiguration{
   602  								Instrument: &protoTypes.InstrumentConfiguration{
   603  									Product: &protoTypes.InstrumentConfiguration_Spot{},
   604  								},
   605  								PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   606  									Triggers: []*protoTypes.PriceMonitoringTrigger{
   607  										{
   608  											Probability: fmt.Sprintf("%f", tc.value),
   609  										},
   610  										{
   611  											Probability: fmt.Sprintf("%f", tc.value),
   612  										},
   613  									},
   614  								},
   615  							},
   616  						},
   617  					},
   618  				},
   619  			})
   620  
   621  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.probability"),
   622  				errors.New("should be between 0.9 (exclusive) and 1 (exclusive)"))
   623  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.probability"),
   624  				errors.New("should be between 0.9 (exclusive) and 1 (exclusive)"))
   625  		})
   626  	}
   627  }
   628  
   629  func testSpotPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds(t *testing.T) {
   630  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   631  		Terms: &vegapb.ProposalTerms{
   632  			Change: &vegapb.ProposalTerms_NewSpotMarket{
   633  				NewSpotMarket: &vegapb.NewSpotMarket{
   634  					Changes: &vegapb.NewSpotMarketConfiguration{
   635  						PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{
   636  							Triggers: []*vegapb.PriceMonitoringTrigger{
   637  								{
   638  									Probability: "0.01",
   639  								},
   640  								{
   641  									Probability: "0.9",
   642  								},
   643  							},
   644  						},
   645  					},
   646  				},
   647  			},
   648  		},
   649  	})
   650  
   651  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.0.probability"),
   652  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   653  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_market.changes.price_monitoring_parameters.triggers.1.probability"),
   654  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   655  }
   656  
   657  func testSpotPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds(t *testing.T) {
   658  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   659  		Terms: &vegapb.ProposalTerms{
   660  			Change: &vegapb.ProposalTerms_NewSpotMarket{
   661  				NewSpotMarket: &vegapb.NewSpotMarket{
   662  					Changes: &vegapb.NewSpotMarketConfiguration{
   663  						PriceMonitoringParameters: &vegapb.PriceMonitoringParameters{
   664  							Triggers: []*vegapb.PriceMonitoringTrigger{
   665  								{
   666  									AuctionExtension: test.RandomPositiveI64(),
   667  								},
   668  								{
   669  									AuctionExtension: test.RandomPositiveI64(),
   670  								},
   671  							},
   672  						},
   673  					},
   674  				},
   675  			},
   676  		},
   677  	})
   678  
   679  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive)
   680  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive)
   681  }
   682  
   683  func testSpotMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds(t *testing.T) {
   684  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   685  		Terms: &protoTypes.ProposalTerms{
   686  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   687  				NewSpotMarket: &protoTypes.NewSpotMarket{
   688  					Changes: &protoTypes.NewSpotMarketConfiguration{
   689  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   690  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   691  								{
   692  									Probability: "0.01",
   693  								},
   694  								{
   695  									Probability: "0.9",
   696  								},
   697  							},
   698  						},
   699  					},
   700  				},
   701  			},
   702  		},
   703  	})
   704  
   705  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.probability"),
   706  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   707  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.probability"),
   708  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   709  }
   710  
   711  func testSpotPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails(t *testing.T) {
   712  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   713  		Terms: &protoTypes.ProposalTerms{
   714  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   715  				NewSpotMarket: &protoTypes.NewSpotMarket{
   716  					Changes: &protoTypes.NewSpotMarketConfiguration{
   717  						Instrument: &protoTypes.InstrumentConfiguration{
   718  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   719  						},
   720  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   721  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   722  								{},
   723  								{},
   724  							},
   725  						},
   726  					},
   727  				},
   728  			},
   729  		},
   730  	})
   731  
   732  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive)
   733  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive)
   734  }
   735  
   736  func testSpotMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds(t *testing.T) {
   737  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   738  		Terms: &protoTypes.ProposalTerms{
   739  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   740  				NewSpotMarket: &protoTypes.NewSpotMarket{
   741  					Changes: &protoTypes.NewSpotMarketConfiguration{
   742  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   743  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   744  								{
   745  									AuctionExtension: test.RandomPositiveI64(),
   746  								},
   747  								{
   748  									AuctionExtension: test.RandomPositiveI64(),
   749  								},
   750  							},
   751  						},
   752  					},
   753  				},
   754  			},
   755  		},
   756  	})
   757  
   758  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive)
   759  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive)
   760  }
   761  
   762  func testNewSpotMarketChangeSubmissionWithoutPriceMonitoringSucceeds(t *testing.T) {
   763  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   764  		Terms: &protoTypes.ProposalTerms{
   765  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   766  				NewSpotMarket: &protoTypes.NewSpotMarket{
   767  					Changes: &protoTypes.NewSpotMarketConfiguration{},
   768  				},
   769  			},
   770  		},
   771  	})
   772  
   773  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters"), commands.ErrIsRequired)
   774  }
   775  
   776  func testNewSpotMarketChangeSubmissionWithPriceMonitoringSucceeds(t *testing.T) {
   777  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   778  		Terms: &protoTypes.ProposalTerms{
   779  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   780  				NewSpotMarket: &protoTypes.NewSpotMarket{
   781  					Changes: &protoTypes.NewSpotMarketConfiguration{
   782  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{},
   783  					},
   784  				},
   785  			},
   786  		},
   787  	})
   788  
   789  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.price_monitoring_parameters"), commands.ErrIsRequired)
   790  }
   791  
   792  func testNewSpotMarketChangeSubmissionWithoutInstrumentNameFails(t *testing.T) {
   793  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   794  		Terms: &protoTypes.ProposalTerms{
   795  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   796  				NewSpotMarket: &protoTypes.NewSpotMarket{
   797  					Changes: &protoTypes.NewSpotMarketConfiguration{
   798  						Instrument: &protoTypes.InstrumentConfiguration{
   799  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   800  							Name:    "",
   801  						},
   802  					},
   803  				},
   804  			},
   805  		},
   806  	})
   807  
   808  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.name"), commands.ErrIsRequired)
   809  }
   810  
   811  func testNewSpotMarketChangeSubmissionWithInstrumentNameSucceeds(t *testing.T) {
   812  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   813  		Terms: &protoTypes.ProposalTerms{
   814  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   815  				NewSpotMarket: &protoTypes.NewSpotMarket{
   816  					Changes: &protoTypes.NewSpotMarketConfiguration{
   817  						Instrument: &protoTypes.InstrumentConfiguration{
   818  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   819  							Name:    "My name",
   820  						},
   821  					},
   822  				},
   823  			},
   824  		},
   825  	})
   826  
   827  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.name"), commands.ErrIsRequired)
   828  }
   829  
   830  func testNewSpotMarketChangeSubmissionWithoutInstrumentCodeFails(t *testing.T) {
   831  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   832  		Terms: &protoTypes.ProposalTerms{
   833  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   834  				NewSpotMarket: &protoTypes.NewSpotMarket{
   835  					Changes: &protoTypes.NewSpotMarketConfiguration{
   836  						Instrument: &protoTypes.InstrumentConfiguration{
   837  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   838  							Code:    "",
   839  						},
   840  					},
   841  				},
   842  			},
   843  		},
   844  	})
   845  
   846  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.code"), commands.ErrIsRequired)
   847  }
   848  
   849  func testNewSpotMarketChangeSubmissionWithInstrumentCodeSucceeds(t *testing.T) {
   850  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   851  		Terms: &protoTypes.ProposalTerms{
   852  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   853  				NewSpotMarket: &protoTypes.NewSpotMarket{
   854  					Changes: &protoTypes.NewSpotMarketConfiguration{
   855  						Instrument: &protoTypes.InstrumentConfiguration{
   856  							Code: "My code",
   857  						},
   858  					},
   859  				},
   860  			},
   861  		},
   862  	})
   863  
   864  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.code"), commands.ErrIsRequired)
   865  }
   866  
   867  func testNewSpotMarketChangeSubmissionWithFutureProductFails(t *testing.T) {
   868  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   869  		Terms: &protoTypes.ProposalTerms{
   870  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   871  				NewSpotMarket: &protoTypes.NewSpotMarket{
   872  					Changes: &protoTypes.NewSpotMarketConfiguration{
   873  						Instrument: &protoTypes.InstrumentConfiguration{
   874  							Product: &protoTypes.InstrumentConfiguration_Future{},
   875  						},
   876  					},
   877  				},
   878  			},
   879  		},
   880  	})
   881  
   882  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product"), commands.ErrIsMismatching)
   883  }
   884  
   885  func testNewSpotMarketChangeSubmissionWithoutProductFails(t *testing.T) {
   886  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   887  		Terms: &protoTypes.ProposalTerms{
   888  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   889  				NewSpotMarket: &protoTypes.NewSpotMarket{
   890  					Changes: &protoTypes.NewSpotMarketConfiguration{
   891  						Instrument: &protoTypes.InstrumentConfiguration{},
   892  					},
   893  				},
   894  			},
   895  		},
   896  	})
   897  
   898  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product"), commands.ErrIsRequired)
   899  }
   900  
   901  func testNewSpotMarketChangeSubmissionWithProductSucceeds(t *testing.T) {
   902  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   903  		Terms: &protoTypes.ProposalTerms{
   904  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   905  				NewSpotMarket: &protoTypes.NewSpotMarket{
   906  					Changes: &protoTypes.NewSpotMarketConfiguration{
   907  						Instrument: &protoTypes.InstrumentConfiguration{
   908  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   909  						},
   910  					},
   911  				},
   912  			},
   913  		},
   914  	})
   915  
   916  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product"), commands.ErrIsRequired)
   917  }
   918  
   919  func testNewSpotMarketMarketChangeSubmissionWithoutSpotFails(t *testing.T) {
   920  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   921  		Terms: &protoTypes.ProposalTerms{
   922  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   923  				NewSpotMarket: &protoTypes.NewSpotMarket{
   924  					Changes: &protoTypes.NewSpotMarketConfiguration{
   925  						Instrument: &protoTypes.InstrumentConfiguration{
   926  							Product: &protoTypes.InstrumentConfiguration_Spot{},
   927  						},
   928  					},
   929  				},
   930  			},
   931  		},
   932  	})
   933  
   934  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot"), commands.ErrIsRequired)
   935  }
   936  
   937  func testNewSpotMarketMarketChangeSubmissionWithSpotSucceeds(t *testing.T) {
   938  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   939  		Terms: &protoTypes.ProposalTerms{
   940  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   941  				NewSpotMarket: &protoTypes.NewSpotMarket{
   942  					Changes: &protoTypes.NewSpotMarketConfiguration{
   943  						Instrument: &protoTypes.InstrumentConfiguration{
   944  							Product: &protoTypes.InstrumentConfiguration_Spot{
   945  								Spot: &protoTypes.SpotProduct{},
   946  							},
   947  						},
   948  					},
   949  				},
   950  			},
   951  		},
   952  	})
   953  
   954  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot"), commands.ErrIsRequired)
   955  }
   956  
   957  func testNewSpotMarketMarketChangeSubmissionWithoutEitherAssetFails(t *testing.T) {
   958  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   959  		Terms: &protoTypes.ProposalTerms{
   960  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   961  				NewSpotMarket: &protoTypes.NewSpotMarket{
   962  					Changes: &protoTypes.NewSpotMarketConfiguration{
   963  						Instrument: &protoTypes.InstrumentConfiguration{
   964  							Product: &protoTypes.InstrumentConfiguration_Spot{
   965  								Spot: &protoTypes.SpotProduct{
   966  									BaseAsset: "BTC",
   967  								},
   968  							},
   969  						},
   970  					},
   971  				},
   972  			},
   973  		},
   974  	})
   975  
   976  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot.quote_asset"), commands.ErrIsRequired)
   977  
   978  	err = checkProposalSubmission(&commandspb.ProposalSubmission{
   979  		Terms: &protoTypes.ProposalTerms{
   980  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
   981  				NewSpotMarket: &protoTypes.NewSpotMarket{
   982  					Changes: &protoTypes.NewSpotMarketConfiguration{
   983  						Instrument: &protoTypes.InstrumentConfiguration{
   984  							Product: &protoTypes.InstrumentConfiguration_Spot{
   985  								Spot: &protoTypes.SpotProduct{
   986  									QuoteAsset: "USDT",
   987  								},
   988  							},
   989  						},
   990  					},
   991  				},
   992  			},
   993  		},
   994  	})
   995  
   996  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot.base_asset"), commands.ErrIsRequired)
   997  }
   998  
   999  func testNewSpotMarketMarketChangeSubmissionWithBaseAndQuoteAssetsSucceeds(t *testing.T) {
  1000  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1001  		Terms: &protoTypes.ProposalTerms{
  1002  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1003  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1004  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1005  						Instrument: &protoTypes.InstrumentConfiguration{
  1006  							Product: &protoTypes.InstrumentConfiguration_Spot{
  1007  								Spot: &protoTypes.SpotProduct{
  1008  									BaseAsset:  "BTC",
  1009  									QuoteAsset: "USDT",
  1010  								},
  1011  							},
  1012  						},
  1013  					},
  1014  				},
  1015  			},
  1016  		},
  1017  	})
  1018  
  1019  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot.base_asset"), commands.ErrIsRequired)
  1020  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.instrument.product.spot.quote_asset"), commands.ErrIsRequired)
  1021  }
  1022  
  1023  func testNewSpotSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails(t *testing.T) {
  1024  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1025  		Terms: &protoTypes.ProposalTerms{
  1026  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1027  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1028  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1029  						Instrument: &protoTypes.InstrumentConfiguration{
  1030  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1031  						},
  1032  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{},
  1033  					},
  1034  				},
  1035  			},
  1036  		},
  1037  	})
  1038  
  1039  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple"), commands.ErrIsRequired)
  1040  }
  1041  
  1042  func testNewSpotSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds(t *testing.T) {
  1043  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1044  		Terms: &protoTypes.ProposalTerms{
  1045  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1046  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1047  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1048  						Instrument: &protoTypes.InstrumentConfiguration{
  1049  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1050  						},
  1051  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1052  							Simple: &protoTypes.SimpleModelParams{},
  1053  						},
  1054  					},
  1055  				},
  1056  			},
  1057  		},
  1058  	})
  1059  
  1060  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple"), commands.ErrIsRequired)
  1061  }
  1062  
  1063  func testNewSpotSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails(t *testing.T) {
  1064  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1065  		Terms: &protoTypes.ProposalTerms{
  1066  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1067  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1068  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1069  						Instrument: &protoTypes.InstrumentConfiguration{
  1070  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1071  						},
  1072  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1073  							Simple: &protoTypes.SimpleModelParams{
  1074  								MinMoveDown: 1,
  1075  							},
  1076  						},
  1077  					},
  1078  				},
  1079  			},
  1080  		},
  1081  	})
  1082  
  1083  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero)
  1084  }
  1085  
  1086  func testNewSpotSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds(t *testing.T) {
  1087  	testCases := []struct {
  1088  		msg   string
  1089  		value float64
  1090  	}{
  1091  		{
  1092  			msg:   "with min move down of 0",
  1093  			value: 0,
  1094  		}, {
  1095  			msg:   "with min move down of -1",
  1096  			value: -1,
  1097  		},
  1098  	}
  1099  	for _, tc := range testCases {
  1100  		t.Run(tc.msg, func(t *testing.T) {
  1101  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1102  				Terms: &protoTypes.ProposalTerms{
  1103  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1104  						NewSpotMarket: &protoTypes.NewSpotMarket{
  1105  							Changes: &protoTypes.NewSpotMarketConfiguration{
  1106  								Instrument: &protoTypes.InstrumentConfiguration{
  1107  									Product: &protoTypes.InstrumentConfiguration_Spot{},
  1108  								},
  1109  								RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1110  									Simple: &protoTypes.SimpleModelParams{
  1111  										MinMoveDown: tc.value,
  1112  									},
  1113  								},
  1114  							},
  1115  						},
  1116  					},
  1117  				},
  1118  			})
  1119  
  1120  			assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero)
  1121  		})
  1122  	}
  1123  }
  1124  
  1125  func testSpotNewSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails(t *testing.T) {
  1126  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1127  		Terms: &protoTypes.ProposalTerms{
  1128  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1129  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1130  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1131  						Instrument: &protoTypes.InstrumentConfiguration{
  1132  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1133  						},
  1134  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1135  							Simple: &protoTypes.SimpleModelParams{
  1136  								MaxMoveUp: -1,
  1137  							},
  1138  						},
  1139  					},
  1140  				},
  1141  			},
  1142  		},
  1143  	})
  1144  
  1145  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero)
  1146  }
  1147  
  1148  func testNewSpotSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails(t *testing.T) {
  1149  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1150  		Terms: &vegapb.ProposalTerms{
  1151  			Change: &vegapb.ProposalTerms_NewMarket{
  1152  				NewMarket: &vegapb.NewMarket{
  1153  					Changes: &vegapb.NewMarketConfiguration{
  1154  						RiskParameters: &vegapb.NewMarketConfiguration_Simple{
  1155  							Simple: &vegapb.SimpleModelParams{
  1156  								MaxMoveUp: -1,
  1157  							},
  1158  						},
  1159  					},
  1160  				},
  1161  			},
  1162  		},
  1163  	})
  1164  
  1165  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero)
  1166  }
  1167  
  1168  func testNewSpotSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds(t *testing.T) {
  1169  	testCases := []struct {
  1170  		msg   string
  1171  		value float64
  1172  	}{
  1173  		{
  1174  			msg:   "with max move up of 0",
  1175  			value: 0,
  1176  		}, {
  1177  			msg:   "with max move up of 1",
  1178  			value: 1,
  1179  		},
  1180  	}
  1181  	for _, tc := range testCases {
  1182  		t.Run(tc.msg, func(t *testing.T) {
  1183  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1184  				Terms: &protoTypes.ProposalTerms{
  1185  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1186  						NewSpotMarket: &protoTypes.NewSpotMarket{
  1187  							Changes: &protoTypes.NewSpotMarketConfiguration{
  1188  								Instrument: &protoTypes.InstrumentConfiguration{
  1189  									Product: &protoTypes.InstrumentConfiguration_Spot{},
  1190  								},
  1191  								RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1192  									Simple: &protoTypes.SimpleModelParams{
  1193  										MaxMoveUp: tc.value,
  1194  									},
  1195  								},
  1196  							},
  1197  						},
  1198  					},
  1199  				},
  1200  			})
  1201  
  1202  			assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero)
  1203  		})
  1204  	}
  1205  }
  1206  
  1207  func testNewSpotSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails(t *testing.T) {
  1208  	testCases := []struct {
  1209  		msg   string
  1210  		value float64
  1211  	}{
  1212  		{
  1213  			msg:   "with probability of trading of -1",
  1214  			value: -1,
  1215  		}, {
  1216  			msg:   "with probability of trading of 2",
  1217  			value: 2,
  1218  		},
  1219  	}
  1220  	for _, tc := range testCases {
  1221  		t.Run(tc.msg, func(t *testing.T) {
  1222  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1223  				Terms: &protoTypes.ProposalTerms{
  1224  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1225  						NewSpotMarket: &protoTypes.NewSpotMarket{
  1226  							Changes: &protoTypes.NewSpotMarketConfiguration{
  1227  								Instrument: &protoTypes.InstrumentConfiguration{
  1228  									Product: &protoTypes.InstrumentConfiguration_Spot{},
  1229  								},
  1230  								RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1231  									Simple: &protoTypes.SimpleModelParams{
  1232  										ProbabilityOfTrading: tc.value,
  1233  									},
  1234  								},
  1235  							},
  1236  						},
  1237  					},
  1238  				},
  1239  			})
  1240  
  1241  			assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.probability_of_trading"),
  1242  				errors.New("should be between 0 (inclusive) and 1 (inclusive)"))
  1243  		})
  1244  	}
  1245  }
  1246  
  1247  func testNewSpotSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds(t *testing.T) {
  1248  	testCases := []struct {
  1249  		msg   string
  1250  		value float64
  1251  	}{
  1252  		{
  1253  			msg:   "with probability of trading of 0",
  1254  			value: 0,
  1255  		}, {
  1256  			msg:   "with probability of trading of 1",
  1257  			value: 1,
  1258  		}, {
  1259  			msg:   "with probability of trading of 0.5",
  1260  			value: 0.5,
  1261  		},
  1262  	}
  1263  	for _, tc := range testCases {
  1264  		t.Run(tc.msg, func(t *testing.T) {
  1265  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1266  				Terms: &protoTypes.ProposalTerms{
  1267  					Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1268  						NewSpotMarket: &protoTypes.NewSpotMarket{
  1269  							Changes: &protoTypes.NewSpotMarketConfiguration{
  1270  								Instrument: &protoTypes.InstrumentConfiguration{
  1271  									Product: &protoTypes.InstrumentConfiguration_Spot{},
  1272  								},
  1273  								RiskParameters: &protoTypes.NewSpotMarketConfiguration_Simple{
  1274  									Simple: &protoTypes.SimpleModelParams{
  1275  										ProbabilityOfTrading: tc.value,
  1276  									},
  1277  								},
  1278  							},
  1279  						},
  1280  					},
  1281  				},
  1282  			})
  1283  
  1284  			assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.simple.probability_of_trading"),
  1285  				errors.New("should be between 0 (inclusive) and 1 (inclusive)"))
  1286  		})
  1287  	}
  1288  }
  1289  
  1290  func testNewSpotLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails(t *testing.T) {
  1291  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1292  		Terms: &protoTypes.ProposalTerms{
  1293  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1294  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1295  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1296  						Instrument: &protoTypes.InstrumentConfiguration{
  1297  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1298  						},
  1299  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{},
  1300  					},
  1301  				},
  1302  			},
  1303  		},
  1304  	})
  1305  
  1306  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired)
  1307  }
  1308  
  1309  func testNewSpotLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds(t *testing.T) {
  1310  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1311  		Terms: &protoTypes.ProposalTerms{
  1312  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1313  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1314  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1315  						Instrument: &protoTypes.InstrumentConfiguration{
  1316  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1317  						},
  1318  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1319  							LogNormal: &protoTypes.LogNormalRiskModel{
  1320  								RiskAversionParameter: 1,
  1321  								Tau:                   2,
  1322  								Params: &protoTypes.LogNormalModelParams{
  1323  									Mu:    0,
  1324  									Sigma: 0.1,
  1325  									R:     0,
  1326  								},
  1327  							},
  1328  						},
  1329  					},
  1330  				},
  1331  			},
  1332  		},
  1333  	})
  1334  
  1335  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired)
  1336  }
  1337  
  1338  func testNewSpotLogNormalRiskParametersChangeSubmissionWithoutParamsFails(t *testing.T) {
  1339  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1340  		Terms: &protoTypes.ProposalTerms{
  1341  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1342  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1343  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1344  						Instrument: &protoTypes.InstrumentConfiguration{
  1345  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1346  						},
  1347  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1348  							LogNormal: &protoTypes.LogNormalRiskModel{},
  1349  						},
  1350  					},
  1351  				},
  1352  			},
  1353  		},
  1354  	})
  1355  
  1356  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params"), commands.ErrIsRequired)
  1357  }
  1358  
  1359  func testNewSpotLogNormalRiskParametersChangeSubmissionInvalidRiskAversion(t *testing.T) {
  1360  	cTooSmall := &commandspb.ProposalSubmission{
  1361  		Terms: &protoTypes.ProposalTerms{
  1362  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1363  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1364  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1365  						Instrument: &protoTypes.InstrumentConfiguration{
  1366  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1367  						},
  1368  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1369  							LogNormal: &protoTypes.LogNormalRiskModel{
  1370  								RiskAversionParameter: 5e-9,
  1371  								Tau:                   1.0,
  1372  								Params: &protoTypes.LogNormalModelParams{
  1373  									Mu:    0.0,
  1374  									Sigma: 0.1,
  1375  									R:     0,
  1376  								},
  1377  							},
  1378  						},
  1379  					},
  1380  				},
  1381  			},
  1382  		},
  1383  	}
  1384  	err := checkProposalSubmission(cTooSmall)
  1385  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]"))
  1386  
  1387  	cNeg := &commandspb.ProposalSubmission{
  1388  		Terms: &protoTypes.ProposalTerms{
  1389  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1390  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1391  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1392  						Instrument: &protoTypes.InstrumentConfiguration{
  1393  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1394  						},
  1395  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1396  							LogNormal: &protoTypes.LogNormalRiskModel{
  1397  								RiskAversionParameter: 1e-9,
  1398  								Tau:                   2,
  1399  								Params: &protoTypes.LogNormalModelParams{
  1400  									Mu:    0,
  1401  									Sigma: 0.1,
  1402  									R:     0,
  1403  								},
  1404  							},
  1405  						},
  1406  					},
  1407  				},
  1408  			},
  1409  		},
  1410  	}
  1411  	err = checkProposalSubmission(cNeg)
  1412  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]"))
  1413  
  1414  	cTooBig := &commandspb.ProposalSubmission{
  1415  		Terms: &protoTypes.ProposalTerms{
  1416  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1417  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1418  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1419  						Instrument: &protoTypes.InstrumentConfiguration{
  1420  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1421  						},
  1422  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1423  							LogNormal: &protoTypes.LogNormalRiskModel{
  1424  								RiskAversionParameter: 0.1 + 1e-8,
  1425  								Tau:                   2,
  1426  								Params: &protoTypes.LogNormalModelParams{
  1427  									Mu:    0,
  1428  									Sigma: 0.1,
  1429  									R:     0,
  1430  								},
  1431  							},
  1432  						},
  1433  					},
  1434  				},
  1435  			},
  1436  		},
  1437  	}
  1438  	err = checkProposalSubmission(cTooBig)
  1439  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 0.1]"))
  1440  
  1441  	cJustAboutRight1 := &commandspb.ProposalSubmission{
  1442  		Terms: &protoTypes.ProposalTerms{
  1443  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1444  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1445  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1446  						Instrument: &protoTypes.InstrumentConfiguration{
  1447  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1448  						},
  1449  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1450  							LogNormal: &protoTypes.LogNormalRiskModel{
  1451  								RiskAversionParameter: 1e-8,
  1452  								Tau:                   2,
  1453  								Params: &protoTypes.LogNormalModelParams{
  1454  									Mu:    0,
  1455  									Sigma: 0.1,
  1456  									R:     0,
  1457  								},
  1458  							},
  1459  						},
  1460  					},
  1461  				},
  1462  			},
  1463  		},
  1464  	}
  1465  	err = checkProposalSubmission(cJustAboutRight1)
  1466  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 1)"))
  1467  
  1468  	cJustAboutRight2 := &commandspb.ProposalSubmission{
  1469  		Terms: &protoTypes.ProposalTerms{
  1470  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1471  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1472  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1473  						Instrument: &protoTypes.InstrumentConfiguration{
  1474  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1475  						},
  1476  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1477  							LogNormal: &protoTypes.LogNormalRiskModel{
  1478  								RiskAversionParameter: 1 - 1e-12,
  1479  								Tau:                   2,
  1480  								Params: &protoTypes.LogNormalModelParams{
  1481  									Mu:    0,
  1482  									Sigma: 0.1,
  1483  									R:     0,
  1484  								},
  1485  							},
  1486  						},
  1487  					},
  1488  				},
  1489  			},
  1490  		},
  1491  	}
  1492  	err = checkProposalSubmission(cJustAboutRight2)
  1493  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), errors.New("must be between [1e-8, 1)"))
  1494  }
  1495  
  1496  func testNewSpotLogNormalRiskParametersChangeSubmissionInvalidTau(t *testing.T) {
  1497  	cZero := &commandspb.ProposalSubmission{
  1498  		Terms: &protoTypes.ProposalTerms{
  1499  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1500  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1501  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1502  						Instrument: &protoTypes.InstrumentConfiguration{
  1503  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1504  						},
  1505  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1506  							LogNormal: &protoTypes.LogNormalRiskModel{
  1507  								RiskAversionParameter: 0.1,
  1508  								Tau:                   0,
  1509  								Params: &protoTypes.LogNormalModelParams{
  1510  									Mu:    0,
  1511  									Sigma: 0.1,
  1512  									R:     0,
  1513  								},
  1514  							},
  1515  						},
  1516  					},
  1517  				},
  1518  			},
  1519  		},
  1520  	}
  1521  	err := checkProposalSubmission(cZero)
  1522  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]"))
  1523  
  1524  	cNeg := &commandspb.ProposalSubmission{
  1525  		Terms: &protoTypes.ProposalTerms{
  1526  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1527  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1528  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1529  						Instrument: &protoTypes.InstrumentConfiguration{
  1530  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1531  						},
  1532  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1533  							LogNormal: &protoTypes.LogNormalRiskModel{
  1534  								RiskAversionParameter: 0.1,
  1535  								Tau:                   1e-9,
  1536  								Params: &protoTypes.LogNormalModelParams{
  1537  									Mu:    0,
  1538  									Sigma: 0.1,
  1539  									R:     0,
  1540  								},
  1541  							},
  1542  						},
  1543  					},
  1544  				},
  1545  			},
  1546  		},
  1547  	}
  1548  	err = checkProposalSubmission(cNeg)
  1549  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]"))
  1550  
  1551  	cTooLarge := &commandspb.ProposalSubmission{
  1552  		Terms: &protoTypes.ProposalTerms{
  1553  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1554  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1555  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1556  						Instrument: &protoTypes.InstrumentConfiguration{
  1557  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1558  						},
  1559  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1560  							LogNormal: &protoTypes.LogNormalRiskModel{
  1561  								RiskAversionParameter: 0.1,
  1562  								Tau:                   1 + 1e-12,
  1563  								Params: &protoTypes.LogNormalModelParams{
  1564  									Mu:    0,
  1565  									Sigma: 0.1,
  1566  									R:     0,
  1567  								},
  1568  							},
  1569  						},
  1570  					},
  1571  				},
  1572  			},
  1573  		},
  1574  	}
  1575  	err = checkProposalSubmission(cTooLarge)
  1576  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between [1e-8, 1]"))
  1577  
  1578  	cJustAboutRight1 := &commandspb.ProposalSubmission{
  1579  		Terms: &protoTypes.ProposalTerms{
  1580  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1581  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1582  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1583  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1584  							LogNormal: &protoTypes.LogNormalRiskModel{
  1585  								RiskAversionParameter: 0.1,
  1586  								Tau:                   1e-12,
  1587  								Params: &protoTypes.LogNormalModelParams{
  1588  									Mu:    0,
  1589  									Sigma: 0.1,
  1590  									R:     0,
  1591  								},
  1592  							},
  1593  						},
  1594  					},
  1595  				},
  1596  			},
  1597  		},
  1598  	}
  1599  	err = checkProposalSubmission(cJustAboutRight1)
  1600  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between (0, 1]"))
  1601  
  1602  	cJustAboutRight2 := &commandspb.ProposalSubmission{
  1603  		Terms: &protoTypes.ProposalTerms{
  1604  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1605  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1606  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1607  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1608  							LogNormal: &protoTypes.LogNormalRiskModel{
  1609  								RiskAversionParameter: 0.1,
  1610  								Tau:                   1,
  1611  								Params: &protoTypes.LogNormalModelParams{
  1612  									Mu:    0,
  1613  									Sigma: 0.1,
  1614  									R:     0,
  1615  								},
  1616  							},
  1617  						},
  1618  					},
  1619  				},
  1620  			},
  1621  		},
  1622  	}
  1623  	err = checkProposalSubmission(cJustAboutRight2)
  1624  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.tau"), errors.New("must be between (0, 1]"))
  1625  }
  1626  
  1627  func testNewSpotLogNormalRiskParametersChangeSubmissionInvalidMu(t *testing.T) {
  1628  	cNaN := &commandspb.ProposalSubmission{
  1629  		Terms: &protoTypes.ProposalTerms{
  1630  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1631  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1632  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1633  						Instrument: &protoTypes.InstrumentConfiguration{
  1634  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1635  						},
  1636  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1637  							LogNormal: &protoTypes.LogNormalRiskModel{
  1638  								RiskAversionParameter: 0.1,
  1639  								Tau:                   0.2,
  1640  								Params: &protoTypes.LogNormalModelParams{
  1641  									Mu:    math.NaN(),
  1642  									Sigma: 0.1,
  1643  									R:     0,
  1644  								},
  1645  							},
  1646  						},
  1647  					},
  1648  				},
  1649  			},
  1650  		},
  1651  	}
  1652  	err := checkProposalSubmission(cNaN)
  1653  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.mu"), commands.ErrIsNotValidNumber)
  1654  
  1655  	cTooSmall := &commandspb.ProposalSubmission{
  1656  		Terms: &protoTypes.ProposalTerms{
  1657  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1658  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1659  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1660  						Instrument: &protoTypes.InstrumentConfiguration{
  1661  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1662  						},
  1663  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1664  							LogNormal: &protoTypes.LogNormalRiskModel{
  1665  								RiskAversionParameter: 0.1,
  1666  								Tau:                   0.2,
  1667  								Params: &protoTypes.LogNormalModelParams{
  1668  									Mu:    -1e-6 - 1e-12,
  1669  									Sigma: 0.1,
  1670  									R:     0,
  1671  								},
  1672  							},
  1673  						},
  1674  					},
  1675  				},
  1676  			},
  1677  		},
  1678  	}
  1679  	err = checkProposalSubmission(cTooSmall)
  1680  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-1e-6,1e-6]"))
  1681  
  1682  	cTooLarge := &commandspb.ProposalSubmission{
  1683  		Terms: &protoTypes.ProposalTerms{
  1684  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1685  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1686  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1687  						Instrument: &protoTypes.InstrumentConfiguration{
  1688  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1689  						},
  1690  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1691  							LogNormal: &protoTypes.LogNormalRiskModel{
  1692  								RiskAversionParameter: 0.1,
  1693  								Tau:                   0.2,
  1694  								Params: &protoTypes.LogNormalModelParams{
  1695  									Mu:    1e-6 + 1e-12,
  1696  									Sigma: 0.1,
  1697  									R:     0,
  1698  								},
  1699  							},
  1700  						},
  1701  					},
  1702  				},
  1703  			},
  1704  		},
  1705  	}
  1706  	err = checkProposalSubmission(cTooLarge)
  1707  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-1e-6,1e-6]"))
  1708  
  1709  	cJustAboutRight1 := &commandspb.ProposalSubmission{
  1710  		Terms: &protoTypes.ProposalTerms{
  1711  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1712  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1713  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1714  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1715  							LogNormal: &protoTypes.LogNormalRiskModel{
  1716  								RiskAversionParameter: 0.1,
  1717  								Tau:                   0.2,
  1718  								Params: &protoTypes.LogNormalModelParams{
  1719  									Mu:    -20,
  1720  									Sigma: 0.1,
  1721  									R:     0,
  1722  								},
  1723  							},
  1724  						},
  1725  					},
  1726  				},
  1727  			},
  1728  		},
  1729  	}
  1730  	err = checkProposalSubmission(cJustAboutRight1)
  1731  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-20,20]"))
  1732  
  1733  	cJustAboutRight2 := &commandspb.ProposalSubmission{
  1734  		Terms: &protoTypes.ProposalTerms{
  1735  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1736  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1737  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1738  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1739  							LogNormal: &protoTypes.LogNormalRiskModel{
  1740  								RiskAversionParameter: 0.1,
  1741  								Tau:                   0.2,
  1742  								Params: &protoTypes.LogNormalModelParams{
  1743  									Mu:    20,
  1744  									Sigma: 0.1,
  1745  									R:     0,
  1746  								},
  1747  							},
  1748  						},
  1749  					},
  1750  				},
  1751  			},
  1752  		},
  1753  	}
  1754  	err = checkProposalSubmission(cJustAboutRight2)
  1755  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.mu"), errors.New("must be between [-20,20]"))
  1756  }
  1757  
  1758  func testNewSpotLogNormalRiskParametersChangeSubmissionInvalidR(t *testing.T) {
  1759  	cNaN := &commandspb.ProposalSubmission{
  1760  		Terms: &protoTypes.ProposalTerms{
  1761  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1762  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1763  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1764  						Instrument: &protoTypes.InstrumentConfiguration{
  1765  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1766  						},
  1767  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1768  							LogNormal: &protoTypes.LogNormalRiskModel{
  1769  								RiskAversionParameter: 0.1,
  1770  								Tau:                   0.2,
  1771  								Params: &protoTypes.LogNormalModelParams{
  1772  									Mu:    0.0,
  1773  									Sigma: 0.1,
  1774  									R:     math.NaN(),
  1775  								},
  1776  							},
  1777  						},
  1778  					},
  1779  				},
  1780  			},
  1781  		},
  1782  	}
  1783  	err := checkProposalSubmission(cNaN)
  1784  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.r"), commands.ErrIsNotValidNumber)
  1785  
  1786  	cTooSmall := &commandspb.ProposalSubmission{
  1787  		Terms: &protoTypes.ProposalTerms{
  1788  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1789  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1790  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1791  						Instrument: &protoTypes.InstrumentConfiguration{
  1792  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1793  						},
  1794  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1795  							LogNormal: &protoTypes.LogNormalRiskModel{
  1796  								RiskAversionParameter: 0.1,
  1797  								Tau:                   0.2,
  1798  								Params: &protoTypes.LogNormalModelParams{
  1799  									Mu:    0.0,
  1800  									Sigma: 0.1,
  1801  									R:     -1 - 1e-12,
  1802  								},
  1803  							},
  1804  						},
  1805  					},
  1806  				},
  1807  			},
  1808  		},
  1809  	}
  1810  	err = checkProposalSubmission(cTooSmall)
  1811  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-1,1]"))
  1812  
  1813  	cTooLarge := &commandspb.ProposalSubmission{
  1814  		Terms: &protoTypes.ProposalTerms{
  1815  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1816  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1817  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1818  						Instrument: &protoTypes.InstrumentConfiguration{
  1819  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1820  						},
  1821  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1822  							LogNormal: &protoTypes.LogNormalRiskModel{
  1823  								RiskAversionParameter: 0.1,
  1824  								Tau:                   0.2,
  1825  								Params: &protoTypes.LogNormalModelParams{
  1826  									Mu:    0.0,
  1827  									Sigma: 0.1,
  1828  									R:     1 + 1e-12,
  1829  								},
  1830  							},
  1831  						},
  1832  					},
  1833  				},
  1834  			},
  1835  		},
  1836  	}
  1837  	err = checkProposalSubmission(cTooLarge)
  1838  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-1,1]"))
  1839  
  1840  	cJustAboutRight1 := &commandspb.ProposalSubmission{
  1841  		Terms: &protoTypes.ProposalTerms{
  1842  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1843  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1844  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1845  						Instrument: &protoTypes.InstrumentConfiguration{
  1846  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1847  						},
  1848  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1849  							LogNormal: &protoTypes.LogNormalRiskModel{
  1850  								RiskAversionParameter: 0.1,
  1851  								Tau:                   0.2,
  1852  								Params: &protoTypes.LogNormalModelParams{
  1853  									Mu:    0.0,
  1854  									Sigma: 0.1,
  1855  									R:     -20,
  1856  								},
  1857  							},
  1858  						},
  1859  					},
  1860  				},
  1861  			},
  1862  		},
  1863  	}
  1864  	err = checkProposalSubmission(cJustAboutRight1)
  1865  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-20,20]"))
  1866  
  1867  	cJustAboutRight2 := &commandspb.ProposalSubmission{
  1868  		Terms: &protoTypes.ProposalTerms{
  1869  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1870  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1871  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1872  						Instrument: &protoTypes.InstrumentConfiguration{
  1873  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1874  						},
  1875  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1876  							LogNormal: &protoTypes.LogNormalRiskModel{
  1877  								RiskAversionParameter: 0.1,
  1878  								Tau:                   0.2,
  1879  								Params: &protoTypes.LogNormalModelParams{
  1880  									Mu:    0.0,
  1881  									Sigma: 0.1,
  1882  									R:     20,
  1883  								},
  1884  							},
  1885  						},
  1886  					},
  1887  				},
  1888  			},
  1889  		},
  1890  	}
  1891  	err = checkProposalSubmission(cJustAboutRight2)
  1892  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.r"), errors.New("must be between [-20,20]"))
  1893  }
  1894  
  1895  func testNewSpotLogNormalRiskParametersChangeSubmissionInvalidSigma(t *testing.T) {
  1896  	cNaN := &commandspb.ProposalSubmission{
  1897  		Terms: &protoTypes.ProposalTerms{
  1898  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1899  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1900  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1901  						Instrument: &protoTypes.InstrumentConfiguration{
  1902  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1903  						},
  1904  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1905  							LogNormal: &protoTypes.LogNormalRiskModel{
  1906  								RiskAversionParameter: 0.1,
  1907  								Tau:                   0.2,
  1908  								Params: &protoTypes.LogNormalModelParams{
  1909  									Mu:    0.0,
  1910  									Sigma: math.NaN(),
  1911  									R:     0,
  1912  								},
  1913  							},
  1914  						},
  1915  					},
  1916  				},
  1917  			},
  1918  		},
  1919  	}
  1920  	err := checkProposalSubmission(cNaN)
  1921  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrIsNotValidNumber)
  1922  
  1923  	cNeg := &commandspb.ProposalSubmission{
  1924  		Terms: &protoTypes.ProposalTerms{
  1925  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1926  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1927  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1928  						Instrument: &protoTypes.InstrumentConfiguration{
  1929  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1930  						},
  1931  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1932  							LogNormal: &protoTypes.LogNormalRiskModel{
  1933  								RiskAversionParameter: 0.1,
  1934  								Tau:                   0.2,
  1935  								Params: &protoTypes.LogNormalModelParams{
  1936  									Mu:    0.0,
  1937  									Sigma: 1e-4,
  1938  									R:     0,
  1939  								},
  1940  							},
  1941  						},
  1942  					},
  1943  				},
  1944  			},
  1945  		},
  1946  	}
  1947  	err = checkProposalSubmission(cNeg)
  1948  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]"))
  1949  
  1950  	cTooSmall := &commandspb.ProposalSubmission{
  1951  		Terms: &protoTypes.ProposalTerms{
  1952  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1953  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1954  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1955  						Instrument: &protoTypes.InstrumentConfiguration{
  1956  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1957  						},
  1958  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1959  							LogNormal: &protoTypes.LogNormalRiskModel{
  1960  								RiskAversionParameter: 0.1,
  1961  								Tau:                   0.2,
  1962  								Params: &protoTypes.LogNormalModelParams{
  1963  									Mu:    0.0,
  1964  									Sigma: 1e-3 - 1e-12,
  1965  									R:     0,
  1966  								},
  1967  							},
  1968  						},
  1969  					},
  1970  				},
  1971  			},
  1972  		},
  1973  	}
  1974  	err = checkProposalSubmission(cTooSmall)
  1975  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]"))
  1976  
  1977  	cTooLarge := &commandspb.ProposalSubmission{
  1978  		Terms: &protoTypes.ProposalTerms{
  1979  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  1980  				NewSpotMarket: &protoTypes.NewSpotMarket{
  1981  					Changes: &protoTypes.NewSpotMarketConfiguration{
  1982  						Instrument: &protoTypes.InstrumentConfiguration{
  1983  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  1984  						},
  1985  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  1986  							LogNormal: &protoTypes.LogNormalRiskModel{
  1987  								RiskAversionParameter: 0.1,
  1988  								Tau:                   0.2,
  1989  								Params: &protoTypes.LogNormalModelParams{
  1990  									Mu:    0.0,
  1991  									Sigma: 50 + 1e-12,
  1992  									R:     0,
  1993  								},
  1994  							},
  1995  						},
  1996  					},
  1997  				},
  1998  			},
  1999  		},
  2000  	}
  2001  	err = checkProposalSubmission(cTooLarge)
  2002  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-3,50]"))
  2003  
  2004  	cJustAboutRight1 := &commandspb.ProposalSubmission{
  2005  		Terms: &protoTypes.ProposalTerms{
  2006  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2007  				NewSpotMarket: &protoTypes.NewSpotMarket{
  2008  					Changes: &protoTypes.NewSpotMarketConfiguration{
  2009  						Instrument: &protoTypes.InstrumentConfiguration{
  2010  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  2011  						},
  2012  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  2013  							LogNormal: &protoTypes.LogNormalRiskModel{
  2014  								RiskAversionParameter: 0.1,
  2015  								Tau:                   0.2,
  2016  								Params: &protoTypes.LogNormalModelParams{
  2017  									Mu:    0.0,
  2018  									Sigma: 1e-4,
  2019  									R:     0,
  2020  								},
  2021  							},
  2022  						},
  2023  					},
  2024  				},
  2025  			},
  2026  		},
  2027  	}
  2028  	err = checkProposalSubmission(cJustAboutRight1)
  2029  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-4,100]"))
  2030  
  2031  	cJustAboutRight2 := &commandspb.ProposalSubmission{
  2032  		Terms: &protoTypes.ProposalTerms{
  2033  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2034  				NewSpotMarket: &protoTypes.NewSpotMarket{
  2035  					Changes: &protoTypes.NewSpotMarketConfiguration{
  2036  						Instrument: &protoTypes.InstrumentConfiguration{
  2037  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  2038  						},
  2039  						RiskParameters: &protoTypes.NewSpotMarketConfiguration_LogNormal{
  2040  							LogNormal: &protoTypes.LogNormalRiskModel{
  2041  								RiskAversionParameter: 0.1,
  2042  								Tau:                   0.2,
  2043  								Params: &protoTypes.LogNormalModelParams{
  2044  									Mu:    0.0,
  2045  									Sigma: 50,
  2046  									R:     0,
  2047  								},
  2048  							},
  2049  						},
  2050  					},
  2051  				},
  2052  			},
  2053  		},
  2054  	}
  2055  	err = checkProposalSubmission(cJustAboutRight2)
  2056  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.risk_parameters.log_normal.params.sigma"), errors.New("must be between [1e-4,100]"))
  2057  }
  2058  
  2059  func testNewSpotMarketSubmissionWithTooLongReferenceFails(t *testing.T) {
  2060  	ref := make([]byte, 101)
  2061  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2062  		Reference: string(ref),
  2063  	})
  2064  	assert.Contains(t, err.Get("proposal_submission.reference"), commands.ErrReferenceTooLong)
  2065  }
  2066  
  2067  func testNewSpotMarketChangeSubmissionWithValidLpRangeSucceeds(t *testing.T) {
  2068  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2069  		Terms: &protoTypes.ProposalTerms{
  2070  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2071  				NewSpotMarket: &protoTypes.NewSpotMarket{
  2072  					Changes: &protoTypes.NewSpotMarketConfiguration{
  2073  						Instrument: &protoTypes.InstrumentConfiguration{
  2074  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  2075  						},
  2076  						SlaParams: &protoTypes.LiquiditySLAParameters{
  2077  							PriceRange: "50",
  2078  						},
  2079  					},
  2080  				},
  2081  			},
  2082  		},
  2083  	})
  2084  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBePositive, commands.ErrMustBePositive, commands.ErrMustBeAtMost100}
  2085  	for _, e := range errors {
  2086  		assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.price_range"), e)
  2087  	}
  2088  }
  2089  
  2090  func testNewSpotMarketChangeSubmissionWithInvalidLpRangeFails(t *testing.T) {
  2091  	priceRanges := []string{"banana", "-1", "0", "101"}
  2092  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20}
  2093  
  2094  	for i, v := range priceRanges {
  2095  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2096  			Terms: &protoTypes.ProposalTerms{
  2097  				Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2098  					NewSpotMarket: &protoTypes.NewSpotMarket{
  2099  						Changes: &protoTypes.NewSpotMarketConfiguration{
  2100  							Instrument: &protoTypes.InstrumentConfiguration{
  2101  								Product: &protoTypes.InstrumentConfiguration_Spot{},
  2102  							},
  2103  							SlaParams: &protoTypes.LiquiditySLAParameters{
  2104  								PriceRange: v,
  2105  							},
  2106  						},
  2107  					},
  2108  				},
  2109  			},
  2110  		})
  2111  		assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.price_range"), errors[i])
  2112  	}
  2113  }
  2114  
  2115  func testNewSpotMarketChangeSubmissionWithInvalidMinTimeFractionFails(t *testing.T) {
  2116  	minTimeFraction := []string{"banana", "-1", "-1.1", "1.1", "100"}
  2117  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01}
  2118  
  2119  	for i, v := range minTimeFraction {
  2120  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2121  			Terms: &protoTypes.ProposalTerms{
  2122  				Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2123  					NewSpotMarket: &protoTypes.NewSpotMarket{
  2124  						Changes: &protoTypes.NewSpotMarketConfiguration{
  2125  							Instrument: &protoTypes.InstrumentConfiguration{
  2126  								Product: &protoTypes.InstrumentConfiguration_Spot{},
  2127  							},
  2128  							SlaParams: &protoTypes.LiquiditySLAParameters{
  2129  								CommitmentMinTimeFraction: v,
  2130  							},
  2131  						},
  2132  					},
  2133  				},
  2134  			},
  2135  		})
  2136  		assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.commitment_min_time_fraction"), errors[i])
  2137  	}
  2138  }
  2139  
  2140  func testNewSpotMarketChangeSubmissionWithValidMinTimeFractionSucceeds(t *testing.T) {
  2141  	minTimeFraction := []string{"0", "0.1", "0.99", "1"}
  2142  
  2143  	for _, v := range minTimeFraction {
  2144  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2145  			Terms: &protoTypes.ProposalTerms{
  2146  				Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2147  					NewSpotMarket: &protoTypes.NewSpotMarket{
  2148  						Changes: &protoTypes.NewSpotMarketConfiguration{
  2149  							Instrument: &protoTypes.InstrumentConfiguration{
  2150  								Product: &protoTypes.InstrumentConfiguration_Spot{},
  2151  							},
  2152  							SlaParams: &protoTypes.LiquiditySLAParameters{
  2153  								CommitmentMinTimeFraction: v,
  2154  							},
  2155  						},
  2156  					},
  2157  				},
  2158  			},
  2159  		})
  2160  
  2161  		errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01}
  2162  		for _, e := range errors {
  2163  			assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.commitment_min_time_fraction"), e)
  2164  		}
  2165  	}
  2166  }
  2167  
  2168  func testNewSpotMarketChangeSubmissionWithInvalidCompetitionFactorFails(t *testing.T) {
  2169  	competitionFactors := []string{"banana", "-1", "-1.1", "1.1", "100"}
  2170  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01}
  2171  
  2172  	for i, v := range competitionFactors {
  2173  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2174  			Terms: &protoTypes.ProposalTerms{
  2175  				Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2176  					NewSpotMarket: &protoTypes.NewSpotMarket{
  2177  						Changes: &protoTypes.NewSpotMarketConfiguration{
  2178  							Instrument: &protoTypes.InstrumentConfiguration{
  2179  								Product: &protoTypes.InstrumentConfiguration_Spot{},
  2180  							},
  2181  							SlaParams: &protoTypes.LiquiditySLAParameters{
  2182  								SlaCompetitionFactor: v,
  2183  							},
  2184  						},
  2185  					},
  2186  				},
  2187  			},
  2188  		})
  2189  		assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.sla_competition_factor"), errors[i])
  2190  	}
  2191  }
  2192  
  2193  func testNewSpotMarketChangeSubmissionWithValidCompetitionFactorSucceeds(t *testing.T) {
  2194  	minTimeFraction := []string{"0", "0.1", "0.99", "1"}
  2195  
  2196  	for _, v := range minTimeFraction {
  2197  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2198  			Terms: &protoTypes.ProposalTerms{
  2199  				Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2200  					NewSpotMarket: &protoTypes.NewSpotMarket{
  2201  						Changes: &protoTypes.NewSpotMarketConfiguration{
  2202  							Instrument: &protoTypes.InstrumentConfiguration{
  2203  								Product: &protoTypes.InstrumentConfiguration_Spot{},
  2204  							},
  2205  							SlaParams: &protoTypes.LiquiditySLAParameters{
  2206  								SlaCompetitionFactor: v,
  2207  							},
  2208  						},
  2209  					},
  2210  				},
  2211  			},
  2212  		})
  2213  
  2214  		errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01}
  2215  		for _, e := range errors {
  2216  			assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.sla_competition_factor"), e)
  2217  		}
  2218  	}
  2219  }
  2220  
  2221  func testNewSpotMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails(t *testing.T) {
  2222  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2223  		Terms: &protoTypes.ProposalTerms{
  2224  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2225  				NewSpotMarket: &protoTypes.NewSpotMarket{
  2226  					Changes: &protoTypes.NewSpotMarketConfiguration{
  2227  						Instrument: &protoTypes.InstrumentConfiguration{
  2228  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  2229  						},
  2230  						SlaParams: &protoTypes.LiquiditySLAParameters{
  2231  							PerformanceHysteresisEpochs: 367,
  2232  						},
  2233  					},
  2234  				},
  2235  			},
  2236  		},
  2237  	})
  2238  	assert.Contains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBeLessThen366)
  2239  }
  2240  
  2241  func testNewSpotMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds(t *testing.T) {
  2242  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  2243  		Terms: &protoTypes.ProposalTerms{
  2244  			Change: &protoTypes.ProposalTerms_NewSpotMarket{
  2245  				NewSpotMarket: &protoTypes.NewSpotMarket{
  2246  					Changes: &protoTypes.NewSpotMarketConfiguration{
  2247  						Instrument: &protoTypes.InstrumentConfiguration{
  2248  							Product: &protoTypes.InstrumentConfiguration_Spot{},
  2249  						},
  2250  						SlaParams: &protoTypes.LiquiditySLAParameters{
  2251  							PerformanceHysteresisEpochs: 1,
  2252  						},
  2253  					},
  2254  				},
  2255  			},
  2256  		},
  2257  	})
  2258  
  2259  	assert.NotContains(t, err.Get("proposal_submission.terms.change.new_spot_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBePositive)
  2260  }