code.vegaprotocol.io/vega@v0.79.0/core/governance/engine_update_discount_volume_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 governance_test 17 18 import ( 19 "testing" 20 "time" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/core/netparams" 24 "code.vegaprotocol.io/vega/core/types" 25 "code.vegaprotocol.io/vega/libs/num" 26 vgrand "code.vegaprotocol.io/vega/libs/rand" 27 vgtest "code.vegaprotocol.io/vega/libs/test" 28 29 "github.com/golang/mock/gomock" 30 "github.com/stretchr/testify/require" 31 ) 32 33 func TestProposalForUpdateDiscountVolumeProgram(t *testing.T) { 34 t.Run("Submitting a proposal for referral program update succeeds", testSubmittingProposalForVolumeDiscountProgramUpdateSucceeds) 35 t.Run("Submitting a proposal for referral program update with too many tiers fails", testSubmittingProposalForVolumeDiscountProgramUpdateWithTooManyTiersFails) 36 t.Run("Submitting a proposal for referral program update with too high discount factor fails", testSubmittingProposalForVolumeDiscountProgramUpdateWithTooHighDiscountFactorFails) 37 } 38 39 func testSubmittingProposalForVolumeDiscountProgramUpdateSucceeds(t *testing.T) { 40 now := time.Now() 41 ctx := vgtest.VegaContext(vgrand.RandomStr(5), vgtest.RandomPositiveI64()) 42 eng := getTestEngine(t, now) 43 44 // setup 45 eng.broker.EXPECT().Send(gomock.Any()).Times(3) 46 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinClose, "48h") 47 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinEnact, "48h") 48 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinProposerBalance, "1000") 49 50 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "2")).Times(1) 51 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "2")) 52 53 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")).Times(1) 54 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")) 55 56 // given 57 proposer := vgrand.RandomStr(5) 58 proposal := eng.newProposalForVolumeDiscountProgramUpdate(proposer, now, &types.VolumeDiscountProgramChanges{ 59 EndOfProgramTimestamp: now.Add(4 * 48 * time.Hour), 60 WindowLength: 15, 61 VolumeBenefitTiers: []*types.VolumeBenefitTier{ 62 { 63 MinimumRunningNotionalTakerVolume: num.NewUint(10000), 64 VolumeDiscountFactors: types.Factors{ 65 Infra: num.DecimalFromFloat(0.001), 66 Maker: num.DecimalFromFloat(0.001), 67 Liquidity: num.DecimalFromFloat(0.001), 68 }, 69 }, { 70 MinimumRunningNotionalTakerVolume: num.NewUint(20000), 71 VolumeDiscountFactors: types.Factors{ 72 Infra: num.DecimalFromFloat(0.005), 73 Maker: num.DecimalFromFloat(0.005), 74 Liquidity: num.DecimalFromFloat(0.005), 75 }, 76 }, 77 }, 78 }) 79 80 // setup 81 eng.ensureTokenBalanceForParty(t, proposer, 1000) 82 83 // expect 84 eng.expectOpenProposalEvent(t, proposer, proposal.ID) 85 86 // when 87 toSubmit, err := eng.submitProposal(t, proposal) 88 89 // then 90 require.NoError(t, err) 91 require.NotNil(t, toSubmit) 92 } 93 94 func testSubmittingProposalForVolumeDiscountProgramUpdateWithTooManyTiersFails(t *testing.T) { 95 now := time.Now() 96 ctx := vgtest.VegaContext(vgrand.RandomStr(5), vgtest.RandomPositiveI64()) 97 eng := getTestEngine(t, now) 98 99 // setup 100 eng.broker.EXPECT().Send(gomock.Any()).Times(3) 101 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinClose, "48h") 102 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinEnact, "48h") 103 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinProposerBalance, "1000") 104 105 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "1")).Times(1) 106 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "1")) 107 108 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")).Times(1) 109 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")) 110 111 // given 112 proposer := vgrand.RandomStr(5) 113 proposal := eng.newProposalForVolumeDiscountProgramUpdate(proposer, now, &types.VolumeDiscountProgramChanges{ 114 EndOfProgramTimestamp: now.Add(4 * 48 * time.Hour), 115 WindowLength: 15, 116 VolumeBenefitTiers: []*types.VolumeBenefitTier{ 117 { 118 MinimumRunningNotionalTakerVolume: num.NewUint(10000), 119 VolumeDiscountFactors: types.Factors{ 120 Infra: num.DecimalFromFloat(0.001), 121 Maker: num.DecimalFromFloat(0.001), 122 Liquidity: num.DecimalFromFloat(0.001), 123 }, 124 }, { 125 MinimumRunningNotionalTakerVolume: num.NewUint(20000), 126 VolumeDiscountFactors: types.Factors{ 127 Infra: num.DecimalFromFloat(0.005), 128 Maker: num.DecimalFromFloat(0.005), 129 Liquidity: num.DecimalFromFloat(0.005), 130 }, 131 }, 132 }, 133 }) 134 135 // setup 136 eng.ensureTokenBalanceForParty(t, proposer, 1000) 137 138 // expect 139 eng.expectRejectedProposalEvent(t, proposer, proposal.ID, types.ProposalErrorInvalidVolumeDiscountProgram) 140 141 // when 142 toSubmit, err := eng.submitProposal(t, proposal) 143 144 // then 145 require.Error(t, err) 146 require.Nil(t, toSubmit) 147 } 148 149 func testSubmittingProposalForVolumeDiscountProgramUpdateWithTooHighDiscountFactorFails(t *testing.T) { 150 now := time.Now() 151 ctx := vgtest.VegaContext(vgrand.RandomStr(5), vgtest.RandomPositiveI64()) 152 eng := getTestEngine(t, now) 153 154 // setup 155 eng.broker.EXPECT().Send(gomock.Any()).Times(3) 156 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinClose, "48h") 157 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinEnact, "48h") 158 eng.netp.Update(ctx, netparams.GovernanceProposalVolumeDiscountProgramMinProposerBalance, "1000") 159 160 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "2")).Times(1) 161 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxBenefitTiers, "2")) 162 163 eng.broker.EXPECT().Send(events.NewNetworkParameterEvent(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")).Times(1) 164 require.NoError(t, eng.netp.Update(ctx, netparams.VolumeDiscountProgramMaxVolumeDiscountFactor, "0.010")) 165 166 // given 167 proposer := vgrand.RandomStr(5) 168 proposal := eng.newProposalForVolumeDiscountProgramUpdate(proposer, now, &types.VolumeDiscountProgramChanges{ 169 EndOfProgramTimestamp: now.Add(4 * 48 * time.Hour), 170 WindowLength: 15, 171 VolumeBenefitTiers: []*types.VolumeBenefitTier{ 172 { 173 MinimumRunningNotionalTakerVolume: num.NewUint(10000), 174 VolumeDiscountFactors: types.Factors{ 175 Infra: num.DecimalFromFloat(0.001), 176 Maker: num.DecimalFromFloat(0.001), 177 Liquidity: num.DecimalFromFloat(0.001), 178 }, 179 }, { 180 MinimumRunningNotionalTakerVolume: num.NewUint(20000), 181 VolumeDiscountFactors: types.Factors{ 182 Infra: num.DecimalFromFloat(0.015), 183 Maker: num.DecimalFromFloat(0.015), 184 Liquidity: num.DecimalFromFloat(0.015), 185 }, 186 }, 187 }, 188 }) 189 190 // setup 191 eng.ensureTokenBalanceForParty(t, proposer, 1000) 192 193 // expect 194 eng.expectRejectedProposalEvent(t, proposer, proposal.ID, types.ProposalErrorInvalidVolumeDiscountProgram) 195 196 // when 197 toSubmit, err := eng.submitProposal(t, proposal) 198 199 // then 200 require.EqualError(t, 201 err, 202 "tier 2 defines a volume discount infrastructure factor higher than the maximum allowed by the network parameter \"volumeDiscountProgram.maxVolumeDiscountFactor\": maximum is 0.01, but got 0.015", 203 ) 204 require.Nil(t, toSubmit) 205 }