code.vegaprotocol.io/vega@v0.79.0/core/governance/engine_update_market_state_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/governance"
    23  	"code.vegaprotocol.io/vega/core/types"
    24  	"code.vegaprotocol.io/vega/libs/num"
    25  
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func TestSubmittingProposalForTerminateMarketSucceeds(t *testing.T) {
    30  	eng := getTestEngine(t, time.Now())
    31  
    32  	// given
    33  	party := eng.newValidParty("a-valid-party", 123456789)
    34  	proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(2*time.Hour), types.MarketStateUpdateTypeTerminate, nil)
    35  
    36  	// setup
    37  	eng.ensureAllAssetEnabled(t)
    38  	eng.expectOpenProposalEvent(t, party.Id, proposal.ID)
    39  	eng.ensureEquityLikeShareForMarketAndParty(t, proposal.UpdateMarketState().Changes.MarketID, party.Id, 0.1)
    40  	eng.markets.EXPECT().MarketExists(proposal.UpdateMarketState().Changes.MarketID).Times(2).Return(true)
    41  	eng.markets.EXPECT().GetMarketState(proposal.UpdateMarketState().Changes.MarketID).Times(1).Return(types.MarketStateActive, nil)
    42  
    43  	// when
    44  	toSubmit, err := eng.submitProposal(t, proposal)
    45  
    46  	// then
    47  	require.NoError(t, err)
    48  	require.NotNil(t, toSubmit)
    49  	require.True(t, toSubmit.Proposal().IsMarketStateUpdate())
    50  }
    51  
    52  func TestSubmittingProposalForUpdateMarketStateInTerminalStateFails(t *testing.T) {
    53  	states := []types.MarketState{
    54  		types.MarketStateCancelled, types.MarketStateClosed, types.MarketStateTradingTerminated, types.MarketStateSettled, types.MarketStateProposed,
    55  	}
    56  	updateType := []types.MarketStateUpdateType{types.MarketStateUpdateTypeResume, types.MarketStateUpdateTypeSuspend, types.MarketStateUpdateTypeTerminate}
    57  	// given
    58  	eng := getTestEngine(t, time.Now())
    59  	party := eng.newValidParty("a-valid-party", 123456789)
    60  	for _, invalidState := range states {
    61  		for _, msu := range updateType {
    62  			proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(2*time.Hour), msu, nil)
    63  			// setup
    64  			eng.ensureAllAssetEnabled(t)
    65  			eng.ensureEquityLikeShareForMarketAndParty(t, proposal.UpdateMarketState().Changes.MarketID, party.Id, 0.1)
    66  			eng.markets.EXPECT().MarketExists(proposal.UpdateMarketState().Changes.MarketID).Times(2).Return(true)
    67  			eng.markets.EXPECT().GetMarketState(proposal.UpdateMarketState().Changes.MarketID).Times(1).Return(invalidState, nil)
    68  			eng.expectRejectedProposalEvent(t, party.Id, proposal.ID, types.ProposalErrorInvalidMarket)
    69  
    70  			// when
    71  			toSubmit, err := eng.submitProposal(t, proposal)
    72  
    73  			// then
    74  			require.Equal(t, "market state does not allow for state update", err.Error())
    75  			require.Nil(t, toSubmit)
    76  		}
    77  	}
    78  }
    79  
    80  func TestSubmittingProposalForUpdateMarketStateForUnknownMarketFails(t *testing.T) {
    81  	eng := getTestEngine(t, time.Now())
    82  
    83  	updateType := []types.MarketStateUpdateType{types.MarketStateUpdateTypeResume, types.MarketStateUpdateTypeSuspend, types.MarketStateUpdateTypeTerminate}
    84  	party := eng.newValidParty("a-valid-party", 123456789)
    85  
    86  	for _, msu := range updateType {
    87  		proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(2*time.Hour), msu, nil)
    88  		// given
    89  		proposer := party.Id
    90  		marketID := proposal.UpdateMarketState().Changes.MarketID
    91  
    92  		// setup
    93  		eng.ensureTokenBalanceForParty(t, proposer, 123456789)
    94  		eng.ensureNonExistingMarket(t, marketID)
    95  
    96  		// expect
    97  		eng.expectRejectedProposalEvent(t, proposer, proposal.ID, types.ProposalErrorInvalidMarket)
    98  
    99  		// when
   100  		toSubmit, err := eng.submitProposal(t, proposal)
   101  
   102  		// then
   103  		require.ErrorIs(t, governance.ErrMarketDoesNotExist, err)
   104  		require.Nil(t, toSubmit)
   105  	}
   106  }
   107  
   108  func TestSubmittingProposalForUpdateMarketStateWithInvalidSettlementDataFails(t *testing.T) {
   109  	eng := getTestEngine(t, time.Now())
   110  	party := eng.newValidParty("party1", 123456789)
   111  	price := num.NewUint(123456789)
   112  	eng.ensureTokenBalanceForParty(t, party.Id, 123456789)
   113  	proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(1*time.Hour), types.MarketStateUpdateTypeTerminate, price)
   114  	eng.ensureEquityLikeShareForMarketAndParty(t, proposal.UpdateMarketState().Changes.MarketID, party.Id, 0.1)
   115  	mID := proposal.UpdateMarketState().Changes.MarketID
   116  	eng.markets.EXPECT().MarketExists(mID).Times(2).Return(true)
   117  	eng.markets.EXPECT().GetMarketState(mID).Times(1).Return(types.MarketStateActive, nil)
   118  	eng.markets.EXPECT().ValidateSettlementData(mID, price).Times(1).Return(false)
   119  	eng.expectRejectedProposalEvent(t, party.Id, proposal.ID, types.ProposalErrorInvalidStateUpdate)
   120  	toSubmit, err := eng.submitProposal(t, proposal)
   121  	require.Error(t, err)
   122  	require.Nil(t, toSubmit)
   123  }
   124  
   125  func TestSubmittingProposalForUpdateMarketStateWithValidSettlementDataSucceeds(t *testing.T) {
   126  	eng := getTestEngine(t, time.Now())
   127  	party := eng.newValidParty("party1", 123456789)
   128  	price := num.NewUint(123456789)
   129  	eng.ensureTokenBalanceForParty(t, party.Id, 123456789)
   130  	proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(1*time.Hour), types.MarketStateUpdateTypeTerminate, price)
   131  	eng.ensureEquityLikeShareForMarketAndParty(t, proposal.UpdateMarketState().Changes.MarketID, party.Id, 0.1)
   132  	mID := proposal.UpdateMarketState().Changes.MarketID
   133  	eng.markets.EXPECT().MarketExists(mID).Times(2).Return(true)
   134  	eng.markets.EXPECT().GetMarketState(mID).Times(1).Return(types.MarketStateActive, nil)
   135  	eng.markets.EXPECT().ValidateSettlementData(mID, price).Times(1).Return(true)
   136  	eng.expectOpenProposalEvent(t, party.Id, proposal.ID)
   137  	toSubmit, err := eng.submitProposal(t, proposal)
   138  	require.NoError(t, err)
   139  	require.NotNil(t, toSubmit)
   140  	require.True(t, toSubmit.Proposal().IsMarketStateUpdate())
   141  }
   142  
   143  func TestSubmittingProposalForUpdateMarketStateWithoutSettlementDataSucceeds(t *testing.T) {
   144  	eng := getTestEngine(t, time.Now())
   145  	party := eng.newValidParty("party1", 123456789)
   146  	eng.ensureTokenBalanceForParty(t, party.Id, 123456789)
   147  	proposal := eng.newProposalForUpdateMarketState(party.Id, eng.tsvc.GetTimeNow().Add(1*time.Hour), types.MarketStateUpdateTypeTerminate, nil)
   148  	eng.ensureEquityLikeShareForMarketAndParty(t, proposal.UpdateMarketState().Changes.MarketID, party.Id, 0.1)
   149  	mID := proposal.UpdateMarketState().Changes.MarketID
   150  	eng.markets.EXPECT().MarketExists(mID).Times(2).Return(true)
   151  	eng.markets.EXPECT().GetMarketState(mID).Times(1).Return(types.MarketStateActive, nil)
   152  	eng.expectOpenProposalEvent(t, party.Id, proposal.ID)
   153  	toSubmit, err := eng.submitProposal(t, proposal)
   154  	require.NoError(t, err)
   155  	require.NotNil(t, toSubmit)
   156  	require.True(t, toSubmit.Proposal().IsMarketStateUpdate())
   157  }