code.vegaprotocol.io/vega@v0.79.0/core/execution/spot/fees_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 27 "github.com/stretchr/testify/require" 28 ) 29 30 func setupToLeaveOpeningAuction(t *testing.T) (*testMarket, context.Context) { 31 t.Helper() 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 _, 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.now = now.Add(2 * time.Second) 51 tm.market.OnTick(ctx, tm.now) 52 md := tm.market.GetMarketData() 53 require.Equal(t, types.MarketTradingModeContinuous, md.MarketTradingMode) 54 return tm, ctx 55 } 56 57 func TestNoFeesInOpeningAuction(t *testing.T) { 58 tm, _ := setupToLeaveOpeningAuction(t) 59 60 // at this point party 1 bought 1 BTC and has one outstanding order at price 30k as we've left opening auction 61 gaBalance1, err := tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 62 require.NoError(t, err) 63 require.Equal(t, "40000", gaBalance1.Balance.String()) 64 65 gaBalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 66 require.NoError(t, err) 67 require.Equal(t, "30000", gaBalance2.Balance.String()) 68 } 69 70 func TestSellerAggressorInContinuousMode(t *testing.T) { 71 tm, ctx := setupToLeaveOpeningAuction(t) 72 73 // there's already an open buy order for 30k in the book from the setup so we only need to setup the 74 // sell aggressive order 75 // setup the aggressive sell order 76 77 // lets check first what is the balance of party2 in the quote asset before the trade 78 gaBalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 79 require.NoError(t, err) 80 require.Equal(t, "30000", gaBalance2.Balance.String()) // the 40k they had from before + the maker fee received 81 82 sellOrder := getGTCLimitOrder(tm, tm.now, crypto.RandomHash(), types.SideSell, "party2", 1, 30000) 83 conf, err := tm.market.SubmitOrder(ctx, sellOrder.IntoSubmission(), sellOrder.Party, crypto.RandomHash()) 84 require.NoError(t, err) 85 require.Equal(t, 1, len(conf.Trades)) 86 87 // the trade price is 30000, however the aggressor, i.e. the seller pays the fee, instead of getting 30000 they get 30000 - fee 88 gaBalance1, err := tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 89 require.NoError(t, err) 90 require.Equal(t, "40120", gaBalance1.Balance.String()) // the 40k they had from before + the maker fee received 91 92 // they had 30k, they get 30k - fees added to their general account in the quote asset 93 gaBalance2, err = tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 94 require.NoError(t, err) 95 require.Equal(t, "59850", gaBalance2.Balance.String()) 96 } 97 98 func TestBuyAggressorInContinuousMode(t *testing.T) { 99 tm, ctx := setupToLeaveOpeningAuction(t) 100 // first lets close the open buy trade in the book 101 102 sellOrder := getGTCLimitOrder(tm, tm.now, crypto.RandomHash(), types.SideSell, "party2", 2, 30000) 103 conf, err := tm.market.SubmitOrder(ctx, sellOrder.IntoSubmission(), sellOrder.Party, crypto.RandomHash()) 104 require.NoError(t, err) 105 require.Equal(t, 1, len(conf.Trades)) 106 107 // confirm the quote asset balance of the seller after the trade 108 gaBalance2, err := tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 109 require.NoError(t, err) 110 require.Equal(t, "59850", gaBalance2.Balance.String()) 111 112 // now place a buy order to trade against the remaining size of party2, but first let's confirm the quote balance of party1 113 gaBalance1, err := tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 114 require.NoError(t, err) 115 require.Equal(t, "40120", gaBalance1.Balance.String()) // the 40k they had from before + the maker fee received 116 117 // this should be enough to cover the trade + fees 118 buyOrder := getGTCLimitOrder(tm, tm.now, crypto.RandomHash(), types.SideBuy, "party1", 1, 30000) 119 conf, err = tm.market.SubmitOrder(ctx, buyOrder.IntoSubmission(), buyOrder.Party, crypto.RandomHash()) 120 require.NoError(t, err) 121 require.Equal(t, 1, len(conf.Trades)) 122 123 // expect the buyer to have paid the 30k + fees 124 gaBalance1, err = tm.collateralEngine.GetPartyGeneralAccount("party1", tm.quoteAsset) 125 require.NoError(t, err) 126 require.Equal(t, "9970", gaBalance1.Balance.String()) 127 128 // confirm the quote asset balance of the seller increased by 30k after the trade + 120 from maker fees 129 gaBalance2, err = tm.collateralEngine.GetPartyGeneralAccount("party2", tm.quoteAsset) 130 require.NoError(t, err) 131 require.Equal(t, "89970", gaBalance2.Balance.String()) 132 }