code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_update_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  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  func TestCheckProposalSubmissionForUpdateSpotMarket(t *testing.T) {
    33  	t.Run("Submitting a market change without update market fails", testUpdateSpotMarketChangeSubmissionWithoutUpdateMarketFails)
    34  	t.Run("Submitting a market change without changes fails", testUpdateSpotMarketChangeSubmissionWithoutChangesFails)
    35  	t.Run("Submitting a market change without decimal places succeeds", testUpdateSpotMarketChangeSubmissionWithoutDecimalPlacesSucceeds)
    36  	t.Run("Submitting a update market without price monitoring succeeds", testUpdateSpotMarketChangeSubmissionWithoutPriceMonitoringSucceeds)
    37  	t.Run("Submitting a update market with price monitoring succeeds", testUpdateSpotMarketChangeSubmissionWithPriceMonitoringSucceeds)
    38  	t.Run("Submitting a price monitoring change without triggers succeeds", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggersSucceeds)
    39  	t.Run("Submitting a price monitoring change with triggers succeeds", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggersSucceeds)
    40  	t.Run("Submitting a price monitoring change without trigger horizon fails", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails)
    41  	t.Run("Submitting a price monitoring change with trigger horizon succeeds", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds)
    42  	t.Run("Submitting a price monitoring change with wrong trigger probability fails", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails)
    43  	t.Run("Submitting a price monitoring change with right trigger probability succeeds", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds)
    44  	t.Run("Submitting a price monitoring change without trigger auction extension fails", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails)
    45  	t.Run("Submitting a price monitoring change with trigger auction extension succeeds", testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds)
    46  	t.Run("Submitting a update market without liquidity monitoring succeeds", testUpdateSpotMarketChangeSubmissionWithoutLiquidityMonitoringSucceeds)
    47  	t.Run("Submitting a simple risk parameters change without simple risk parameters fails", testUpdateSpotSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails)
    48  	t.Run("Submitting a simple risk parameters change with simple risk parameters succeeds", testUpdateSpotSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds)
    49  	t.Run("Submitting a simple risk parameters change with min move down fails", testUpdateSpotSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails)
    50  	t.Run("Submitting a simple risk parameters change with min move down succeeds", testUpdateSpotSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds)
    51  	t.Run("Submitting a simple risk parameters change with max move up fails", testUpdateSpotSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails)
    52  	t.Run("Submitting a simple risk parameters change with max move up succeeds", testUpdateSpotSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds)
    53  	t.Run("Submitting a simple risk parameters change with wrong probability of trading fails", testUpdateSpotSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails)
    54  	t.Run("Submitting a simple risk parameters change with right probability of trading succeeds", testUpdateSpotSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds)
    55  	t.Run("Submitting a log normal risk parameters change without log normal risk parameters fails", testUpdateSpotLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails)
    56  	t.Run("Submitting a log normal risk parameters change with log normal risk parameters succeeds", testUpdateSpotLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds)
    57  	t.Run("Submitting a log normal risk parameters change with params fails", testUpdateSpotLogNormalRiskParametersChangeSubmissionWithoutParamsFails)
    58  	t.Run("Submitting a log normal risk parameters change with invalid risk aversion", testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidRiskAversion)
    59  	t.Run("Submitting a log normal risk parameters change with invalid tau", testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidTau)
    60  	t.Run("Submitting a log normal risk parameters change with invalid mu", testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidMu)
    61  	t.Run("Submitting a log normal risk parameters change with invalid sigma", testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidSigma)
    62  	t.Run("Submitting a log normal risk parameters change with invalid r", testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidR)
    63  	t.Run("Submitting a spot market update with a too long reference fails", testUpdateSpotMarketSubmissionWithTooLongReferenceFails)
    64  	t.Run("Submitting a spot market update with market ID succeeds", testUpdateSpotMarketWithMarketIDSucceeds)
    65  	t.Run("Submitting a spot market update without market ID fails", testUpdateSpotMarketWithoutMarketIDFails)
    66  	t.Run("Submitting a spot market update without target stake parameters fails", testUpdateSpotMarketWithoutTargetStakeParametersFails)
    67  	t.Run("Submitting a spot market update with a target stake parameters with non positive time window fails", testUpdateSpotMarketTargetStakeParamsWithNonPositiveTimeWindowFails)
    68  	t.Run("Submitting a spot market update with a target stake parameters with positive time window succeeds", testUpdateSpotMarketWithTargetStakeParamsPositiveTimeWindowSucceeds)
    69  	t.Run("Submitting a spot market update with a target stake parameters with non positive scaling factor fails", testUpdateSpotMarketWithTargetStakeParamsNonPositiveScalingFactorFails)
    70  	t.Run("Submitting a spot market update with a target stake parameters with positive time window succeeds", testUpdateSpotMarketWithTargetStakeParamsPositiveScalingFactorSucceeds)
    71  	t.Run("Submitting a spot market update with a target stake parameters succeeds", testUpdateSpotMarketWithTargetStakeParametersSucceeds)
    72  	t.Run("Submitting a spot market update with invalid SLA price range fails", testUpdateSpotMarketChangeSubmissionWithInvalidLpRangeFails)
    73  	t.Run("Submitting a spot market update with valid SLA price range succeeds", testUpdateSpotMarketChangeSubmissionWithValidLpRangeSucceeds)
    74  	t.Run("Submitting a spot market update with invalid min time fraction fails", testUpdateSpotMarketChangeSubmissionWithInvalidMinTimeFractionFails)
    75  	t.Run("Submitting a spot market update with valid min time fraction succeeds", testUpdateSpotMarketChangeSubmissionWithValidMinTimeFractionSucceeds)
    76  	t.Run("Submitting a spot market update with invalid competition factor fails", testUpdateSpotMarketChangeSubmissionWithInvalidCompetitionFactorFails)
    77  	t.Run("Submitting a spot market update with valid competition factor succeeds", testUpdateSpotMarketChangeSubmissionWithValidCompetitionFactorSucceeds)
    78  	t.Run("Submitting a spot market update with invalid hysteresis epochs fails", testUpdateSpotMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails)
    79  	t.Run("Submitting a spot market update with valid hysteresis epochs succeeds", testUpdateSpotMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds)
    80  	t.Run("Submitting a spot market update with invalid tick size fails and valid tick size succeeds", testUpdateSpotMarketTickSize)
    81  	t.Run("Submitting a spot market update without instrument name or code fails", testUpdateSpotMarketChangeSubmissionWithoutInstrumentNameFails)
    82  }
    83  
    84  func testUpdateSpotMarketTickSize(t *testing.T) {
    85  	cases := getTickSizeCases()
    86  	for _, tsc := range cases {
    87  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
    88  			Terms: &protoTypes.ProposalTerms{
    89  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
    90  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
    91  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
    92  							TickSize: tsc.tickSize,
    93  						},
    94  					},
    95  				},
    96  			},
    97  		})
    98  		if tsc.err != nil {
    99  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.tick_size"), tsc.err)
   100  		} else {
   101  			assert.Empty(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.tick_size"))
   102  		}
   103  	}
   104  }
   105  
   106  func testUpdateSpotMarketChangeSubmissionWithoutUpdateMarketFails(t *testing.T) {
   107  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   108  		Terms: &protoTypes.ProposalTerms{
   109  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{},
   110  		},
   111  	})
   112  
   113  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market"), commands.ErrIsRequired)
   114  }
   115  
   116  func testUpdateSpotMarketChangeSubmissionWithoutChangesFails(t *testing.T) {
   117  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   118  		Terms: &protoTypes.ProposalTerms{
   119  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   120  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{},
   121  			},
   122  		},
   123  	})
   124  
   125  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes"), commands.ErrIsRequired)
   126  }
   127  
   128  func testUpdateSpotMarketChangeSubmissionWithoutDecimalPlacesSucceeds(t *testing.T) {
   129  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   130  		Terms: &protoTypes.ProposalTerms{
   131  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   132  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   133  					Changes: &protoTypes.UpdateSpotMarketConfiguration{},
   134  				},
   135  			},
   136  		},
   137  	})
   138  
   139  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.decimal_places"), commands.ErrMustBePositiveOrZero)
   140  }
   141  
   142  func testUpdateSpotMarketChangeSubmissionWithoutLiquidityMonitoringSucceeds(t *testing.T) {
   143  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   144  		Terms: &protoTypes.ProposalTerms{
   145  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   146  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   147  					Changes: &protoTypes.UpdateSpotMarketConfiguration{},
   148  				},
   149  			},
   150  		},
   151  	})
   152  
   153  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.liquidity_monitoring_parameters"), commands.ErrIsRequired)
   154  }
   155  
   156  func testUpdateSpotMarketWithoutTargetStakeParametersFails(t *testing.T) {
   157  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   158  		Terms: &protoTypes.ProposalTerms{
   159  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   160  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   161  					Changes: &protoTypes.UpdateSpotMarketConfiguration{},
   162  				},
   163  			},
   164  		},
   165  	})
   166  
   167  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.target_stake_parameters"), commands.ErrIsRequired)
   168  }
   169  
   170  func testUpdateSpotMarketWithTargetStakeParametersSucceeds(t *testing.T) {
   171  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   172  		Terms: &protoTypes.ProposalTerms{
   173  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   174  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   175  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   176  						TargetStakeParameters: &protoTypes.TargetStakeParameters{},
   177  					},
   178  				},
   179  			},
   180  		},
   181  	})
   182  
   183  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.target_stake_parameters"), commands.ErrIsRequired)
   184  }
   185  
   186  func testUpdateSpotMarketTargetStakeParamsWithNonPositiveTimeWindowFails(t *testing.T) {
   187  	testCases := []struct {
   188  		msg   string
   189  		value int64
   190  	}{
   191  		{
   192  			msg:   "with ratio of 0",
   193  			value: 0,
   194  		}, {
   195  			msg:   "with ratio of -1",
   196  			value: test.RandomNegativeI64(),
   197  		},
   198  	}
   199  	for _, tc := range testCases {
   200  		t.Run(tc.msg, func(t *testing.T) {
   201  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   202  				Terms: &protoTypes.ProposalTerms{
   203  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   204  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   205  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   206  								TargetStakeParameters: &protoTypes.TargetStakeParameters{
   207  									TimeWindow: tc.value,
   208  								},
   209  							},
   210  						},
   211  					},
   212  				},
   213  			})
   214  
   215  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.target_stake_parameters.time_window"), commands.ErrMustBePositive)
   216  		})
   217  	}
   218  }
   219  
   220  func testUpdateSpotMarketWithTargetStakeParamsPositiveTimeWindowSucceeds(t *testing.T) {
   221  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   222  		Terms: &protoTypes.ProposalTerms{
   223  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   224  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   225  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   226  						TargetStakeParameters: &protoTypes.TargetStakeParameters{
   227  							TimeWindow: test.RandomPositiveI64(),
   228  						},
   229  					},
   230  				},
   231  			},
   232  		},
   233  	})
   234  
   235  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.liquidity_monitoring_parameters.target_stake_parameters.time_window"), commands.ErrMustBePositive)
   236  }
   237  
   238  func testUpdateSpotMarketWithTargetStakeParamsNonPositiveScalingFactorFails(t *testing.T) {
   239  	testCases := []struct {
   240  		msg   string
   241  		value float64
   242  	}{
   243  		{
   244  			msg:   "with ratio of 0",
   245  			value: 0,
   246  		}, {
   247  			msg:   "with ratio of -1.5",
   248  			value: -1.5,
   249  		},
   250  	}
   251  	for _, tc := range testCases {
   252  		t.Run(tc.msg, func(t *testing.T) {
   253  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   254  				Terms: &protoTypes.ProposalTerms{
   255  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   256  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   257  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   258  								TargetStakeParameters: &protoTypes.TargetStakeParameters{
   259  									ScalingFactor: tc.value,
   260  								},
   261  							},
   262  						},
   263  					},
   264  				},
   265  			})
   266  
   267  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive)
   268  		})
   269  	}
   270  }
   271  
   272  func testUpdateSpotMarketWithTargetStakeParamsPositiveScalingFactorSucceeds(t *testing.T) {
   273  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   274  		Terms: &protoTypes.ProposalTerms{
   275  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   276  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   277  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   278  						TargetStakeParameters: &protoTypes.TargetStakeParameters{
   279  							ScalingFactor: 1.5,
   280  						},
   281  					},
   282  				},
   283  			},
   284  		},
   285  	})
   286  
   287  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.target_stake_parameters.scaling_factor"), commands.ErrMustBePositive)
   288  }
   289  
   290  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggersSucceeds(t *testing.T) {
   291  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   292  		Terms: &protoTypes.ProposalTerms{
   293  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   294  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   295  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   296  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   297  							Triggers: []*protoTypes.PriceMonitoringTrigger{},
   298  						},
   299  					},
   300  				},
   301  			},
   302  		},
   303  	})
   304  
   305  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired)
   306  }
   307  
   308  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggersSucceeds(t *testing.T) {
   309  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   310  		Terms: &protoTypes.ProposalTerms{
   311  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   312  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   313  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   314  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   315  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   316  								{},
   317  								{},
   318  							},
   319  						},
   320  					},
   321  				},
   322  			},
   323  		},
   324  	})
   325  
   326  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers"), commands.ErrIsRequired)
   327  }
   328  
   329  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggerHorizonFails(t *testing.T) {
   330  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   331  		Terms: &protoTypes.ProposalTerms{
   332  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   333  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   334  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   335  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   336  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   337  								{},
   338  								{},
   339  							},
   340  						},
   341  					},
   342  				},
   343  			},
   344  		},
   345  	})
   346  
   347  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive)
   348  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive)
   349  }
   350  
   351  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggerHorizonSucceeds(t *testing.T) {
   352  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   353  		Terms: &protoTypes.ProposalTerms{
   354  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   355  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   356  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   357  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   358  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   359  								{
   360  									Horizon: test.RandomPositiveI64(),
   361  								},
   362  								{
   363  									Horizon: test.RandomPositiveI64(),
   364  								},
   365  							},
   366  						},
   367  					},
   368  				},
   369  			},
   370  		},
   371  	})
   372  
   373  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.horizon"), commands.ErrMustBePositive)
   374  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.horizon"), commands.ErrMustBePositive)
   375  }
   376  
   377  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithWrongTriggerProbabilityFails(t *testing.T) {
   378  	testCases := []struct {
   379  		msg   string
   380  		value float64
   381  	}{
   382  		{
   383  			msg:   "with probability of -1",
   384  			value: -1,
   385  		}, {
   386  			msg:   "with probability of 0",
   387  			value: 0,
   388  		}, {
   389  			msg:   "with probability of 1",
   390  			value: 1,
   391  		}, {
   392  			msg:   "with probability of 2",
   393  			value: 2,
   394  		},
   395  	}
   396  	for _, tc := range testCases {
   397  		t.Run(tc.msg, func(t *testing.T) {
   398  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   399  				Terms: &protoTypes.ProposalTerms{
   400  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   401  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   402  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   403  								PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   404  									Triggers: []*protoTypes.PriceMonitoringTrigger{
   405  										{
   406  											Probability: fmt.Sprintf("%f", tc.value),
   407  										},
   408  										{
   409  											Probability: fmt.Sprintf("%f", tc.value),
   410  										},
   411  									},
   412  								},
   413  							},
   414  						},
   415  					},
   416  				},
   417  			})
   418  
   419  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.probability"),
   420  				errors.New("should be between 0.9 (exclusive) and 1 (exclusive)"))
   421  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.probability"),
   422  				errors.New("should be between 0.9 (exclusive) and 1 (exclusive)"))
   423  		})
   424  	}
   425  }
   426  
   427  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithRightTriggerProbabilitySucceeds(t *testing.T) {
   428  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   429  		Terms: &protoTypes.ProposalTerms{
   430  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   431  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   432  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   433  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   434  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   435  								{
   436  									Probability: "0.01",
   437  								},
   438  								{
   439  									Probability: "0.9",
   440  								},
   441  							},
   442  						},
   443  					},
   444  				},
   445  			},
   446  		},
   447  	})
   448  
   449  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.probability"),
   450  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   451  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.probability"),
   452  		errors.New("should be between 0 (exclusive) and 1 (exclusive)"))
   453  }
   454  
   455  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithoutTriggerAuctionExtensionFails(t *testing.T) {
   456  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   457  		Terms: &protoTypes.ProposalTerms{
   458  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   459  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   460  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   461  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   462  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   463  								{},
   464  								{},
   465  							},
   466  						},
   467  					},
   468  				},
   469  			},
   470  		},
   471  	})
   472  
   473  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive)
   474  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive)
   475  }
   476  
   477  func testUpdateSpotMarketPriceMonitoringChangeSubmissionWithTriggerAuctionExtensionSucceeds(t *testing.T) {
   478  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   479  		Terms: &protoTypes.ProposalTerms{
   480  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   481  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   482  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   483  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{
   484  							Triggers: []*protoTypes.PriceMonitoringTrigger{
   485  								{
   486  									AuctionExtension: test.RandomPositiveI64(),
   487  								},
   488  								{
   489  									AuctionExtension: test.RandomPositiveI64(),
   490  								},
   491  							},
   492  						},
   493  					},
   494  				},
   495  			},
   496  		},
   497  	})
   498  
   499  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.0.auction_extension"), commands.ErrMustBePositive)
   500  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters.triggers.1.auction_extension"), commands.ErrMustBePositive)
   501  }
   502  
   503  func testUpdateSpotMarketChangeSubmissionWithoutPriceMonitoringSucceeds(t *testing.T) {
   504  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   505  		Terms: &protoTypes.ProposalTerms{
   506  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   507  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   508  					Changes: &protoTypes.UpdateSpotMarketConfiguration{},
   509  				},
   510  			},
   511  		},
   512  	})
   513  
   514  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters"), commands.ErrIsRequired)
   515  }
   516  
   517  func testUpdateSpotMarketChangeSubmissionWithPriceMonitoringSucceeds(t *testing.T) {
   518  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   519  		Terms: &protoTypes.ProposalTerms{
   520  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   521  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   522  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   523  						PriceMonitoringParameters: &protoTypes.PriceMonitoringParameters{},
   524  					},
   525  				},
   526  			},
   527  		},
   528  	})
   529  
   530  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.price_monitoring_parameters"), commands.ErrIsRequired)
   531  }
   532  
   533  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithoutSimpleRiskParametersFails(t *testing.T) {
   534  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   535  		Terms: &protoTypes.ProposalTerms{
   536  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   537  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   538  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   539  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{},
   540  					},
   541  				},
   542  			},
   543  		},
   544  	})
   545  
   546  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple"), commands.ErrIsRequired)
   547  }
   548  
   549  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithSimpleRiskParametersSucceeds(t *testing.T) {
   550  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   551  		Terms: &protoTypes.ProposalTerms{
   552  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   553  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   554  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   555  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   556  							Simple: &protoTypes.SimpleModelParams{},
   557  						},
   558  					},
   559  				},
   560  			},
   561  		},
   562  	})
   563  
   564  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple"), commands.ErrIsRequired)
   565  }
   566  
   567  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithPositiveMinMoveDownFails(t *testing.T) {
   568  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   569  		Terms: &protoTypes.ProposalTerms{
   570  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   571  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   572  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   573  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   574  							Simple: &protoTypes.SimpleModelParams{
   575  								MinMoveDown: 1,
   576  							},
   577  						},
   578  					},
   579  				},
   580  			},
   581  		},
   582  	})
   583  
   584  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero)
   585  }
   586  
   587  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithNonPositiveMinMoveDownSucceeds(t *testing.T) {
   588  	testCases := []struct {
   589  		msg   string
   590  		value float64
   591  	}{
   592  		{
   593  			msg:   "with min move down of 0",
   594  			value: 0,
   595  		}, {
   596  			msg:   "with min move down of -1",
   597  			value: -1,
   598  		},
   599  	}
   600  	for _, tc := range testCases {
   601  		t.Run(tc.msg, func(t *testing.T) {
   602  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   603  				Terms: &protoTypes.ProposalTerms{
   604  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   605  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   606  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   607  								RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   608  									Simple: &protoTypes.SimpleModelParams{
   609  										MinMoveDown: tc.value,
   610  									},
   611  								},
   612  							},
   613  						},
   614  					},
   615  				},
   616  			})
   617  
   618  			assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.min_move_down"), commands.ErrMustBeNegativeOrZero)
   619  		})
   620  	}
   621  }
   622  
   623  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithNegativeMaxMoveUpFails(t *testing.T) {
   624  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   625  		Terms: &protoTypes.ProposalTerms{
   626  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   627  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   628  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   629  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   630  							Simple: &protoTypes.SimpleModelParams{
   631  								MaxMoveUp: -1,
   632  							},
   633  						},
   634  					},
   635  				},
   636  			},
   637  		},
   638  	})
   639  
   640  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero)
   641  }
   642  
   643  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithNonNegativeMaxMoveUpSucceeds(t *testing.T) {
   644  	testCases := []struct {
   645  		msg   string
   646  		value float64
   647  	}{
   648  		{
   649  			msg:   "with max move up of 0",
   650  			value: 0,
   651  		}, {
   652  			msg:   "with max move up of 1",
   653  			value: 1,
   654  		},
   655  	}
   656  	for _, tc := range testCases {
   657  		t.Run(tc.msg, func(t *testing.T) {
   658  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   659  				Terms: &protoTypes.ProposalTerms{
   660  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   661  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   662  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   663  								RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   664  									Simple: &protoTypes.SimpleModelParams{
   665  										MaxMoveUp: tc.value,
   666  									},
   667  								},
   668  							},
   669  						},
   670  					},
   671  				},
   672  			})
   673  
   674  			assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.max_move_up"), commands.ErrMustBePositiveOrZero)
   675  		})
   676  	}
   677  }
   678  
   679  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithWrongProbabilityOfTradingFails(t *testing.T) {
   680  	testCases := []struct {
   681  		msg   string
   682  		value float64
   683  	}{
   684  		{
   685  			msg:   "with probability of trading of -1",
   686  			value: -1,
   687  		}, {
   688  			msg:   "with probability of trading of 2",
   689  			value: 2,
   690  		},
   691  	}
   692  	for _, tc := range testCases {
   693  		t.Run(tc.msg, func(t *testing.T) {
   694  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   695  				Terms: &protoTypes.ProposalTerms{
   696  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   697  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   698  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   699  								RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   700  									Simple: &protoTypes.SimpleModelParams{
   701  										ProbabilityOfTrading: tc.value,
   702  									},
   703  								},
   704  							},
   705  						},
   706  					},
   707  				},
   708  			})
   709  
   710  			assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.probability_of_trading"),
   711  				errors.New("should be between 0 (inclusive) and 1 (inclusive)"))
   712  		})
   713  	}
   714  }
   715  
   716  func testUpdateSpotSimpleRiskParametersChangeSubmissionWithRightProbabilityOfTradingSucceeds(t *testing.T) {
   717  	testCases := []struct {
   718  		msg   string
   719  		value float64
   720  	}{
   721  		{
   722  			msg:   "with probability of trading of 0",
   723  			value: 0,
   724  		}, {
   725  			msg:   "with probability of trading of 1",
   726  			value: 1,
   727  		}, {
   728  			msg:   "with probability of trading of 0.5",
   729  			value: 0.5,
   730  		},
   731  	}
   732  	for _, tc := range testCases {
   733  		t.Run(tc.msg, func(t *testing.T) {
   734  			err := checkProposalSubmission(&commandspb.ProposalSubmission{
   735  				Terms: &protoTypes.ProposalTerms{
   736  					Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   737  						UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   738  							Changes: &protoTypes.UpdateSpotMarketConfiguration{
   739  								RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_Simple{
   740  									Simple: &protoTypes.SimpleModelParams{
   741  										ProbabilityOfTrading: tc.value,
   742  									},
   743  								},
   744  							},
   745  						},
   746  					},
   747  				},
   748  			})
   749  
   750  			assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.simple.probability_of_trading"),
   751  				errors.New("should be between 0 (inclusive) and 1 (inclusive)"))
   752  		})
   753  	}
   754  }
   755  
   756  func testUpdateSpotLogNormalRiskParametersChangeSubmissionWithoutLogNormalRiskParametersFails(t *testing.T) {
   757  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   758  		Terms: &protoTypes.ProposalTerms{
   759  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   760  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   761  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   762  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{},
   763  					},
   764  				},
   765  			},
   766  		},
   767  	})
   768  
   769  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired)
   770  }
   771  
   772  func testUpdateSpotLogNormalRiskParametersChangeSubmissionWithLogNormalRiskParametersSucceeds(t *testing.T) {
   773  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   774  		Terms: &protoTypes.ProposalTerms{
   775  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   776  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   777  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   778  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   779  							LogNormal: &protoTypes.LogNormalRiskModel{
   780  								RiskAversionParameter: 1,
   781  								Tau:                   2,
   782  								Params: &protoTypes.LogNormalModelParams{
   783  									Mu:    0,
   784  									Sigma: 0.1,
   785  									R:     0,
   786  								},
   787  							},
   788  						},
   789  					},
   790  				},
   791  			},
   792  		},
   793  	})
   794  
   795  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal"), commands.ErrIsRequired)
   796  }
   797  
   798  func testUpdateSpotLogNormalRiskParametersChangeSubmissionWithoutParamsFails(t *testing.T) {
   799  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   800  		Terms: &protoTypes.ProposalTerms{
   801  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   802  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   803  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   804  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   805  							LogNormal: &protoTypes.LogNormalRiskModel{},
   806  						},
   807  					},
   808  				},
   809  			},
   810  		},
   811  	})
   812  
   813  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params"), commands.ErrIsRequired)
   814  }
   815  
   816  func testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidRiskAversion(t *testing.T) {
   817  	cZero := &commandspb.ProposalSubmission{
   818  		Terms: &protoTypes.ProposalTerms{
   819  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   820  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   821  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   822  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   823  							LogNormal: &protoTypes.LogNormalRiskModel{
   824  								RiskAversionParameter: 0,
   825  								Tau:                   2,
   826  								Params: &protoTypes.LogNormalModelParams{
   827  									Mu:    0,
   828  									Sigma: 0.1,
   829  									R:     0,
   830  								},
   831  							},
   832  						},
   833  					},
   834  				},
   835  			},
   836  		},
   837  	}
   838  	err := checkProposalSubmission(cZero)
   839  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), commands.ErrMustBePositive)
   840  
   841  	cNeg := &commandspb.ProposalSubmission{
   842  		Terms: &protoTypes.ProposalTerms{
   843  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   844  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   845  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   846  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   847  							LogNormal: &protoTypes.LogNormalRiskModel{
   848  								RiskAversionParameter: -0.1,
   849  								Tau:                   2,
   850  								Params: &protoTypes.LogNormalModelParams{
   851  									Mu:    0,
   852  									Sigma: 0.1,
   853  									R:     0,
   854  								},
   855  							},
   856  						},
   857  					},
   858  				},
   859  			},
   860  		},
   861  	}
   862  	err = checkProposalSubmission(cNeg)
   863  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.risk_aversion_parameter"), commands.ErrMustBePositive)
   864  }
   865  
   866  func testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidTau(t *testing.T) {
   867  	cZero := &commandspb.ProposalSubmission{
   868  		Terms: &protoTypes.ProposalTerms{
   869  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   870  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   871  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   872  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   873  							LogNormal: &protoTypes.LogNormalRiskModel{
   874  								RiskAversionParameter: 0.1,
   875  								Tau:                   0,
   876  								Params: &protoTypes.LogNormalModelParams{
   877  									Mu:    0,
   878  									Sigma: 0.1,
   879  									R:     0,
   880  								},
   881  							},
   882  						},
   883  					},
   884  				},
   885  			},
   886  		},
   887  	}
   888  	err := checkProposalSubmission(cZero)
   889  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.tau"), commands.ErrMustBePositive)
   890  
   891  	cNeg := &commandspb.ProposalSubmission{
   892  		Terms: &protoTypes.ProposalTerms{
   893  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   894  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   895  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   896  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   897  							LogNormal: &protoTypes.LogNormalRiskModel{
   898  								RiskAversionParameter: 0.1,
   899  								Tau:                   -0.2,
   900  								Params: &protoTypes.LogNormalModelParams{
   901  									Mu:    0,
   902  									Sigma: 0.1,
   903  									R:     0,
   904  								},
   905  							},
   906  						},
   907  					},
   908  				},
   909  			},
   910  		},
   911  	}
   912  	err = checkProposalSubmission(cNeg)
   913  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.tau"), commands.ErrMustBePositive)
   914  }
   915  
   916  func testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidMu(t *testing.T) {
   917  	cNaN := &commandspb.ProposalSubmission{
   918  		Terms: &protoTypes.ProposalTerms{
   919  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   920  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   921  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   922  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   923  							LogNormal: &protoTypes.LogNormalRiskModel{
   924  								RiskAversionParameter: 0.1,
   925  								Tau:                   0.2,
   926  								Params: &protoTypes.LogNormalModelParams{
   927  									Mu:    math.NaN(),
   928  									Sigma: 0.1,
   929  									R:     0,
   930  								},
   931  							},
   932  						},
   933  					},
   934  				},
   935  			},
   936  		},
   937  	}
   938  	err := checkProposalSubmission(cNaN)
   939  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params.mu"), commands.ErrIsNotValidNumber)
   940  }
   941  
   942  func testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidR(t *testing.T) {
   943  	cNaN := &commandspb.ProposalSubmission{
   944  		Terms: &protoTypes.ProposalTerms{
   945  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   946  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   947  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   948  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   949  							LogNormal: &protoTypes.LogNormalRiskModel{
   950  								RiskAversionParameter: 0.1,
   951  								Tau:                   0.2,
   952  								Params: &protoTypes.LogNormalModelParams{
   953  									Mu:    0.2,
   954  									Sigma: 0.1,
   955  									R:     math.NaN(),
   956  								},
   957  							},
   958  						},
   959  					},
   960  				},
   961  			},
   962  		},
   963  	}
   964  	err := checkProposalSubmission(cNaN)
   965  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params.r"), commands.ErrIsNotValidNumber)
   966  }
   967  
   968  func testUpdateSpotLogNormalRiskParametersChangeSubmissionInvalidSigma(t *testing.T) {
   969  	cNaN := &commandspb.ProposalSubmission{
   970  		Terms: &protoTypes.ProposalTerms{
   971  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   972  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   973  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   974  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   975  							LogNormal: &protoTypes.LogNormalRiskModel{
   976  								RiskAversionParameter: 0.1,
   977  								Tau:                   0.2,
   978  								Params: &protoTypes.LogNormalModelParams{
   979  									Mu:    0.2,
   980  									Sigma: math.NaN(),
   981  									R:     0,
   982  								},
   983  							},
   984  						},
   985  					},
   986  				},
   987  			},
   988  		},
   989  	}
   990  	err := checkProposalSubmission(cNaN)
   991  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrIsNotValidNumber)
   992  
   993  	cNeg := &commandspb.ProposalSubmission{
   994  		Terms: &protoTypes.ProposalTerms{
   995  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
   996  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
   997  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
   998  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
   999  							LogNormal: &protoTypes.LogNormalRiskModel{
  1000  								RiskAversionParameter: 0.1,
  1001  								Tau:                   0.2,
  1002  								Params: &protoTypes.LogNormalModelParams{
  1003  									Mu:    0.2,
  1004  									Sigma: -0.1,
  1005  									R:     0,
  1006  								},
  1007  							},
  1008  						},
  1009  					},
  1010  				},
  1011  			},
  1012  		},
  1013  	}
  1014  	err = checkProposalSubmission(cNeg)
  1015  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrMustBePositive)
  1016  
  1017  	c0 := &commandspb.ProposalSubmission{
  1018  		Terms: &protoTypes.ProposalTerms{
  1019  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1020  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1021  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1022  						RiskParameters: &protoTypes.UpdateSpotMarketConfiguration_LogNormal{
  1023  							LogNormal: &protoTypes.LogNormalRiskModel{
  1024  								RiskAversionParameter: 0.1,
  1025  								Tau:                   0.2,
  1026  								Params: &protoTypes.LogNormalModelParams{
  1027  									Mu:    0.2,
  1028  									Sigma: 0,
  1029  									R:     0,
  1030  								},
  1031  							},
  1032  						},
  1033  					},
  1034  				},
  1035  			},
  1036  		},
  1037  	}
  1038  	err = checkProposalSubmission(c0)
  1039  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.risk_parameters.log_normal.params.sigma"), commands.ErrMustBePositive)
  1040  }
  1041  
  1042  func testUpdateSpotMarketSubmissionWithTooLongReferenceFails(t *testing.T) {
  1043  	ref := make([]byte, 101)
  1044  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1045  		Reference: string(ref),
  1046  	})
  1047  	assert.Contains(t, err.Get("proposal_submission.reference"), commands.ErrReferenceTooLong)
  1048  }
  1049  
  1050  func testUpdateSpotMarketWithMarketIDSucceeds(t *testing.T) {
  1051  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1052  		Terms: &protoTypes.ProposalTerms{
  1053  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1054  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1055  					MarketId: "12345",
  1056  				},
  1057  			},
  1058  		},
  1059  	})
  1060  
  1061  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.market_id"), commands.ErrIsRequired)
  1062  }
  1063  
  1064  func testUpdateSpotMarketWithoutMarketIDFails(t *testing.T) {
  1065  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1066  		Terms: &protoTypes.ProposalTerms{
  1067  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1068  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{},
  1069  			},
  1070  		},
  1071  	})
  1072  
  1073  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.market_id"), commands.ErrIsRequired)
  1074  }
  1075  
  1076  func testUpdateSpotMarketChangeSubmissionWithValidLpRangeSucceeds(t *testing.T) {
  1077  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1078  		Terms: &protoTypes.ProposalTerms{
  1079  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1080  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1081  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1082  						SlaParams: &protoTypes.LiquiditySLAParameters{
  1083  							PriceRange: "50",
  1084  						},
  1085  					},
  1086  				},
  1087  			},
  1088  		},
  1089  	})
  1090  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBePositive, commands.ErrMustBePositive, commands.ErrMustBeAtMost100}
  1091  	for _, e := range errors {
  1092  		assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.price_range"), e)
  1093  	}
  1094  }
  1095  
  1096  func testUpdateSpotMarketChangeSubmissionWithInvalidLpRangeFails(t *testing.T) {
  1097  	priceRanges := []string{"banana", "-1", "0", "101"}
  1098  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20, commands.ErrMustBeWithinRangeGT0LT20}
  1099  
  1100  	for i, v := range priceRanges {
  1101  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1102  			Terms: &protoTypes.ProposalTerms{
  1103  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1104  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1105  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1106  							SlaParams: &protoTypes.LiquiditySLAParameters{
  1107  								PriceRange: v,
  1108  							},
  1109  						},
  1110  					},
  1111  				},
  1112  			},
  1113  		})
  1114  		assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.price_range"), errors[i])
  1115  	}
  1116  }
  1117  
  1118  func testUpdateSpotMarketChangeSubmissionWithInvalidMinTimeFractionFails(t *testing.T) {
  1119  	minTimeFraction := []string{"banana", "-1", "-1.1", "1.1", "100"}
  1120  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01}
  1121  
  1122  	for i, v := range minTimeFraction {
  1123  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1124  			Terms: &protoTypes.ProposalTerms{
  1125  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1126  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1127  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1128  							SlaParams: &protoTypes.LiquiditySLAParameters{
  1129  								CommitmentMinTimeFraction: v,
  1130  							},
  1131  						},
  1132  					},
  1133  				},
  1134  			},
  1135  		})
  1136  		assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.commitment_min_time_fraction"), errors[i])
  1137  	}
  1138  }
  1139  
  1140  func testUpdateSpotMarketChangeSubmissionWithValidMinTimeFractionSucceeds(t *testing.T) {
  1141  	minTimeFraction := []string{"0", "0.1", "0.99", "1"}
  1142  
  1143  	for _, v := range minTimeFraction {
  1144  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1145  			Terms: &protoTypes.ProposalTerms{
  1146  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1147  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1148  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1149  							SlaParams: &protoTypes.LiquiditySLAParameters{
  1150  								CommitmentMinTimeFraction: v,
  1151  							},
  1152  						},
  1153  					},
  1154  				},
  1155  			},
  1156  		})
  1157  
  1158  		errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01}
  1159  		for _, e := range errors {
  1160  			assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.commitment_min_time_fraction"), e)
  1161  		}
  1162  	}
  1163  }
  1164  
  1165  func testUpdateSpotMarketChangeSubmissionWithInvalidCompetitionFactorFails(t *testing.T) {
  1166  	competitionFactors := []string{"banana", "-1", "-1.1", "1.1", "100"}
  1167  	errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01, commands.ErrMustBeWithinRange01}
  1168  
  1169  	for i, v := range competitionFactors {
  1170  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1171  			Terms: &protoTypes.ProposalTerms{
  1172  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1173  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1174  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1175  							SlaParams: &protoTypes.LiquiditySLAParameters{
  1176  								SlaCompetitionFactor: v,
  1177  							},
  1178  						},
  1179  					},
  1180  				},
  1181  			},
  1182  		})
  1183  		assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.sla_competition_factor"), errors[i])
  1184  	}
  1185  }
  1186  
  1187  func testUpdateSpotMarketChangeSubmissionWithValidCompetitionFactorSucceeds(t *testing.T) {
  1188  	minTimeFraction := []string{"0", "0.1", "0.99", "1"}
  1189  
  1190  	for _, v := range minTimeFraction {
  1191  		err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1192  			Terms: &protoTypes.ProposalTerms{
  1193  				Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1194  					UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1195  						Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1196  							SlaParams: &protoTypes.LiquiditySLAParameters{
  1197  								SlaCompetitionFactor: v,
  1198  							},
  1199  						},
  1200  					},
  1201  				},
  1202  			},
  1203  		})
  1204  
  1205  		errors := []error{commands.ErrIsNotValidNumber, commands.ErrMustBeWithinRange01}
  1206  		for _, e := range errors {
  1207  			assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.sla_competition_factor"), e)
  1208  		}
  1209  	}
  1210  }
  1211  
  1212  func testUpdateSpotMarketChangeSubmissionWithInvalidPerformanceHysteresisEpochsFails(t *testing.T) {
  1213  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1214  		Terms: &protoTypes.ProposalTerms{
  1215  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1216  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1217  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1218  						SlaParams: &protoTypes.LiquiditySLAParameters{
  1219  							PerformanceHysteresisEpochs: 367,
  1220  						},
  1221  					},
  1222  				},
  1223  			},
  1224  		},
  1225  	})
  1226  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBeLessThen366)
  1227  }
  1228  
  1229  func testUpdateSpotMarketChangeSubmissionWithValidPerformanceHysteresisEpochsSucceeds(t *testing.T) {
  1230  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1231  		Terms: &protoTypes.ProposalTerms{
  1232  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1233  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1234  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1235  						SlaParams: &protoTypes.LiquiditySLAParameters{
  1236  							PerformanceHysteresisEpochs: 1,
  1237  						},
  1238  					},
  1239  				},
  1240  			},
  1241  		},
  1242  	})
  1243  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.sla_params.performance_hysteresis_epochs"), commands.ErrMustBePositive)
  1244  }
  1245  
  1246  func testUpdateSpotMarketChangeSubmissionWithoutInstrumentNameFails(t *testing.T) {
  1247  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
  1248  		Terms: &protoTypes.ProposalTerms{
  1249  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1250  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1251  					Changes: &protoTypes.UpdateSpotMarketConfiguration{},
  1252  				},
  1253  			},
  1254  		},
  1255  	})
  1256  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.instrument"), commands.ErrIsRequired)
  1257  
  1258  	err = checkProposalSubmission(&commandspb.ProposalSubmission{
  1259  		Terms: &protoTypes.ProposalTerms{
  1260  			Change: &protoTypes.ProposalTerms_UpdateSpotMarket{
  1261  				UpdateSpotMarket: &protoTypes.UpdateSpotMarket{
  1262  					Changes: &protoTypes.UpdateSpotMarketConfiguration{
  1263  						Instrument: &protoTypes.UpdateSpotInstrumentConfiguration{},
  1264  					},
  1265  				},
  1266  			},
  1267  		},
  1268  	})
  1269  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.instrument.code"), commands.ErrIsRequired)
  1270  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_spot_market.changes.instrument.name"), commands.ErrIsRequired)
  1271  }