diff --git a/commands/proposal_submission.go b/commands/proposal_submission.go index c322688629a..30a175dfea4 100644 --- a/commands/proposal_submission.go +++ b/commands/proposal_submission.go @@ -54,8 +54,6 @@ var validTransfers = map[protoTypes.AccountType]map[protoTypes.AccountType]struc }, protoTypes.AccountType_ACCOUNT_TYPE_INSURANCE: { protoTypes.AccountType_ACCOUNT_TYPE_GENERAL: {}, - protoTypes.AccountType_ACCOUNT_TYPE_BOND: {}, - protoTypes.AccountType_ACCOUNT_TYPE_MARGIN: {}, protoTypes.AccountType_ACCOUNT_TYPE_GLOBAL_INSURANCE: {}, protoTypes.AccountType_ACCOUNT_TYPE_INSURANCE: {}, protoTypes.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY: {}, @@ -71,8 +69,6 @@ var validTransfers = map[protoTypes.AccountType]map[protoTypes.AccountType]struc }, protoTypes.AccountType_ACCOUNT_TYPE_GLOBAL_INSURANCE: { protoTypes.AccountType_ACCOUNT_TYPE_GENERAL: {}, - protoTypes.AccountType_ACCOUNT_TYPE_BOND: {}, - protoTypes.AccountType_ACCOUNT_TYPE_MARGIN: {}, protoTypes.AccountType_ACCOUNT_TYPE_INSURANCE: {}, protoTypes.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY: {}, protoTypes.AccountType_ACCOUNT_TYPE_GLOBAL_REWARD: {}, diff --git a/commands/proposal_submission_new_transfer_test.go b/commands/proposal_submission_new_transfer_test.go index 7fa24d8da22..1d4c6e4a6e7 100644 --- a/commands/proposal_submission_new_transfer_test.go +++ b/commands/proposal_submission_new_transfer_test.go @@ -18,6 +18,7 @@ package commands_test import ( "errors" "testing" + "time" "code.vegaprotocol.io/vega/commands" "code.vegaprotocol.io/vega/libs/crypto" @@ -50,6 +51,7 @@ func TestCheckProposalSubmissionForNewTransfer(t *testing.T) { t.Run("Submitting a new recurring transfer change with a dispatch strategy and incompatible empty asset for metric", testInvalidAssetForMetric) t.Run("Submitting a new recurring transfer change with a dispatch strategy and mismatching destination type for metric", testInvalidDestForMetric) t.Run("Submitting a new transfer change with destination type general and an invalid vega public key", testInvalidGeneralPubKey) + t.Run("Submitting a new transfer change with destination type general and an invalid vega public key", testOnlyGeneralValid) } func testInvalidDestForMetric(t *testing.T) { @@ -326,6 +328,77 @@ func testOneOffWithNegativeDeliverOn(t *testing.T) { require.Contains(t, err.Get("proposal_submission.terms.change.new_transfer.changes.oneoff.deliveron"), commands.ErrMustBePositiveOrZero) } +func testOnlyGeneralValid(t *testing.T) { + partyAccs := []types.AccountType{ + types.AccountType_ACCOUNT_TYPE_MARGIN, + types.AccountType_ACCOUNT_TYPE_BOND, + } + // start with a valid transfer to the general account + prop := &commandspb.ProposalSubmission{ + Rationale: &types.ProposalRationale{ + Description: "valid", + Title: "test", + }, + Terms: &types.ProposalTerms{ + ClosingTimestamp: time.Now().Unix() + 100, + EnactmentTimestamp: time.Now().Unix() + 200, + Change: &types.ProposalTerms_NewTransfer{ + NewTransfer: &types.NewTransfer{ + Changes: &types.NewTransferConfiguration{ + FractionOfBalance: "0.5", + Amount: "1000", + SourceType: types.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY, + DestinationType: types.AccountType_ACCOUNT_TYPE_GENERAL, + Destination: crypto.RandomHash(), + TransferType: types.GovernanceTransferType_GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING, + Asset: "abcde", + Kind: &types.NewTransferConfiguration_OneOff{ + OneOff: &types.OneOffTransfer{ + DeliverOn: 0, + }, + }, + }, + }, + }, + }, + } + err := checkProposalSubmission(prop) + require.True(t, err.Empty()) + // none of the other accounts are valid destination types: + for _, at := range partyAccs { + prop := &commandspb.ProposalSubmission{ + Rationale: &types.ProposalRationale{ + Description: "invalid", + Title: "test", + }, + Terms: &types.ProposalTerms{ + ClosingTimestamp: time.Now().Unix() + 100, + EnactmentTimestamp: time.Now().Unix() + 200, + Change: &types.ProposalTerms_NewTransfer{ + NewTransfer: &types.NewTransfer{ + Changes: &types.NewTransferConfiguration{ + FractionOfBalance: "0.5", + Amount: "1000", + SourceType: types.AccountType_ACCOUNT_TYPE_NETWORK_TREASURY, + DestinationType: at, + Destination: crypto.RandomHash(), // ensure a valid hash + TransferType: types.GovernanceTransferType_GOVERNANCE_TRANSFER_TYPE_ALL_OR_NOTHING, + Asset: "abcde", + Kind: &types.NewTransferConfiguration_OneOff{ + OneOff: &types.OneOffTransfer{ + DeliverOn: 0, + }, + }, + }, + }, + }, + }, + } + err = checkProposalSubmission(prop) + require.Contains(t, err.Get("proposal_submission.terms.change.new_transfer.changes.destination_type"), commands.ErrIsNotValid) + } +} + func testInvalidGeneralPubKey(t *testing.T) { err := checkProposalSubmission(&commandspb.ProposalSubmission{ Terms: &types.ProposalTerms{ diff --git a/core/integration/features/perpetual.feature b/core/integration/features/perpetual.feature index 73d709e639d..0f304d6b543 100644 --- a/core/integration/features/perpetual.feature +++ b/core/integration/features/perpetual.feature @@ -122,3 +122,83 @@ Feature: Simple test creating a perpetual market. | market id | state | settlement price | | ETH/DEC19 | MARKET_STATE_UPDATE_TYPE_TERMINATE | 976 | Then the market state should be "STATE_CLOSED" for the market "ETH/DEC19" + + @PerpetualCancel + Scenario: 003 Cancel a perps market in opening auction + # the amount ought to be 390,500.000,000,000,000,000,000 + Given the parties submit the following liquidity provision: + | id | party | market id | commitment amount | fee | lp type | + | lp1 | lpprov | ETH/DEC19 | 3905000000000000 | 0.3 | submission | + And the parties place the following pegged iceberg orders: + | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | reference | + | lpprov | ETH/DEC19 | 4000000000000000 | 3905000000000000 | buy | BID | 4000000000000000 | 1 | lp-ice-buy | + | lpprov | ETH/DEC19 | 4000000000000000 | 3905000000000000 | sell | ASK | 4000000000000000 | 1 | lp-ice-sell | + And the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader1 | ETH/DEC19 | buy | 5 | 1001 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-1 | + | trader1 | ETH/DEC19 | buy | 5 | 900 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-2 | + | trader1 | ETH/DEC19 | buy | 1 | 100 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-3 | + | trader2 | ETH/DEC19 | sell | 5 | 1200 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-1 | + | trader2 | ETH/DEC19 | sell | 1 | 100000 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-2 | + When the opening auction period ends for market "ETH/DEC19" + Then the market data for the market "ETH/DEC19" should be: + | mark price | trading mode | auction trigger | + | 0 | TRADING_MODE_OPENING_AUCTION | AUCTION_TRIGGER_OPENING | + And the parties should have the following account balances: + | party | asset | market id | margin | general | + | trader1 | ETH | ETH/DEC19 | 60659552186 | 9999999999999939340447814 | + + + # example of how to use the oracle + When the oracles broadcast data with block time signed with "0xCAFECAFE1": + | name | value | time offset | + | perp.ETH.value | 975 | -2s | + | perp.ETH.value | 977 | -1s | + + And the parties place the following orders with ticks: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader2 | ETH/DEC19 | sell | 1 | 951 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-2 | + Then the market data for the market "ETH/DEC19" should be: + | mark price | trading mode | auction trigger | + | 976 | TRADING_MODE_CONTINUOUS | AUCTION_TRIGGER_UNSPECIFIED | + When the market states are updated through governance: + | market id | state | settlement price | + | ETH/DEC19 | MARKET_STATE_UPDATE_TYPE_TERMINATE | 976 | + Then the market state should be "STATE_CLOSED" for the market "ETH/DEC19" + + @PerpetualCancel + Scenario: 003 Cancel a perps market in opening auction + # the amount ought to be 390,500.000,000,000,000,000,000 + Given the parties submit the following liquidity provision: + | id | party | market id | commitment amount | fee | lp type | + | lp1 | lpprov | ETH/DEC19 | 3905000000000000 | 0.3 | submission | + And the parties place the following pegged iceberg orders: + | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | reference | + | lpprov | ETH/DEC19 | 4000000000000000 | 3905000000000000 | buy | BID | 4000000000000000 | 1 | lp-ice-buy | + | lpprov | ETH/DEC19 | 4000000000000000 | 3905000000000000 | sell | ASK | 4000000000000000 | 1 | lp-ice-sell | + And the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | reference | + | trader1 | ETH/DEC19 | buy | 5 | 1001 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-1 | + | trader1 | ETH/DEC19 | buy | 5 | 900 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-2 | + | trader1 | ETH/DEC19 | buy | 1 | 100 | 0 | TYPE_LIMIT | TIF_GTC | t1-b-3 | + | trader2 | ETH/DEC19 | sell | 5 | 1200 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-1 | + | trader2 | ETH/DEC19 | sell | 1 | 100000 | 0 | TYPE_LIMIT | TIF_GTC | t2-s-2 | + When the opening auction period ends for market "ETH/DEC19" + Then the market data for the market "ETH/DEC19" should be: + | mark price | trading mode | auction trigger | + | 0 | TRADING_MODE_OPENING_AUCTION | AUCTION_TRIGGER_OPENING | + And the parties should have the following account balances: + | party | asset | market id | margin | general | + | trader1 | ETH | ETH/DEC19 | 60659552186 | 9999999999999939340447814 | + + + # example of how to use the oracle + When the oracles broadcast data with block time signed with "0xCAFECAFE1": + | name | value | time offset | + | perp.ETH.value | 975 | -2s | + | perp.ETH.value | 977 | -1s | + + And the market states are updated through governance: + | market id | state | settlement price | + | ETH/DEC19 | MARKET_STATE_UPDATE_TYPE_TERMINATE | 976 | + Then the market state should be "STATE_CANCELLED" for the market "ETH/DEC19"