code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_update_referral_program_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  	"fmt"
    20  	"testing"
    21  
    22  	"code.vegaprotocol.io/vega/commands"
    23  	types "code.vegaprotocol.io/vega/protos/vega"
    24  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func TestCheckProposalSubmissionForReferralProgramUpdate(t *testing.T) {
    30  	t.Run("Submitting a referral program update without update fails", testSubmissionForReferralProgramUpdateWithoutUpdateFails)
    31  	t.Run("Submitting a referral program update without changes fails", testSubmissionForReferralProgramUpdateWithoutChangesFails)
    32  	t.Run("Submitting a referral program update without end of program timestamp fails", testSubmissionForReferralProgramUpdateWithoutEndOfProgramFails)
    33  	t.Run("Submitting a referral program update with negative end of program timestamp fails", testSubmissionForReferralProgramUpdateWithNegativeEndOfProgramFails)
    34  	t.Run("Submitting a referral program update with end of program before enactment timestamp fails", testSubmissionForReferralProgramUpdateWithEndOfProgramBeforeEnactmentFails)
    35  	t.Run("Submitting a referral program update without window length fails", testSubmissionForReferralProgramUpdateWithoutWindowLengthFails)
    36  	t.Run("Submitting a referral program update with window length over limit fails", testSubmissionForReferralProgramUpdateWithWindowLengthOverLimitFails)
    37  	t.Run("Submitting a referral program update without tier minimum running volume fails", testSubmissionForReferralProgramUpdateWithoutTierMinimumRunningNotionalTakerVolumeFails)
    38  	t.Run("Submitting a referral program update with bad format for tier minimum running volume fails", testSubmissionForReferralProgramUpdateWithBadFormatForTierMinimumRunningNotionalTakerVolumeFails)
    39  	t.Run("Submitting a referral program update with bad value for tier minimum running volume fails", testSubmissionForReferralProgramUpdateWithBadValueForTierMinimumRunningNotionalTakerVolumeFails)
    40  	t.Run("Submitting a referral program update without tier minimum epochs fails", testSubmissionForReferralProgramUpdateWithoutTierMinimumEpochsFails)
    41  	t.Run("Submitting a referral program update with bad format for tier minimum epochs fails", testSubmissionForReferralProgramUpdateWithBadFormatForTierMinimumEpochsFails)
    42  	t.Run("Submitting a referral program update with bad value for tier minimum epochs fails", testSubmissionForReferralProgramUpdateWithBadValueForTierMinimumEpochsFails)
    43  	t.Run("Submitting a referral program update without tier referral reward factor fails", testSubmissionForReferralProgramUpdateWithoutTierReferralRewardFactorFails)
    44  	t.Run("Submitting a referral program update with bad format for tier referral reward factor fails", testSubmissionForReferralProgramUpdateWithBadFormatForTierReferralRewardFactorFails)
    45  	t.Run("Submitting a referral program update with bad value for tier referral reward factor fails", testSubmissionForReferralProgramUpdateWithBadValueForTierReferralRewardFactorFails)
    46  	t.Run("Submitting a referral program update without tier referral discount factor fails", testSubmissionForReferralProgramUpdateWithoutTierReferralDiscountFactorFails)
    47  	t.Run("Submitting a referral program update with bad format for tier referral discount factor fails", testSubmissionForReferralProgramUpdateWithBadFormatForTierReferralDiscountFactorFails)
    48  	t.Run("Submitting a referral program update with bad value for tier referral discount factor fails", testSubmissionForReferralProgramUpdateWithBadValueForTierReferralDiscountFactorFails)
    49  	t.Run("Submitting a referral program update without staking tier minimum staked tokens fails", testSubmissionForReferralProgramUpdateWithoutStakingTierMinimumStakedTokensFails)
    50  	t.Run("Submitting a referral program update with bad format for staking tier minimum staked tokens fails", testSubmissionForReferralProgramUpdateWithBadFormatForStakingTierMinimumStakedTokensFails)
    51  	t.Run("Submitting a referral program update with bad value for staking tier minimum staked tokens fails", testSubmissionForReferralProgramUpdateWithBadValueForStakingTierMinimumStakedTokensFails)
    52  	t.Run("Submitting a referral program update without staking tier referral reward multiplier fails", testSubmissionForReferralProgramUpdateWithoutStakingTierReferralRewardMultiplierFails)
    53  	t.Run("Submitting a referral program update with bad format for staking tier referral reward multiplier fails", testSubmissionForReferralProgramUpdateWithBadFormatForStakingTierReferralRewardMultiplierFails)
    54  	t.Run("Submitting a referral program update with bad value for staking tier referral reward multiplier fails", testSubmissionForReferralProgramUpdateWithBadValueForStakingTierReferralRewardMultiplierFails)
    55  	t.Run("Submitting a referral program update with multiple identical staking tiers fails", testSubmissionForReferralProgramUpdateWithDuplicateStakingTierEntriesFails)
    56  	t.Run("Submitting a referral program update with multiple identical benefit tiers fails", testSubmissionForReferralProgramUpdateWithDuplicateBenefitTierEntriesFails)
    57  }
    58  
    59  func testSubmissionForReferralProgramUpdateWithoutUpdateFails(t *testing.T) {
    60  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    61  		Terms: &types.ProposalTerms{
    62  			Change: &types.ProposalTerms_UpdateReferralProgram{},
    63  		},
    64  	})
    65  
    66  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program"), commands.ErrIsRequired)
    67  }
    68  
    69  func testSubmissionForReferralProgramUpdateWithoutChangesFails(t *testing.T) {
    70  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    71  		Terms: &types.ProposalTerms{
    72  			Change: &types.ProposalTerms_UpdateReferralProgram{
    73  				UpdateReferralProgram: &types.UpdateReferralProgram{},
    74  			},
    75  		},
    76  	})
    77  
    78  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes"), commands.ErrIsRequired)
    79  }
    80  
    81  func testSubmissionForReferralProgramUpdateWithoutEndOfProgramFails(t *testing.T) {
    82  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    83  		Terms: &types.ProposalTerms{
    84  			Change: &types.ProposalTerms_UpdateReferralProgram{
    85  				UpdateReferralProgram: &types.UpdateReferralProgram{
    86  					Changes: &types.ReferralProgramChanges{
    87  						EndOfProgramTimestamp: 0,
    88  					},
    89  				},
    90  			},
    91  		},
    92  	})
    93  
    94  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.end_of_program_timestamp"), commands.ErrIsRequired)
    95  }
    96  
    97  func testSubmissionForReferralProgramUpdateWithNegativeEndOfProgramFails(t *testing.T) {
    98  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    99  		Terms: &types.ProposalTerms{
   100  			Change: &types.ProposalTerms_UpdateReferralProgram{
   101  				UpdateReferralProgram: &types.UpdateReferralProgram{
   102  					Changes: &types.ReferralProgramChanges{
   103  						EndOfProgramTimestamp: -1,
   104  					},
   105  				},
   106  			},
   107  		},
   108  	})
   109  
   110  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.end_of_program_timestamp"), commands.ErrMustBePositive)
   111  }
   112  
   113  func testSubmissionForReferralProgramUpdateWithEndOfProgramBeforeEnactmentFails(t *testing.T) {
   114  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   115  		Terms: &types.ProposalTerms{
   116  			EnactmentTimestamp: 10,
   117  			Change: &types.ProposalTerms_UpdateReferralProgram{
   118  				UpdateReferralProgram: &types.UpdateReferralProgram{
   119  					Changes: &types.ReferralProgramChanges{
   120  						EndOfProgramTimestamp: 5,
   121  					},
   122  				},
   123  			},
   124  		},
   125  	})
   126  
   127  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.end_of_program_timestamp"), commands.ErrMustBeGreaterThanEnactmentTimestamp)
   128  }
   129  
   130  func testSubmissionForReferralProgramUpdateWithoutWindowLengthFails(t *testing.T) {
   131  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   132  		Terms: &types.ProposalTerms{
   133  			Change: &types.ProposalTerms_UpdateReferralProgram{
   134  				UpdateReferralProgram: &types.UpdateReferralProgram{
   135  					Changes: &types.ReferralProgramChanges{
   136  						WindowLength: 0,
   137  					},
   138  				},
   139  			},
   140  		},
   141  	})
   142  
   143  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.window_length"), commands.ErrIsRequired)
   144  }
   145  
   146  func testSubmissionForReferralProgramUpdateWithWindowLengthOverLimitFails(t *testing.T) {
   147  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   148  		Terms: &types.ProposalTerms{
   149  			Change: &types.ProposalTerms_UpdateReferralProgram{
   150  				UpdateReferralProgram: &types.UpdateReferralProgram{
   151  					Changes: &types.ReferralProgramChanges{
   152  						WindowLength: 201,
   153  					},
   154  				},
   155  			},
   156  		},
   157  	})
   158  
   159  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.window_length"), commands.ErrMustBeAtMost200)
   160  }
   161  
   162  func testSubmissionForReferralProgramUpdateWithoutTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   163  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   164  		Terms: &types.ProposalTerms{
   165  			Change: &types.ProposalTerms_UpdateReferralProgram{
   166  				UpdateReferralProgram: &types.UpdateReferralProgram{
   167  					Changes: &types.ReferralProgramChanges{
   168  						BenefitTiers: []*types.BenefitTier{
   169  							{
   170  								MinimumRunningNotionalTakerVolume: "",
   171  							}, {
   172  								MinimumRunningNotionalTakerVolume: "",
   173  							},
   174  						},
   175  					},
   176  				},
   177  			},
   178  		},
   179  	})
   180  
   181  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrIsRequired)
   182  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrIsRequired)
   183  }
   184  
   185  func testSubmissionForReferralProgramUpdateWithDuplicateBenefitTierEntriesFails(t *testing.T) {
   186  	factors := []string{"1.1", "1.2", "1.3", "1.4", "1.5", "1.6"}
   187  
   188  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   189  		Terms: &types.ProposalTerms{
   190  			Change: &types.ProposalTerms_UpdateReferralProgram{
   191  				UpdateReferralProgram: &types.UpdateReferralProgram{
   192  					Changes: &types.ReferralProgramChanges{
   193  						BenefitTiers: []*types.BenefitTier{
   194  							{
   195  								MinimumRunningNotionalTakerVolume: "100",
   196  								MinimumEpochs:                     "10",
   197  								ReferralRewardFactors: &types.RewardFactors{
   198  									InfrastructureRewardFactor: factors[0],
   199  									MakerRewardFactor:          factors[1],
   200  									LiquidityRewardFactor:      factors[2],
   201  								},
   202  								ReferralDiscountFactors: &types.DiscountFactors{
   203  									InfrastructureDiscountFactor: factors[1],
   204  									MakerDiscountFactor:          factors[2],
   205  									LiquidityDiscountFactor:      factors[3],
   206  								},
   207  							},
   208  							{
   209  								MinimumRunningNotionalTakerVolume: "100",
   210  								MinimumEpochs:                     "10",
   211  								ReferralRewardFactors: &types.RewardFactors{
   212  									InfrastructureRewardFactor: factors[1],
   213  									MakerRewardFactor:          factors[2],
   214  									LiquidityRewardFactor:      factors[3],
   215  								},
   216  								ReferralDiscountFactors: &types.DiscountFactors{
   217  									InfrastructureDiscountFactor: factors[2],
   218  									MakerDiscountFactor:          factors[3],
   219  									LiquidityDiscountFactor:      factors[4],
   220  								},
   221  							},
   222  							{
   223  								MinimumRunningNotionalTakerVolume: "100",
   224  								MinimumEpochs:                     "20",
   225  								ReferralRewardFactors: &types.RewardFactors{
   226  									InfrastructureRewardFactor: factors[2],
   227  									MakerRewardFactor:          factors[3],
   228  									LiquidityRewardFactor:      factors[4],
   229  								},
   230  								ReferralDiscountFactors: &types.DiscountFactors{
   231  									InfrastructureDiscountFactor: factors[3],
   232  									MakerDiscountFactor:          factors[4],
   233  									LiquidityDiscountFactor:      factors[5],
   234  								},
   235  							},
   236  						},
   237  					},
   238  				},
   239  			},
   240  		},
   241  	})
   242  
   243  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1"), fmt.Errorf("duplicate benefit tier"))
   244  	assert.NotContains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.2"), fmt.Errorf("duplicate benefit tier"))
   245  }
   246  
   247  func testSubmissionForReferralProgramUpdateWithDuplicateStakingTierEntriesFails(t *testing.T) {
   248  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   249  		Terms: &types.ProposalTerms{
   250  			Change: &types.ProposalTerms_UpdateReferralProgram{
   251  				UpdateReferralProgram: &types.UpdateReferralProgram{
   252  					Changes: &types.ReferralProgramChanges{
   253  						StakingTiers: []*types.StakingTier{
   254  							{
   255  								MinimumStakedTokens:      "100",
   256  								ReferralRewardMultiplier: "1.2",
   257  							}, {
   258  								MinimumStakedTokens:      "100",
   259  								ReferralRewardMultiplier: "1.3",
   260  							},
   261  						},
   262  					},
   263  				},
   264  			},
   265  		},
   266  	})
   267  
   268  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1"), fmt.Errorf("duplicate staking tier"))
   269  }
   270  
   271  func testSubmissionForReferralProgramUpdateWithBadFormatForTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   272  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   273  		Terms: &types.ProposalTerms{
   274  			Change: &types.ProposalTerms_UpdateReferralProgram{
   275  				UpdateReferralProgram: &types.UpdateReferralProgram{
   276  					Changes: &types.ReferralProgramChanges{
   277  						BenefitTiers: []*types.BenefitTier{
   278  							{
   279  								MinimumRunningNotionalTakerVolume: "qbc",
   280  							}, {
   281  								MinimumRunningNotionalTakerVolume: "0x32",
   282  							},
   283  						},
   284  					},
   285  				},
   286  			},
   287  		},
   288  	})
   289  
   290  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrIsNotValidNumber)
   291  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrIsNotValidNumber)
   292  }
   293  
   294  func testSubmissionForReferralProgramUpdateWithBadValueForTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   295  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   296  		Terms: &types.ProposalTerms{
   297  			Change: &types.ProposalTerms_UpdateReferralProgram{
   298  				UpdateReferralProgram: &types.UpdateReferralProgram{
   299  					Changes: &types.ReferralProgramChanges{
   300  						BenefitTiers: []*types.BenefitTier{
   301  							{
   302  								MinimumRunningNotionalTakerVolume: "0",
   303  							}, {
   304  								MinimumRunningNotionalTakerVolume: "-1",
   305  							},
   306  						},
   307  					},
   308  				},
   309  			},
   310  		},
   311  	})
   312  
   313  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrMustBePositive)
   314  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrMustBePositive)
   315  }
   316  
   317  func testSubmissionForReferralProgramUpdateWithoutTierMinimumEpochsFails(t *testing.T) {
   318  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   319  		Terms: &types.ProposalTerms{
   320  			Change: &types.ProposalTerms_UpdateReferralProgram{
   321  				UpdateReferralProgram: &types.UpdateReferralProgram{
   322  					Changes: &types.ReferralProgramChanges{
   323  						BenefitTiers: []*types.BenefitTier{
   324  							{
   325  								MinimumEpochs: "",
   326  							}, {
   327  								MinimumEpochs: "",
   328  							},
   329  						},
   330  					},
   331  				},
   332  			},
   333  		},
   334  	})
   335  
   336  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_epochs"), commands.ErrIsRequired)
   337  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_epochs"), commands.ErrIsRequired)
   338  }
   339  
   340  func testSubmissionForReferralProgramUpdateWithBadFormatForTierMinimumEpochsFails(t *testing.T) {
   341  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   342  		Terms: &types.ProposalTerms{
   343  			Change: &types.ProposalTerms_UpdateReferralProgram{
   344  				UpdateReferralProgram: &types.UpdateReferralProgram{
   345  					Changes: &types.ReferralProgramChanges{
   346  						BenefitTiers: []*types.BenefitTier{
   347  							{
   348  								MinimumEpochs: "qbc",
   349  							}, {
   350  								MinimumEpochs: "0x32",
   351  							},
   352  						},
   353  					},
   354  				},
   355  			},
   356  		},
   357  	})
   358  
   359  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_epochs"), commands.ErrIsNotValidNumber)
   360  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_epochs"), commands.ErrIsNotValidNumber)
   361  }
   362  
   363  func testSubmissionForReferralProgramUpdateWithBadValueForTierMinimumEpochsFails(t *testing.T) {
   364  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   365  		Terms: &types.ProposalTerms{
   366  			Change: &types.ProposalTerms_UpdateReferralProgram{
   367  				UpdateReferralProgram: &types.UpdateReferralProgram{
   368  					Changes: &types.ReferralProgramChanges{
   369  						BenefitTiers: []*types.BenefitTier{
   370  							{
   371  								MinimumEpochs: "0",
   372  							}, {
   373  								MinimumEpochs: "-1",
   374  							},
   375  						},
   376  					},
   377  				},
   378  			},
   379  		},
   380  	})
   381  
   382  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.minimum_epochs"), commands.ErrMustBePositive)
   383  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.minimum_epochs"), commands.ErrMustBePositive)
   384  }
   385  
   386  func testSubmissionForReferralProgramUpdateWithoutTierReferralRewardFactorFails(t *testing.T) {
   387  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   388  		Terms: &types.ProposalTerms{
   389  			Change: &types.ProposalTerms_UpdateReferralProgram{
   390  				UpdateReferralProgram: &types.UpdateReferralProgram{
   391  					Changes: &types.ReferralProgramChanges{
   392  						BenefitTiers: []*types.BenefitTier{
   393  							{
   394  								ReferralRewardFactor: "",
   395  							}, {
   396  								ReferralRewardFactor: "",
   397  							},
   398  						},
   399  					},
   400  				},
   401  			},
   402  		},
   403  	})
   404  
   405  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_reward_factors"), commands.ErrIsRequired)
   406  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_reward_factors"), commands.ErrIsRequired)
   407  }
   408  
   409  func testSubmissionForReferralProgramUpdateWithBadFormatForTierReferralRewardFactorFails(t *testing.T) {
   410  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   411  		Terms: &types.ProposalTerms{
   412  			Change: &types.ProposalTerms_UpdateReferralProgram{
   413  				UpdateReferralProgram: &types.UpdateReferralProgram{
   414  					Changes: &types.ReferralProgramChanges{
   415  						BenefitTiers: []*types.BenefitTier{
   416  							{
   417  								ReferralRewardFactors: &types.RewardFactors{
   418  									InfrastructureRewardFactor: "qbc",
   419  									MakerRewardFactor:          "qbc",
   420  									LiquidityRewardFactor:      "qbc",
   421  								},
   422  							}, {
   423  								ReferralRewardFactors: &types.RewardFactors{
   424  									InfrastructureRewardFactor: "0x32",
   425  									MakerRewardFactor:          "0x32",
   426  									LiquidityRewardFactor:      "0x32",
   427  								},
   428  							},
   429  						},
   430  					},
   431  				},
   432  			},
   433  		},
   434  	})
   435  
   436  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_reward_factors.infrastructure_reward_factor"), commands.ErrIsNotValidNumber)
   437  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_reward_factors.infrastructure_reward_factor"), commands.ErrIsNotValidNumber)
   438  }
   439  
   440  func testSubmissionForReferralProgramUpdateWithBadValueForTierReferralRewardFactorFails(t *testing.T) {
   441  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   442  		Terms: &types.ProposalTerms{
   443  			Change: &types.ProposalTerms_UpdateReferralProgram{
   444  				UpdateReferralProgram: &types.UpdateReferralProgram{
   445  					Changes: &types.ReferralProgramChanges{
   446  						BenefitTiers: []*types.BenefitTier{
   447  							{
   448  								ReferralRewardFactors: &types.RewardFactors{
   449  									InfrastructureRewardFactor: "-10",
   450  									MakerRewardFactor:          "-10",
   451  									LiquidityRewardFactor:      "-10",
   452  								},
   453  							}, {
   454  								ReferralRewardFactors: &types.RewardFactors{
   455  									InfrastructureRewardFactor: "-1",
   456  									MakerRewardFactor:          "-1",
   457  									LiquidityRewardFactor:      "-1",
   458  								},
   459  							},
   460  						},
   461  					},
   462  				},
   463  			},
   464  		},
   465  	})
   466  
   467  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_reward_factors.infrastructure_reward_factor"), commands.ErrMustBePositiveOrZero)
   468  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_reward_factors.infrastructure_reward_factor"), commands.ErrMustBePositiveOrZero)
   469  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_reward_factors.maker_reward_factor"), commands.ErrMustBePositiveOrZero)
   470  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_reward_factors.maker_reward_factor"), commands.ErrMustBePositiveOrZero)
   471  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_reward_factors.liquidity_reward_factor"), commands.ErrMustBePositiveOrZero)
   472  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_reward_factors.liquidity_reward_factor"), commands.ErrMustBePositiveOrZero)
   473  }
   474  
   475  func testSubmissionForReferralProgramUpdateWithoutTierReferralDiscountFactorFails(t *testing.T) {
   476  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   477  		Terms: &types.ProposalTerms{
   478  			Change: &types.ProposalTerms_UpdateReferralProgram{
   479  				UpdateReferralProgram: &types.UpdateReferralProgram{
   480  					Changes: &types.ReferralProgramChanges{
   481  						BenefitTiers: []*types.BenefitTier{
   482  							{
   483  								ReferralDiscountFactors: &types.DiscountFactors{},
   484  							}, {
   485  								ReferralDiscountFactors: &types.DiscountFactors{},
   486  							},
   487  						},
   488  					},
   489  				},
   490  			},
   491  		},
   492  	})
   493  
   494  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.infrastructure_discount_factor"), commands.ErrIsRequired)
   495  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.infrastructure_discount_factor"), commands.ErrIsRequired)
   496  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.maker_discount_factor"), commands.ErrIsRequired)
   497  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.maker_discount_factor"), commands.ErrIsRequired)
   498  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.liquidity_discount_factor"), commands.ErrIsRequired)
   499  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.liquidity_discount_factor"), commands.ErrIsRequired)
   500  }
   501  
   502  func testSubmissionForReferralProgramUpdateWithBadFormatForTierReferralDiscountFactorFails(t *testing.T) {
   503  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   504  		Terms: &types.ProposalTerms{
   505  			Change: &types.ProposalTerms_UpdateReferralProgram{
   506  				UpdateReferralProgram: &types.UpdateReferralProgram{
   507  					Changes: &types.ReferralProgramChanges{
   508  						BenefitTiers: []*types.BenefitTier{
   509  							{
   510  								ReferralDiscountFactors: &types.DiscountFactors{
   511  									InfrastructureDiscountFactor: "qbc",
   512  									LiquidityDiscountFactor:      "qbc",
   513  									MakerDiscountFactor:          "qbc",
   514  								},
   515  							}, {
   516  								ReferralDiscountFactors: &types.DiscountFactors{
   517  									InfrastructureDiscountFactor: "0x32",
   518  									LiquidityDiscountFactor:      "0x32",
   519  									MakerDiscountFactor:          "0x32",
   520  								},
   521  							},
   522  						},
   523  					},
   524  				},
   525  			},
   526  		},
   527  	})
   528  
   529  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.infrastructure_discount_factor"), commands.ErrIsNotValidNumber)
   530  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.infrastructure_discount_factor"), commands.ErrIsNotValidNumber)
   531  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.maker_discount_factor"), commands.ErrIsNotValidNumber)
   532  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.maker_discount_factor"), commands.ErrIsNotValidNumber)
   533  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.liquidity_discount_factor"), commands.ErrIsNotValidNumber)
   534  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.liquidity_discount_factor"), commands.ErrIsNotValidNumber)
   535  }
   536  
   537  func testSubmissionForReferralProgramUpdateWithBadValueForTierReferralDiscountFactorFails(t *testing.T) {
   538  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   539  		Terms: &types.ProposalTerms{
   540  			Change: &types.ProposalTerms_UpdateReferralProgram{
   541  				UpdateReferralProgram: &types.UpdateReferralProgram{
   542  					Changes: &types.ReferralProgramChanges{
   543  						BenefitTiers: []*types.BenefitTier{
   544  							{
   545  								ReferralDiscountFactors: &types.DiscountFactors{
   546  									InfrastructureDiscountFactor: "-10",
   547  									MakerDiscountFactor:          "-10",
   548  									LiquidityDiscountFactor:      "-10",
   549  								},
   550  							}, {
   551  								ReferralDiscountFactors: &types.DiscountFactors{
   552  									InfrastructureDiscountFactor: "-1",
   553  									MakerDiscountFactor:          "-1",
   554  									LiquidityDiscountFactor:      "-1",
   555  								},
   556  							},
   557  						},
   558  					},
   559  				},
   560  			},
   561  		},
   562  	})
   563  
   564  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.infrastructure_discount_factor"), commands.ErrMustBePositiveOrZero)
   565  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.infrastructure_discount_factor"), commands.ErrMustBePositiveOrZero)
   566  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.liquidity_discount_factor"), commands.ErrMustBePositiveOrZero)
   567  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.liquidity_discount_factor"), commands.ErrMustBePositiveOrZero)
   568  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.0.referral_discount_factors.maker_discount_factor"), commands.ErrMustBePositiveOrZero)
   569  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.benefit_tiers.1.referral_discount_factors.maker_discount_factor"), commands.ErrMustBePositiveOrZero)
   570  }
   571  
   572  func testSubmissionForReferralProgramUpdateWithoutStakingTierMinimumStakedTokensFails(t *testing.T) {
   573  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   574  		Terms: &types.ProposalTerms{
   575  			Change: &types.ProposalTerms_UpdateReferralProgram{
   576  				UpdateReferralProgram: &types.UpdateReferralProgram{
   577  					Changes: &types.ReferralProgramChanges{
   578  						StakingTiers: []*types.StakingTier{
   579  							{
   580  								MinimumStakedTokens: "",
   581  							}, {
   582  								MinimumStakedTokens: "",
   583  							},
   584  						},
   585  					},
   586  				},
   587  			},
   588  		},
   589  	})
   590  
   591  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.minimum_staked_tokens"), commands.ErrIsRequired)
   592  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.minimum_staked_tokens"), commands.ErrIsRequired)
   593  }
   594  
   595  func testSubmissionForReferralProgramUpdateWithBadFormatForStakingTierMinimumStakedTokensFails(t *testing.T) {
   596  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   597  		Terms: &types.ProposalTerms{
   598  			Change: &types.ProposalTerms_UpdateReferralProgram{
   599  				UpdateReferralProgram: &types.UpdateReferralProgram{
   600  					Changes: &types.ReferralProgramChanges{
   601  						StakingTiers: []*types.StakingTier{
   602  							{
   603  								MinimumStakedTokens: "qbc",
   604  							}, {
   605  								MinimumStakedTokens: "0x32",
   606  							},
   607  						},
   608  					},
   609  				},
   610  			},
   611  		},
   612  	})
   613  
   614  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.minimum_staked_tokens"), commands.ErrIsNotValidNumber)
   615  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.minimum_staked_tokens"), commands.ErrIsNotValidNumber)
   616  }
   617  
   618  func testSubmissionForReferralProgramUpdateWithBadValueForStakingTierMinimumStakedTokensFails(t *testing.T) {
   619  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   620  		Terms: &types.ProposalTerms{
   621  			Change: &types.ProposalTerms_UpdateReferralProgram{
   622  				UpdateReferralProgram: &types.UpdateReferralProgram{
   623  					Changes: &types.ReferralProgramChanges{
   624  						StakingTiers: []*types.StakingTier{
   625  							{
   626  								MinimumStakedTokens: "-100",
   627  							}, {
   628  								MinimumStakedTokens: "-1",
   629  							},
   630  						},
   631  					},
   632  				},
   633  			},
   634  		},
   635  	})
   636  
   637  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.minimum_staked_tokens"), commands.ErrMustBePositive)
   638  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.minimum_staked_tokens"), commands.ErrMustBePositive)
   639  }
   640  
   641  func testSubmissionForReferralProgramUpdateWithoutStakingTierReferralRewardMultiplierFails(t *testing.T) {
   642  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   643  		Terms: &types.ProposalTerms{
   644  			Change: &types.ProposalTerms_UpdateReferralProgram{
   645  				UpdateReferralProgram: &types.UpdateReferralProgram{
   646  					Changes: &types.ReferralProgramChanges{
   647  						StakingTiers: []*types.StakingTier{
   648  							{
   649  								ReferralRewardMultiplier: "",
   650  							}, {
   651  								ReferralRewardMultiplier: "",
   652  							},
   653  						},
   654  					},
   655  				},
   656  			},
   657  		},
   658  	})
   659  
   660  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.referral_reward_multiplier"), commands.ErrIsRequired)
   661  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.referral_reward_multiplier"), commands.ErrIsRequired)
   662  }
   663  
   664  func testSubmissionForReferralProgramUpdateWithBadFormatForStakingTierReferralRewardMultiplierFails(t *testing.T) {
   665  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   666  		Terms: &types.ProposalTerms{
   667  			Change: &types.ProposalTerms_UpdateReferralProgram{
   668  				UpdateReferralProgram: &types.UpdateReferralProgram{
   669  					Changes: &types.ReferralProgramChanges{
   670  						StakingTiers: []*types.StakingTier{
   671  							{
   672  								ReferralRewardMultiplier: "qbc",
   673  							}, {
   674  								ReferralRewardMultiplier: "0x32",
   675  							},
   676  						},
   677  					},
   678  				},
   679  			},
   680  		},
   681  	})
   682  
   683  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.referral_reward_multiplier"), commands.ErrIsNotValidNumber)
   684  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.referral_reward_multiplier"), commands.ErrIsNotValidNumber)
   685  }
   686  
   687  func testSubmissionForReferralProgramUpdateWithBadValueForStakingTierReferralRewardMultiplierFails(t *testing.T) {
   688  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   689  		Terms: &types.ProposalTerms{
   690  			Change: &types.ProposalTerms_UpdateReferralProgram{
   691  				UpdateReferralProgram: &types.UpdateReferralProgram{
   692  					Changes: &types.ReferralProgramChanges{
   693  						StakingTiers: []*types.StakingTier{
   694  							{
   695  								ReferralRewardMultiplier: "-0.1",
   696  							}, {
   697  								ReferralRewardMultiplier: "0",
   698  							}, {
   699  								ReferralRewardMultiplier: "0.9",
   700  							},
   701  						},
   702  					},
   703  				},
   704  			},
   705  		},
   706  	})
   707  
   708  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.0.referral_reward_multiplier"), commands.ErrMustBeGTE1)
   709  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.1.referral_reward_multiplier"), commands.ErrMustBeGTE1)
   710  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_referral_program.changes.staking_tiers.2.referral_reward_multiplier"), commands.ErrMustBeGTE1)
   711  }