code.vegaprotocol.io/vega@v0.79.0/core/execution/spot/spot_monitoring_auction_execution_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 spot_test 17 18 import ( 19 "context" 20 "testing" 21 "time" 22 23 "code.vegaprotocol.io/vega/core/types" 24 vegacontext "code.vegaprotocol.io/vega/libs/context" 25 "code.vegaprotocol.io/vega/libs/crypto" 26 "code.vegaprotocol.io/vega/libs/num" 27 28 "github.com/stretchr/testify/require" 29 ) 30 31 func TestMonitoringAuction(t *testing.T) { 32 now := time.Now() 33 ctx := context.Background() 34 ctx = vegacontext.WithTraceID(ctx, crypto.RandomHash()) 35 tm := newTestMarket(t, defaultPriceMonitorSettings, &types.AuctionDuration{Duration: 1}, now) 36 37 addAccountWithAmount(tm, "party1", 100000, "ETH") 38 addAccountWithAmount(tm, "party2", 5, "BTC") 39 40 tm.market.StartOpeningAuction(ctx) 41 42 order1 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideBuy, "party1", 2, 30000) 43 conf1, err := tm.market.SubmitOrder(ctx, order1.IntoSubmission(), order1.Party, crypto.RandomHash()) 44 require.NoError(t, err) 45 46 order2 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideSell, "party2", 1, 30000) 47 _, err = tm.market.SubmitOrder(ctx, order2.IntoSubmission(), order2.Party, crypto.RandomHash()) 48 require.NoError(t, err) 49 50 tm.market.OnTick(ctx, now.Add(2*time.Second)) 51 md := tm.market.GetMarketData() 52 require.Equal(t, types.MarketTradingModeContinuous, md.MarketTradingMode) 53 54 // at this point party 1 bought 1 BTC and has one outstanding order at price 30k as we've left opening auction 55 gaBalance1, err := tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 56 require.NoError(t, err) 57 require.Equal(t, "40000", gaBalance1.Balance.String()) 58 haBalance1, err := tm.collateralEngine.GetPartyHoldingAccount("party1", tm.quoteAsset) 59 require.NoError(t, err) 60 require.Equal(t, "30000", haBalance1.Balance.String()) 61 gaBaseBalance1, err := tm.collateralEngine.GetPartyGeneralAccount("party1", tm.baseAsset) 62 require.NoError(t, err) 63 require.Equal(t, "1", gaBaseBalance1.Balance.String()) 64 65 // move the price of the remaining order of party1 significantly 66 _, err = tm.market.AmendOrder(ctx, &types.OrderAmendment{OrderID: conf1.Order.ID, Price: num.NewUint(10000)}, "party1", crypto.RandomHash()) 67 require.NoError(t, err) 68 69 gaBalance1, err = tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 70 require.NoError(t, err) 71 require.Equal(t, "60000", gaBalance1.Balance.String()) 72 haBalance1, err = tm.collateralEngine.GetPartyHoldingAccount("party1", tm.quoteAsset) 73 require.NoError(t, err) 74 require.Equal(t, "10000", haBalance1.Balance.String()) 75 76 order3 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideSell, "party2", 1, 10000) 77 _, err = tm.market.SubmitOrder(ctx, order3.IntoSubmission(), order3.Party, crypto.RandomHash()) 78 require.NoError(t, err) 79 80 tm.market.OnTick(ctx, now.Add(2*time.Second)) 81 md = tm.market.GetMarketData() 82 // we're in price monitoring!!! 83 require.Equal(t, types.MarketTradingModeMonitoringAuction, md.MarketTradingMode) 84 85 // check that the buyer transfers into holding the expected fees amounts 86 gaBalance1, err = tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 87 require.NoError(t, err) 88 require.Equal(t, "59995", gaBalance1.Balance.String()) 89 haBalance1, err = tm.collateralEngine.GetPartyHoldingAccount("party1", tm.quoteAsset) 90 require.NoError(t, err) 91 require.Equal(t, "10005", haBalance1.Balance.String()) 92 93 gaBalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 94 require.NoError(t, err) 95 require.Equal(t, "30000", gaBalance2.Balance.String()) 96 97 tm.market.OnTick(ctx, now.Add(60*time.Minute)) 98 md = tm.market.GetMarketData() 99 require.Equal(t, types.MarketTradingModeContinuous, md.MarketTradingMode) 100 101 // we're out of the monitoring auction. expect the trade to have happened and both parties paying fees 102 // both pay infra fee, none gets maker fee as we're in auction 103 gaBalance1, err = tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 104 require.NoError(t, err) 105 require.Equal(t, "59995", gaBalance1.Balance.String()) 106 haBalance1, err = tm.collateralEngine.GetPartyHoldingAccount("party1", tm.quoteAsset) 107 require.NoError(t, err) 108 require.Equal(t, "0", haBalance1.Balance.String()) 109 gaBaseBalance1, err = tm.collateralEngine.GetPartyGeneralAccount("party1", tm.baseAsset) 110 require.NoError(t, err) 111 require.Equal(t, "2", gaBaseBalance1.Balance.String()) 112 113 gaBaseBalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.baseAsset) 114 require.NoError(t, err) 115 require.Equal(t, "3", gaBaseBalance2.Balance.String()) 116 gaalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 117 require.NoError(t, err) 118 require.Equal(t, "39995", gaalance2.Balance.String()) 119 } 120 121 func TestMonitoringAuctionInsufficientFundsToCoverFeesOnAmend(t *testing.T) { 122 now := time.Now() 123 ctx := context.Background() 124 ctx = vegacontext.WithTraceID(ctx, crypto.RandomHash()) 125 tm := newTestMarket(t, defaultPriceMonitorSettings, &types.AuctionDuration{Duration: 1}, now) 126 127 addAccountWithAmount(tm, "party1", 100000, "ETH") 128 addAccountWithAmount(tm, "party2", 5, "BTC") 129 130 tm.market.StartOpeningAuction(ctx) 131 132 order1 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideBuy, "party1", 2, 30000) 133 conf1, err := tm.market.SubmitOrder(ctx, order1.IntoSubmission(), order1.Party, crypto.RandomHash()) 134 require.NoError(t, err) 135 136 order2 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideSell, "party2", 1, 30000) 137 _, err = tm.market.SubmitOrder(ctx, order2.IntoSubmission(), order2.Party, crypto.RandomHash()) 138 require.NoError(t, err) 139 140 tm.market.OnTick(ctx, now.Add(2*time.Second)) 141 md := tm.market.GetMarketData() 142 require.Equal(t, types.MarketTradingModeContinuous, md.MarketTradingMode) 143 144 // move the price of the remaining order of party1 significantly 145 _, err = tm.market.AmendOrder(ctx, &types.OrderAmendment{OrderID: conf1.Order.ID, Price: num.NewUint(10000)}, "party1", crypto.RandomHash()) 146 require.NoError(t, err) 147 148 // submit an order to get us into price monitoring auction 149 order3 := getGTCLimitOrder(tm, now, crypto.RandomHash(), types.SideSell, "party2", 1, 10000) 150 _, err = tm.market.SubmitOrder(ctx, order3.IntoSubmission(), order3.Party, crypto.RandomHash()) 151 require.NoError(t, err) 152 153 tm.market.OnTick(ctx, now.Add(2*time.Second)) 154 md = tm.market.GetMarketData() 155 // we're in price monitoring!!! 156 require.Equal(t, types.MarketTradingModeMonitoringAuction, md.MarketTradingMode) 157 158 // try to increase the size by 6 for party 1, this would require them to have in their general account 60k + infra fee which they don't have so expect a failure 159 _, err = tm.market.AmendOrder(ctx, &types.OrderAmendment{OrderID: conf1.Order.ID, Price: num.NewUint(10000), SizeDelta: 6}, "party1", crypto.RandomHash()) 160 require.Equal(t, "party does not have sufficient balance to cover the trade and fees", err.Error()) 161 }