code.vegaprotocol.io/vega@v0.79.0/commands/proposal_submission_update_volume_discount_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  	"testing"
    20  
    21  	"code.vegaprotocol.io/vega/commands"
    22  	types "code.vegaprotocol.io/vega/protos/vega"
    23  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func TestCheckProposalSubmissionForVolumeDiscountProgramUpdate(t *testing.T) {
    29  	t.Run("Submitting a volume discount program update without update fails", testSubmissionForVolumeDiscountProgramUpdateWithoutUpdateFails)
    30  	t.Run("Submitting a volume discount program update without changes fails", testSubmissionForVolumeDiscountProgramUpdateWithoutChangesFails)
    31  	t.Run("Submitting a volume discount program update without end of program timestamp fails", testSubmissionForVolumeDiscountProgramUpdateWithoutEndOfProgramFails)
    32  	t.Run("Submitting a volume discount program update with negative end of program timestamp fails", testSubmissionForVolumeDiscountProgramUpdateWithNegativeEndOfProgramFails)
    33  	t.Run("Submitting a volume discount program update with end of program before enactment timestamp fails", testSubmissionForVolumeDiscountProgramUpdateWithEndOfProgramBeforeEnactmentFails)
    34  	t.Run("Submitting a volume discount program update without window length fails", testSubmissionForVolumeDiscountProgramUpdateWithoutWindowLengthFails)
    35  	t.Run("Submitting a volume discount program update with window length over limit fails", testSubmissionForVolumeDiscountProgramUpdateWithWindowLengthOverLimitFails)
    36  	t.Run("Submitting a volume discount program update without tier minimum running volume fails", testSubmissionForVolumeDiscountProgramUpdateWithoutTierMinimumRunningNotionalTakerVolumeFails)
    37  	t.Run("Submitting a volume discount program update with bad format for tier minimum running volume fails", testSubmissionForVolumeDiscountProgramUpdateWithBadFormatForTierMinimumRunningNotionalTakerVolumeFails)
    38  	t.Run("Submitting a volume discount program update with bad value for tier minimum running volume fails", testSubmissionForVolumeDiscountProgramUpdateWithBadValueForTierMinimumRunningNotionalTakerVolumeFails)
    39  	t.Run("Submitting a volume discount program update without tier volume discount factor fails", testSubmissionForVolumeDiscountProgramUpdateWithoutTierVolumeDiscountFactorFails)
    40  	t.Run("Submitting a volume discount program update with bad format for tier volume discount factor fails", testSubmissionForVolumeDiscountProgramUpdateWithBadFormatForTierVolumeDiscountFactorFails)
    41  	t.Run("Submitting a volume discount program update with bad value for tier volume discount factor fails", testSubmissionForVolumeDiscountProgramUpdateWithBadValueForTierVolumeDiscountFactorFails)
    42  }
    43  
    44  func testSubmissionForVolumeDiscountProgramUpdateWithoutUpdateFails(t *testing.T) {
    45  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    46  		Terms: &types.ProposalTerms{
    47  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{},
    48  		},
    49  	})
    50  
    51  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program"), commands.ErrIsRequired)
    52  }
    53  
    54  func testSubmissionForVolumeDiscountProgramUpdateWithoutChangesFails(t *testing.T) {
    55  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    56  		Terms: &types.ProposalTerms{
    57  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
    58  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{},
    59  			},
    60  		},
    61  	})
    62  
    63  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes"), commands.ErrIsRequired)
    64  }
    65  
    66  func testSubmissionForVolumeDiscountProgramUpdateWithoutEndOfProgramFails(t *testing.T) {
    67  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    68  		Terms: &types.ProposalTerms{
    69  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
    70  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
    71  					Changes: &types.VolumeDiscountProgramChanges{
    72  						EndOfProgramTimestamp: 0,
    73  					},
    74  				},
    75  			},
    76  		},
    77  	})
    78  
    79  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.end_of_program_timestamp"), commands.ErrIsRequired)
    80  }
    81  
    82  func testSubmissionForVolumeDiscountProgramUpdateWithNegativeEndOfProgramFails(t *testing.T) {
    83  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
    84  		Terms: &types.ProposalTerms{
    85  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
    86  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
    87  					Changes: &types.VolumeDiscountProgramChanges{
    88  						EndOfProgramTimestamp: -1,
    89  					},
    90  				},
    91  			},
    92  		},
    93  	})
    94  
    95  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.end_of_program_timestamp"), commands.ErrMustBePositive)
    96  }
    97  
    98  func testSubmissionForVolumeDiscountProgramUpdateWithEndOfProgramBeforeEnactmentFails(t *testing.T) {
    99  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   100  		Terms: &types.ProposalTerms{
   101  			EnactmentTimestamp: 10,
   102  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   103  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   104  					Changes: &types.VolumeDiscountProgramChanges{
   105  						EndOfProgramTimestamp: 5,
   106  					},
   107  				},
   108  			},
   109  		},
   110  	})
   111  
   112  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.end_of_program_timestamp"), commands.ErrMustBeGreaterThanEnactmentTimestamp)
   113  }
   114  
   115  func testSubmissionForVolumeDiscountProgramUpdateWithoutWindowLengthFails(t *testing.T) {
   116  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   117  		Terms: &types.ProposalTerms{
   118  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   119  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   120  					Changes: &types.VolumeDiscountProgramChanges{
   121  						WindowLength: 0,
   122  					},
   123  				},
   124  			},
   125  		},
   126  	})
   127  
   128  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.window_length"), commands.ErrIsRequired)
   129  }
   130  
   131  func testSubmissionForVolumeDiscountProgramUpdateWithWindowLengthOverLimitFails(t *testing.T) {
   132  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   133  		Terms: &types.ProposalTerms{
   134  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   135  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   136  					Changes: &types.VolumeDiscountProgramChanges{
   137  						WindowLength: 201,
   138  					},
   139  				},
   140  			},
   141  		},
   142  	})
   143  
   144  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.window_length"), commands.ErrMustBeAtMost200)
   145  }
   146  
   147  func testSubmissionForVolumeDiscountProgramUpdateWithoutTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   148  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   149  		Terms: &types.ProposalTerms{
   150  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   151  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   152  					Changes: &types.VolumeDiscountProgramChanges{
   153  						BenefitTiers: []*types.VolumeBenefitTier{
   154  							{
   155  								MinimumRunningNotionalTakerVolume: "",
   156  							}, {
   157  								MinimumRunningNotionalTakerVolume: "",
   158  							},
   159  						},
   160  					},
   161  				},
   162  			},
   163  		},
   164  	})
   165  
   166  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrIsRequired)
   167  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrIsRequired)
   168  }
   169  
   170  func testSubmissionForVolumeDiscountProgramUpdateWithBadFormatForTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   171  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   172  		Terms: &types.ProposalTerms{
   173  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   174  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   175  					Changes: &types.VolumeDiscountProgramChanges{
   176  						BenefitTiers: []*types.VolumeBenefitTier{
   177  							{
   178  								MinimumRunningNotionalTakerVolume: "qbc",
   179  							}, {
   180  								MinimumRunningNotionalTakerVolume: "0x32",
   181  							},
   182  						},
   183  					},
   184  				},
   185  			},
   186  		},
   187  	})
   188  
   189  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrIsNotValidNumber)
   190  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrIsNotValidNumber)
   191  }
   192  
   193  func testSubmissionForVolumeDiscountProgramUpdateWithBadValueForTierMinimumRunningNotionalTakerVolumeFails(t *testing.T) {
   194  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   195  		Terms: &types.ProposalTerms{
   196  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   197  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   198  					Changes: &types.VolumeDiscountProgramChanges{
   199  						BenefitTiers: []*types.VolumeBenefitTier{
   200  							{
   201  								MinimumRunningNotionalTakerVolume: "0",
   202  							}, {
   203  								MinimumRunningNotionalTakerVolume: "-1",
   204  							},
   205  						},
   206  					},
   207  				},
   208  			},
   209  		},
   210  	})
   211  
   212  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.minimum_running_notional_taker_volume"), commands.ErrMustBePositive)
   213  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.minimum_running_notional_taker_volume"), commands.ErrMustBePositive)
   214  }
   215  
   216  func testSubmissionForVolumeDiscountProgramUpdateWithoutTierVolumeDiscountFactorFails(t *testing.T) {
   217  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   218  		Terms: &types.ProposalTerms{
   219  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   220  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   221  					Changes: &types.VolumeDiscountProgramChanges{
   222  						BenefitTiers: []*types.VolumeBenefitTier{
   223  							{}, {},
   224  						},
   225  					},
   226  				},
   227  			},
   228  		},
   229  	})
   230  
   231  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors"), commands.ErrIsRequired)
   232  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.volume_discount_factors"), commands.ErrIsRequired)
   233  }
   234  
   235  func testSubmissionForVolumeDiscountProgramUpdateWithBadFormatForTierVolumeDiscountFactorFails(t *testing.T) {
   236  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   237  		Terms: &types.ProposalTerms{
   238  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   239  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   240  					Changes: &types.VolumeDiscountProgramChanges{
   241  						BenefitTiers: []*types.VolumeBenefitTier{
   242  							{
   243  								VolumeDiscountFactors: &types.DiscountFactors{
   244  									InfrastructureDiscountFactor: "qbc",
   245  									LiquidityDiscountFactor:      "qbc",
   246  									MakerDiscountFactor:          "qbc",
   247  								},
   248  							}, {
   249  								VolumeDiscountFactors: &types.DiscountFactors{
   250  									InfrastructureDiscountFactor: "0x32",
   251  									LiquidityDiscountFactor:      "0x32",
   252  									MakerDiscountFactor:          "0x32",
   253  								},
   254  							},
   255  						},
   256  					},
   257  				},
   258  			},
   259  		},
   260  	})
   261  
   262  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.maker_discount_factor"), commands.ErrIsNotValidNumber)
   263  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.liquidity_discount_factor"), commands.ErrIsNotValidNumber)
   264  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.infrastructure_discount_factor"), commands.ErrIsNotValidNumber)
   265  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.volume_discount_factors.maker_discount_factor"), commands.ErrIsNotValidNumber)
   266  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.volume_discount_factors.liquidity_discount_factor"), commands.ErrIsNotValidNumber)
   267  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.1.volume_discount_factors.infrastructure_discount_factor"), commands.ErrIsNotValidNumber)
   268  }
   269  
   270  func testSubmissionForVolumeDiscountProgramUpdateWithBadValueForTierVolumeDiscountFactorFails(t *testing.T) {
   271  	err := checkProposalSubmission(&commandspb.ProposalSubmission{
   272  		Terms: &types.ProposalTerms{
   273  			Change: &types.ProposalTerms_UpdateVolumeDiscountProgram{
   274  				UpdateVolumeDiscountProgram: &types.UpdateVolumeDiscountProgram{
   275  					Changes: &types.VolumeDiscountProgramChanges{
   276  						BenefitTiers: []*types.VolumeBenefitTier{
   277  							{
   278  								VolumeDiscountFactors: &types.DiscountFactors{
   279  									InfrastructureDiscountFactor: "-10",
   280  									LiquidityDiscountFactor:      "-5",
   281  									MakerDiscountFactor:          "-7",
   282  								},
   283  							}, {
   284  								VolumeDiscountFactors: &types.DiscountFactors{
   285  									InfrastructureDiscountFactor: "-1",
   286  									LiquidityDiscountFactor:      "-3",
   287  									MakerDiscountFactor:          "-9",
   288  								},
   289  							},
   290  						},
   291  					},
   292  				},
   293  			},
   294  		},
   295  	})
   296  
   297  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.maker_discount_factor"), commands.ErrMustBePositiveOrZero)
   298  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.liquidity_discount_factor"), commands.ErrMustBePositiveOrZero)
   299  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.infrastructure_discount_factor"), commands.ErrMustBePositiveOrZero)
   300  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.maker_discount_factor"), commands.ErrMustBePositiveOrZero)
   301  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.liquidity_discount_factor"), commands.ErrMustBePositiveOrZero)
   302  	assert.Contains(t, err.Get("proposal_submission.terms.change.update_volume_discount_program.changes.benefit_tiers.0.volume_discount_factors.infrastructure_discount_factor"), commands.ErrMustBePositiveOrZero)
   303  }