code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/fees_stats_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 sqlstore_test
    17  
    18  import (
    19  	"context"
    20  	"testing"
    21  	"time"
    22  
    23  	"code.vegaprotocol.io/vega/datanode/entities"
    24  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    25  	"code.vegaprotocol.io/vega/datanode/sqlstore/helpers"
    26  	"code.vegaprotocol.io/vega/libs/ptr"
    27  	eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1"
    28  
    29  	"github.com/georgysavva/scany/pgxscan"
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestFeesStats_AddFeesStats(t *testing.T) {
    35  	t.Run("Should add the stats for the epoch if they do not exist", testAddFeesStatsEpochNotExists)
    36  	t.Run("Should return an error if the epoch already exists for the market/asset", testAddFeesStatsEpochExists)
    37  }
    38  
    39  type FeesStatsTestStores struct {
    40  	bs *sqlstore.Blocks
    41  	ms *sqlstore.Markets
    42  	ps *sqlstore.Parties
    43  	as *sqlstore.Assets
    44  	fs *sqlstore.FeesStats
    45  }
    46  
    47  func setupFeesStatsStores(t *testing.T) *FeesStatsTestStores {
    48  	t.Helper()
    49  	bs := sqlstore.NewBlocks(connectionSource)
    50  	ms := sqlstore.NewMarkets(connectionSource)
    51  	ps := sqlstore.NewParties(connectionSource)
    52  	as := sqlstore.NewAssets(connectionSource)
    53  	fs := sqlstore.NewFeesStats(connectionSource)
    54  
    55  	return &FeesStatsTestStores{
    56  		bs: bs,
    57  		ms: ms,
    58  		ps: ps,
    59  		as: as,
    60  		fs: fs,
    61  	}
    62  }
    63  
    64  func testAddFeesStatsEpochNotExists(t *testing.T) {
    65  	stores := setupFeesStatsStores(t)
    66  	ctx := tempTransaction(t)
    67  	block := addTestBlock(t, ctx, stores.bs)
    68  	market := helpers.AddTestMarket(t, ctx, stores.ms, block)
    69  	asset := addTestAsset(t, ctx, stores.as, block)
    70  
    71  	want := entities.FeesStats{
    72  		MarketID:                 market.ID,
    73  		AssetID:                  asset.ID,
    74  		EpochSeq:                 100,
    75  		TotalRewardsReceived:     nil,
    76  		ReferrerRewardsGenerated: nil,
    77  		RefereesDiscountApplied:  nil,
    78  		VolumeDiscountApplied:    nil,
    79  		VegaTime:                 block.VegaTime,
    80  	}
    81  
    82  	err := stores.fs.AddFeesStats(ctx, &want)
    83  	require.NoError(t, err)
    84  
    85  	// Check that the stats were added
    86  	var got entities.FeesStats
    87  	err = pgxscan.Get(ctx, connectionSource, &got,
    88  		`SELECT * FROM fees_stats WHERE market_id = $1 AND asset_id = $2 AND epoch_seq = $3`,
    89  		market.ID, asset.ID, want.EpochSeq,
    90  	)
    91  	require.NoError(t, err)
    92  	assert.Equal(t, want, got)
    93  }
    94  
    95  func testAddFeesStatsEpochExists(t *testing.T) {
    96  	stores := setupFeesStatsStores(t)
    97  	ctx := tempTransaction(t)
    98  	block := addTestBlock(t, ctx, stores.bs)
    99  	market := helpers.AddTestMarket(t, ctx, stores.ms, block)
   100  	asset := addTestAsset(t, ctx, stores.as, block)
   101  
   102  	want := entities.FeesStats{
   103  		MarketID:                 market.ID,
   104  		AssetID:                  asset.ID,
   105  		EpochSeq:                 100,
   106  		TotalRewardsReceived:     nil,
   107  		ReferrerRewardsGenerated: nil,
   108  		RefereesDiscountApplied:  nil,
   109  		VolumeDiscountApplied:    nil,
   110  		VegaTime:                 block.VegaTime,
   111  	}
   112  
   113  	err := stores.fs.AddFeesStats(ctx, &want)
   114  	require.NoError(t, err)
   115  
   116  	// now try to insert again and make sure we get an error
   117  	err = stores.fs.AddFeesStats(ctx, &want)
   118  	require.Error(t, err)
   119  	assert.Contains(t, err.Error(), "duplicate key value violates unique constraint")
   120  }
   121  
   122  func TestFeesStats_GetFeesStats(t *testing.T) {
   123  	t.Run("Should return the stats for the market and epoch requested", testGetFeesStatsForMarketAndEpoch)
   124  	t.Run("Should return the stats for the asset and epoch requested", testGetFeesStatsForAssetAndEpoch)
   125  	t.Run("Should return the latest stats for the market requested", testGetFeesStatsForMarketLatest)
   126  	t.Run("Should return the latest stats for the asset requested", testGetFeesStatsForAssetLatest)
   127  	t.Run("Should return an error if an asset and market is provided", testGetFeesStatsNoAssetOrMarket)
   128  	t.Run("Should return the stats for the party and epoch requested", testGetFeesStatsForPartyAndEpoch)
   129  	t.Run("Should return the latest stats for the party", testGetFeesStatsForPartyLatest)
   130  	t.Run("Should return the stats for all asset given a party", testGetFeesStatsForParty)
   131  }
   132  
   133  func testGetFeesStatsForMarketAndEpoch(t *testing.T) {
   134  	stores := setupFeesStatsStores(t)
   135  	ctx := tempTransaction(t)
   136  	stats := setupFeesStats(t, ctx, stores.fs)
   137  
   138  	// get the stats for the first market and epoch
   139  	want := stats[0]
   140  	got, err := stores.fs.GetFeesStats(ctx, &want.MarketID, nil, &want.EpochSeq, nil, nil, nil)
   141  	require.NoError(t, err)
   142  	assert.Equal(t, want, *got)
   143  
   144  	// get the stats for the second market and epoch
   145  	want = stats[3]
   146  	got, err = stores.fs.GetFeesStats(ctx, &want.MarketID, nil, &want.EpochSeq, nil, nil, nil)
   147  	require.NoError(t, err)
   148  	assert.Equal(t, want, *got)
   149  }
   150  
   151  func testGetFeesStatsForAssetAndEpoch(t *testing.T) {
   152  	stores := setupFeesStatsStores(t)
   153  	ctx := tempTransaction(t)
   154  	stats := setupFeesStats(t, ctx, stores.fs)
   155  
   156  	// get the stats for the first market and epoch
   157  	want := stats[0]
   158  	got, err := stores.fs.GetFeesStats(ctx, nil, &want.AssetID, &want.EpochSeq, nil, nil, nil)
   159  	require.NoError(t, err)
   160  	assert.Equal(t, want, *got)
   161  
   162  	// get the stats for the second market and epoch
   163  	want = stats[6]
   164  	got, err = stores.fs.GetFeesStats(ctx, nil, &want.AssetID, &want.EpochSeq, nil, nil, nil)
   165  	require.NoError(t, err)
   166  	assert.Equal(t, want, *got)
   167  }
   168  
   169  func testGetFeesStatsForMarketLatest(t *testing.T) {
   170  	stores := setupFeesStatsStores(t)
   171  	ctx := tempTransaction(t)
   172  	stats := setupFeesStats(t, ctx, stores.fs)
   173  
   174  	// get the stats for the first market and epoch
   175  	want := stats[2]
   176  	got, err := stores.fs.GetFeesStats(ctx, &want.MarketID, nil, nil, nil, nil, nil)
   177  	require.NoError(t, err)
   178  	assert.Equal(t, want, *got)
   179  
   180  	// get the stats for the second market and epoch
   181  	want = stats[8]
   182  	got, err = stores.fs.GetFeesStats(ctx, &want.MarketID, nil, nil, nil, nil, nil)
   183  	require.NoError(t, err)
   184  	assert.Equal(t, want, *got)
   185  }
   186  
   187  func testGetFeesStatsForAssetLatest(t *testing.T) {
   188  	stores := setupFeesStatsStores(t)
   189  	ctx := tempTransaction(t)
   190  	stats := setupFeesStats(t, ctx, stores.fs)
   191  
   192  	// get the stats for the first market and epoch
   193  	want := stats[2]
   194  	got, err := stores.fs.GetFeesStats(ctx, nil, &want.AssetID, nil, nil, nil, nil)
   195  	require.NoError(t, err)
   196  	assert.Equal(t, want, *got)
   197  
   198  	// get the stats for the second market and epoch
   199  	want = stats[8]
   200  	got, err = stores.fs.GetFeesStats(ctx, nil, &want.AssetID, nil, nil, nil, nil)
   201  	require.NoError(t, err)
   202  	assert.Equal(t, want, *got)
   203  }
   204  
   205  func testGetFeesStatsNoAssetOrMarket(t *testing.T) {
   206  	stores := setupFeesStatsStores(t)
   207  	ctx := tempTransaction(t)
   208  
   209  	_, err := stores.fs.GetFeesStats(ctx, ptr.From(entities.MarketID("deadbeef01")), ptr.From(entities.AssetID("deadbeef02")), nil, nil, nil, nil)
   210  	require.Error(t, err)
   211  }
   212  
   213  func testGetFeesStatsForPartyAndEpoch(t *testing.T) {
   214  	stores := setupFeesStatsStores(t)
   215  	ctx := tempTransaction(t)
   216  	stats := setupFeesStats(t, ctx, stores.fs)
   217  
   218  	// get the stats for the first market and epoch
   219  	expected := stats[1]
   220  	want := entities.FeesStats{
   221  		MarketID: entities.MarketID("deadbeef01"),
   222  		AssetID:  entities.AssetID("deadbaad01"),
   223  		EpochSeq: 2,
   224  		TotalRewardsReceived: []*eventspb.PartyAmount{
   225  			{
   226  				Party:  "cafedaad01",
   227  				Amount: "1100000",
   228  			},
   229  		},
   230  		ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   231  			{
   232  				Referrer: "cafedaad01",
   233  				GeneratedReward: []*eventspb.PartyAmount{
   234  					{
   235  						Party:  "cafed00d01",
   236  						Amount: "550000",
   237  					},
   238  					{
   239  						Party:  "cafed00d02",
   240  						Amount: "550000",
   241  					},
   242  				},
   243  			},
   244  		},
   245  		RefereesDiscountApplied: []*eventspb.PartyAmount{},
   246  		VolumeDiscountApplied:   []*eventspb.PartyAmount{},
   247  		TotalMakerFeesReceived:  []*eventspb.PartyAmount{},
   248  		MakerFeesGenerated:      []*eventspb.MakerFeesGenerated{},
   249  		VegaTime:                expected.VegaTime,
   250  	}
   251  
   252  	got, err := stores.fs.GetFeesStats(ctx, nil, &want.AssetID, ptr.From(want.EpochSeq), &want.ReferrerRewardsGenerated[0].Referrer, nil, nil)
   253  	require.NoError(t, err)
   254  	assert.Equal(t, want, *got)
   255  }
   256  
   257  func testGetFeesStatsForPartyLatest(t *testing.T) {
   258  	stores := setupFeesStatsStores(t)
   259  	ctx := tempTransaction(t)
   260  	stats := setupFeesStats(t, ctx, stores.fs)
   261  
   262  	// get the stats for the first market and epoch
   263  	expected := stats[2]
   264  	want := entities.FeesStats{
   265  		MarketID: entities.MarketID("deadbeef01"),
   266  		AssetID:  entities.AssetID("deadbaad01"),
   267  		EpochSeq: 3,
   268  		TotalRewardsReceived: []*eventspb.PartyAmount{
   269  			{
   270  				Party:  "cafedaad01",
   271  				Amount: "1200000",
   272  			},
   273  		},
   274  		ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   275  			{
   276  				Referrer: "cafedaad01",
   277  				GeneratedReward: []*eventspb.PartyAmount{
   278  					{
   279  						Party:  "cafed00d01",
   280  						Amount: "600000",
   281  					},
   282  					{
   283  						Party:  "cafed00d02",
   284  						Amount: "600000",
   285  					},
   286  				},
   287  			},
   288  		},
   289  		RefereesDiscountApplied: []*eventspb.PartyAmount{},
   290  		VolumeDiscountApplied:   []*eventspb.PartyAmount{},
   291  		TotalMakerFeesReceived:  []*eventspb.PartyAmount{},
   292  		MakerFeesGenerated:      []*eventspb.MakerFeesGenerated{},
   293  		VegaTime:                expected.VegaTime,
   294  	}
   295  	got, err := stores.fs.GetFeesStats(ctx, nil, &want.AssetID, nil, &want.ReferrerRewardsGenerated[0].Referrer, nil, nil)
   296  	require.NoError(t, err)
   297  	assert.Equal(t, want, *got)
   298  }
   299  
   300  func testGetFeesStatsForParty(t *testing.T) {
   301  	stores := setupFeesStatsStores(t)
   302  	ctx := tempTransaction(t)
   303  	_ = setupFeesStats(t, ctx, stores.fs)
   304  
   305  	got, err := stores.fs.StatsForParty(ctx, "cafedaad01", ptr.From(entities.AssetID("deadbaad01")), ptr.From(uint64(1)), ptr.From(uint64(2)))
   306  	require.NoError(t, err)
   307  	assert.Equal(t, []entities.FeesStatsForParty{
   308  		{
   309  			AssetID:                 entities.AssetID("deadbaad01"),
   310  			TotalRewardsReceived:    "4200000",
   311  			RefereesDiscountApplied: "0",
   312  			VolumeDiscountApplied:   "0",
   313  			TotalMakerFeesReceived:  "0",
   314  		},
   315  	}, got)
   316  
   317  	got, err = stores.fs.StatsForParty(ctx, "cafedaad01", ptr.From(entities.AssetID("deadbaad01")), ptr.From(uint64(2)), nil)
   318  	require.NoError(t, err)
   319  	assert.Equal(t, []entities.FeesStatsForParty{
   320  		{
   321  			AssetID:                 entities.AssetID("deadbaad01"),
   322  			TotalRewardsReceived:    "4600000",
   323  			RefereesDiscountApplied: "0",
   324  			VolumeDiscountApplied:   "0",
   325  			TotalMakerFeesReceived:  "0",
   326  		},
   327  	}, got)
   328  
   329  	got, err = stores.fs.StatsForParty(ctx, "cafedaad01", ptr.From(entities.AssetID("deadbaad01")), nil, ptr.From(uint64(2)))
   330  	require.NoError(t, err)
   331  	assert.Equal(t, []entities.FeesStatsForParty{
   332  		{
   333  			AssetID:                 entities.AssetID("deadbaad01"),
   334  			TotalRewardsReceived:    "4200000",
   335  			RefereesDiscountApplied: "0",
   336  			VolumeDiscountApplied:   "0",
   337  			TotalMakerFeesReceived:  "0",
   338  		},
   339  	}, got)
   340  
   341  	got, err = stores.fs.StatsForParty(ctx, "cafedaad01", ptr.From(entities.AssetID("deadbaad01")), nil, nil)
   342  	require.NoError(t, err)
   343  	assert.Equal(t, []entities.FeesStatsForParty{
   344  		{
   345  			AssetID:                 entities.AssetID("deadbaad01"),
   346  			TotalRewardsReceived:    "2400000",
   347  			RefereesDiscountApplied: "0",
   348  			VolumeDiscountApplied:   "0",
   349  			TotalMakerFeesReceived:  "0",
   350  		},
   351  	}, got)
   352  }
   353  
   354  func setupFeesStats(t *testing.T, ctx context.Context, fs *sqlstore.FeesStats) []entities.FeesStats {
   355  	t.Helper()
   356  	vegaTime := time.Now().Add(-time.Minute).Round(time.Microsecond) // round to microsecond because Postgres doesn't store nanoseconds at the current time
   357  	stats := []entities.FeesStats{
   358  		{
   359  			MarketID: entities.MarketID("deadbeef01"),
   360  			AssetID:  entities.AssetID("deadbaad01"),
   361  			EpochSeq: 1,
   362  			TotalRewardsReceived: []*eventspb.PartyAmount{
   363  				{
   364  					Party:  "cafedaad01",
   365  					Amount: "1000000",
   366  				},
   367  			},
   368  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   369  				{
   370  					Referrer: "cafedaad01",
   371  					GeneratedReward: []*eventspb.PartyAmount{
   372  						{
   373  							Party:  "cafed00d01",
   374  							Amount: "500000",
   375  						},
   376  						{
   377  							Party:  "cafed00d02",
   378  							Amount: "500000",
   379  						},
   380  					},
   381  				},
   382  			},
   383  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   384  				{
   385  					Party:  "cafed00d01",
   386  					Amount: "100000",
   387  				},
   388  				{
   389  					Party:  "cafed00d02",
   390  					Amount: "100000",
   391  				},
   392  			},
   393  			VegaTime: vegaTime.Add(5 * time.Second),
   394  		},
   395  		{
   396  			MarketID: entities.MarketID("deadbeef01"),
   397  			AssetID:  entities.AssetID("deadbaad01"),
   398  			EpochSeq: 2,
   399  			TotalRewardsReceived: []*eventspb.PartyAmount{
   400  				{
   401  					Party:  "cafedaad01",
   402  					Amount: "1100000",
   403  				},
   404  			},
   405  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   406  				{
   407  					Referrer: "cafedaad01",
   408  					GeneratedReward: []*eventspb.PartyAmount{
   409  						{
   410  							Party:  "cafed00d01",
   411  							Amount: "550000",
   412  						},
   413  						{
   414  							Party:  "cafed00d02",
   415  							Amount: "550000",
   416  						},
   417  					},
   418  				},
   419  			},
   420  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   421  				{
   422  					Party:  "cafed00d01",
   423  					Amount: "110000",
   424  				},
   425  				{
   426  					Party:  "cafed00d02",
   427  					Amount: "110000",
   428  				},
   429  			},
   430  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   431  			VegaTime:              vegaTime.Add(10 * time.Second),
   432  		},
   433  		{
   434  			MarketID: entities.MarketID("deadbeef01"),
   435  			AssetID:  entities.AssetID("deadbaad01"),
   436  			EpochSeq: 3,
   437  			TotalRewardsReceived: []*eventspb.PartyAmount{
   438  				{
   439  					Party:  "cafedaad01",
   440  					Amount: "1200000",
   441  				},
   442  			},
   443  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   444  				{
   445  					Referrer: "cafedaad01",
   446  					GeneratedReward: []*eventspb.PartyAmount{
   447  						{
   448  							Party:  "cafed00d01",
   449  							Amount: "600000",
   450  						},
   451  						{
   452  							Party:  "cafed00d02",
   453  							Amount: "600000",
   454  						},
   455  					},
   456  				},
   457  			},
   458  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   459  				{
   460  					Party:  "cafed00d01",
   461  					Amount: "120000",
   462  				},
   463  				{
   464  					Party:  "cafed00d02",
   465  					Amount: "120000",
   466  				},
   467  			},
   468  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   469  			VegaTime:              vegaTime.Add(15 * time.Second),
   470  		},
   471  		{
   472  			MarketID: entities.MarketID("deadbeef11"),
   473  			AssetID:  entities.AssetID("deadbaad01"),
   474  			EpochSeq: 1,
   475  			TotalRewardsReceived: []*eventspb.PartyAmount{
   476  				{
   477  					Party:  "cafedaad01",
   478  					Amount: "1000000",
   479  				},
   480  			},
   481  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   482  				{
   483  					Referrer: "cafedaad01",
   484  					GeneratedReward: []*eventspb.PartyAmount{
   485  						{
   486  							Party:  "cafed00d01",
   487  							Amount: "500000",
   488  						},
   489  						{
   490  							Party:  "cafed00d02",
   491  							Amount: "500000",
   492  						},
   493  					},
   494  				},
   495  			},
   496  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   497  				{
   498  					Party:  "cafed00d01",
   499  					Amount: "100000",
   500  				},
   501  				{
   502  					Party:  "cafed00d02",
   503  					Amount: "100000",
   504  				},
   505  			},
   506  			VegaTime: vegaTime.Add(5 * time.Second),
   507  		},
   508  		{
   509  			MarketID: entities.MarketID("deadbeef11"),
   510  			AssetID:  entities.AssetID("deadbaad01"),
   511  			EpochSeq: 2,
   512  			TotalRewardsReceived: []*eventspb.PartyAmount{
   513  				{
   514  					Party:  "cafedaad01",
   515  					Amount: "1100000",
   516  				},
   517  			},
   518  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   519  				{
   520  					Referrer: "cafedaad01",
   521  					GeneratedReward: []*eventspb.PartyAmount{
   522  						{
   523  							Party:  "cafed00d01",
   524  							Amount: "550000",
   525  						},
   526  						{
   527  							Party:  "cafed00d02",
   528  							Amount: "550000",
   529  						},
   530  					},
   531  				},
   532  			},
   533  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   534  				{
   535  					Party:  "cafed00d01",
   536  					Amount: "110000",
   537  				},
   538  				{
   539  					Party:  "cafed00d02",
   540  					Amount: "110000",
   541  				},
   542  			},
   543  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   544  			VegaTime:              vegaTime.Add(10 * time.Second),
   545  		},
   546  		{
   547  			MarketID: entities.MarketID("deadbeef11"),
   548  			AssetID:  entities.AssetID("deadbaad01"),
   549  			EpochSeq: 3,
   550  			TotalRewardsReceived: []*eventspb.PartyAmount{
   551  				{
   552  					Party:  "cafedaad01",
   553  					Amount: "1200000",
   554  				},
   555  			},
   556  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   557  				{
   558  					Referrer: "cafedaad01",
   559  					GeneratedReward: []*eventspb.PartyAmount{
   560  						{
   561  							Party:  "cafed00d01",
   562  							Amount: "600000",
   563  						},
   564  						{
   565  							Party:  "cafed00d02",
   566  							Amount: "600000",
   567  						},
   568  					},
   569  				},
   570  			},
   571  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   572  				{
   573  					Party:  "cafed00d01",
   574  					Amount: "120000",
   575  				},
   576  				{
   577  					Party:  "cafed00d02",
   578  					Amount: "120000",
   579  				},
   580  			},
   581  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   582  			VegaTime:              vegaTime.Add(15 * time.Second),
   583  		},
   584  		{
   585  			MarketID: entities.MarketID("deadbeef02"),
   586  			AssetID:  entities.AssetID("deadbaad02"),
   587  			EpochSeq: 1,
   588  			TotalRewardsReceived: []*eventspb.PartyAmount{
   589  				{
   590  					Party:  "cafedaad02",
   591  					Amount: "2000000",
   592  				},
   593  			},
   594  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   595  				{
   596  					Referrer: "cafedaad02",
   597  					GeneratedReward: []*eventspb.PartyAmount{
   598  						{
   599  							Party:  "cafed00d03",
   600  							Amount: "2000000",
   601  						},
   602  						{
   603  							Party:  "cafed00d04",
   604  							Amount: "2000000",
   605  						},
   606  					},
   607  				},
   608  			},
   609  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   610  				{
   611  					Party:  "cafed00d03",
   612  					Amount: "200000",
   613  				},
   614  				{
   615  					Party:  "cafed00d04",
   616  					Amount: "200000",
   617  				},
   618  			},
   619  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   620  			VegaTime:              vegaTime.Add(5 * time.Second),
   621  		},
   622  		{
   623  			MarketID: entities.MarketID("deadbeef02"),
   624  			AssetID:  entities.AssetID("deadbaad02"),
   625  			EpochSeq: 2,
   626  			TotalRewardsReceived: []*eventspb.PartyAmount{
   627  				{
   628  					Party:  "cafedaad02",
   629  					Amount: "2100000",
   630  				},
   631  			},
   632  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   633  				{
   634  					Referrer: "cafedaad01",
   635  					GeneratedReward: []*eventspb.PartyAmount{
   636  						{
   637  							Party:  "cafed00d03",
   638  							Amount: "1050000",
   639  						},
   640  						{
   641  							Party:  "cafed00d04",
   642  							Amount: "1050000",
   643  						},
   644  					},
   645  				},
   646  			},
   647  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   648  				{
   649  					Party:  "cafed00d03",
   650  					Amount: "210000",
   651  				},
   652  				{
   653  					Party:  "cafed00d04",
   654  					Amount: "210000",
   655  				},
   656  			},
   657  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   658  			VegaTime:              vegaTime.Add(10 * time.Second),
   659  		},
   660  		{
   661  			MarketID: entities.MarketID("deadbeef02"),
   662  			AssetID:  entities.AssetID("deadbaad02"),
   663  			EpochSeq: 3,
   664  			TotalRewardsReceived: []*eventspb.PartyAmount{
   665  				{
   666  					Party:  "cafedaad02",
   667  					Amount: "2200000",
   668  				},
   669  			},
   670  			ReferrerRewardsGenerated: []*eventspb.ReferrerRewardsGenerated{
   671  				{
   672  					Referrer: "cafedaad01",
   673  					GeneratedReward: []*eventspb.PartyAmount{
   674  						{
   675  							Party:  "cafed00d03",
   676  							Amount: "1100000",
   677  						},
   678  						{
   679  							Party:  "cafed00d04",
   680  							Amount: "1100000",
   681  						},
   682  					},
   683  				},
   684  			},
   685  			RefereesDiscountApplied: []*eventspb.PartyAmount{
   686  				{
   687  					Party:  "cafed00d03",
   688  					Amount: "220000",
   689  				},
   690  				{
   691  					Party:  "cafed00d04",
   692  					Amount: "220000",
   693  				},
   694  			},
   695  			VolumeDiscountApplied: []*eventspb.PartyAmount{},
   696  			VegaTime:              vegaTime.Add(15 * time.Second),
   697  		},
   698  	}
   699  
   700  	for _, stat := range stats {
   701  		err := fs.AddFeesStats(ctx, &stat)
   702  		require.NoError(t, err)
   703  	}
   704  
   705  	return stats
   706  }