From 91d66ba0e2e1ca4205477d8b6b3cb60771037d4a Mon Sep 17 00:00:00 2001 From: ze97286 Date: Wed, 11 Oct 2023 17:56:04 +0100 Subject: [PATCH] fix: LP fees reward handling + destination type --- CHANGELOG.md | 2 + .../common/liquidity_provision_fees.go | 4 +- .../common/liquidity_provision_test.go | 3 +- .../common/market_activity_tracker.go | 7 +- .../market_activity_tracker_internal_test.go | 18 ++- .../market_activity_tracker_snapshot.go | 2 +- .../common/market_activity_tracker_test.go | 104 ++++++++------- core/execution/engine_snapshot_test.go | 10 +- core/execution/future/market_snapshot_test.go | 3 +- core/execution/future/market_test.go | 6 +- core/execution/snapshot_test.go | 6 +- core/execution/spot/market_test.go | 3 +- core/governance/market_cp_restore_test.go | 3 +- .../features/rewards/lp_reward.feature | 122 ++++++++++++++++++ core/integration/setup_test.go | 3 +- core/protocol/all_services.go | 4 +- .../gateway/graphql/new_transfer_resolver.go | 2 +- 17 files changed, 229 insertions(+), 73 deletions(-) create mode 100644 core/integration/features/rewards/lp_reward.feature diff --git a/CHANGELOG.md b/CHANGELOG.md index 8779100cf7a..e92eff140fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -294,6 +294,8 @@ - [9734](https://github.com/vegaprotocol/vega/issues/9734) - Fix creation of new account types for existing assets during migration - [9731](https://github.com/vegaprotocol/vega/issues/9731) - Allow team rewards to apply to all teams. - [9727](https://github.com/vegaprotocol/vega/issues/9727) - Initialize teams earlier to avoid panic. +- [9746](https://github.com/vegaprotocol/vega/issues/9746) - Fix handling of LP fees reward +- [9747](https://github.com/vegaprotocol/vega/issues/9747) - Return correct destination type ## 0.72.1 diff --git a/core/execution/common/liquidity_provision_fees.go b/core/execution/common/liquidity_provision_fees.go index e1f66e716fa..cdfc4495599 100644 --- a/core/execution/common/liquidity_provision_fees.go +++ b/core/execution/common/liquidity_provision_fees.go @@ -89,7 +89,6 @@ func (m *MarketLiquidity) AllocateFees(ctx context.Context) error { return nil } - m.marketActivityTracker.UpdateFeesFromTransfers(m.asset, m.marketID, feeTransfer.Transfers()) ledgerMovements, err := m.transferFees(ctx, feeTransfer) if err != nil { return fmt.Errorf("failed to transfer fees: %w", err) @@ -212,6 +211,8 @@ func (m *MarketLiquidity) distributeFeesAndCalculateBonuses( bonusPerParty[partyID] = bonus } + m.marketActivityTracker.UpdateFeesFromTransfers(m.asset, m.marketID, allTransfers.transfers) + // transfer all the fees. ledgerMovements, err := m.transferFees(ctx, allTransfers) if err != nil { @@ -279,6 +280,7 @@ func (m *MarketLiquidity) distributePerformanceBonuses( bonusTransfers.transfers = append(bonusTransfers.transfers, transfer) } + m.marketActivityTracker.UpdateFeesFromTransfers(m.asset, m.marketID, bonusTransfers.transfers) ledgerMovements, err := m.transferFees(ctx, bonusTransfers) if err != nil { m.log.Panic("failed to distribute SLA bonuses", logging.Error(err)) diff --git a/core/execution/common/liquidity_provision_test.go b/core/execution/common/liquidity_provision_test.go index 2c0b17df3bb..0dc7fb6f351 100644 --- a/core/execution/common/liquidity_provision_test.go +++ b/core/execution/common/liquidity_provision_test.go @@ -80,7 +80,8 @@ func newMarketLiquidity(t *testing.T) *marketLiquidityTest { teams := mocks.NewMockTeams(ctrl) bc := mocks.NewMockAccountBalanceChecker(ctrl) - marketTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, bc) + marketTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epochEngine.NotifyOnEpoch(marketTracker.OnEpochEvent, marketTracker.OnEpochRestore) marketLiquidity := common.NewMarketLiquidity( log, diff --git a/core/execution/common/market_activity_tracker.go b/core/execution/common/market_activity_tracker.go index c76db550444..dbc17be1985 100644 --- a/core/execution/common/market_activity_tracker.go +++ b/core/execution/common/market_activity_tracker.go @@ -107,7 +107,7 @@ type MarketActivityTracker struct { } // NewMarketActivityTracker instantiates the fees tracker. -func NewMarketActivityTracker(log *logging.Logger, epochEngine EpochEngine, teams Teams, balanceChecker AccountBalanceChecker) *MarketActivityTracker { +func NewMarketActivityTracker(log *logging.Logger, teams Teams, balanceChecker AccountBalanceChecker) *MarketActivityTracker { mat := &MarketActivityTracker{ assetToMarketTrackers: map[string]map[string]*marketTracker{}, ss: &snapshotState{}, @@ -118,7 +118,6 @@ func NewMarketActivityTracker(log *logging.Logger, epochEngine EpochEngine, team partyTakerNotionalVolume: map[string]*num.Uint{}, } - epochEngine.NotifyOnEpoch(mat.onEpochEvent, mat.onEpochRestore) return mat } @@ -365,7 +364,7 @@ func (mat *MarketActivityTracker) RemoveMarket(asset, marketID string) { } // onEpochEvent is called when the state of the epoch changes, we only care about new epochs starting. -func (mat *MarketActivityTracker) onEpochEvent(_ context.Context, epoch types.Epoch) { +func (mat *MarketActivityTracker) OnEpochEvent(_ context.Context, epoch types.Epoch) { if epoch.Action == proto.EpochAction_EPOCH_ACTION_START { mat.epochStartTime = epoch.StartTime mat.partyContributionCache = map[string][]*types.PartyContributionScore{} @@ -434,7 +433,7 @@ func (mat *MarketActivityTracker) UpdateFeesFromTransfers(asset, market string, mat.addFees(mt.makerFeesPaid, t.Owner, t.Amount.Amount, mt.totalMakerFeesPaid) case types.TransferTypeMakerFeeReceive: mat.addFees(mt.makerFeesReceived, t.Owner, t.Amount.Amount, mt.totalMakerFeesReceived) - case types.TransferTypeLiquidityFeeDistribute: + case types.TransferTypeLiquidityFeeNetDistribute, types.TransferTypeSlaPerformanceBonusDistribute: mat.addFees(mt.lpFees, t.Owner, t.Amount.Amount, mt.totalLpFees) default: } diff --git a/core/execution/common/market_activity_tracker_internal_test.go b/core/execution/common/market_activity_tracker_internal_test.go index 41babe8698d..01d2bc0b88b 100644 --- a/core/execution/common/market_activity_tracker_internal_test.go +++ b/core/execution/common/market_activity_tracker_internal_test.go @@ -259,7 +259,8 @@ func TestCalculateMetricForIndividualsAvePosition(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) @@ -434,7 +435,8 @@ func TestCalculateMetricForPartyAvePosition(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) @@ -617,7 +619,8 @@ func TestCalculateMetricForIndividualReturnVolatility(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) @@ -753,7 +756,8 @@ func TestCalculateMetricForIndividualsRelativeReturn(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) @@ -912,7 +916,8 @@ func TestCalculateMetricForPartyRelativeReturn(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) @@ -1123,7 +1128,8 @@ func TestCalculateMetricForParty(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&DummyEligibilityChecker{}) epochService.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: time.Time{}}) diff --git a/core/execution/common/market_activity_tracker_snapshot.go b/core/execution/common/market_activity_tracker_snapshot.go index 8ea24785f2c..78a2452ed14 100644 --- a/core/execution/common/market_activity_tracker_snapshot.go +++ b/core/execution/common/market_activity_tracker_snapshot.go @@ -498,7 +498,7 @@ func (mat *MarketActivityTracker) restore(tracker *snapshot.MarketTracker) { } // onEpochRestore is called when the state of the epoch changes, we only care about new epochs starting. -func (mat *MarketActivityTracker) onEpochRestore(_ context.Context, epoch types.Epoch) { +func (mat *MarketActivityTracker) OnEpochRestore(_ context.Context, epoch types.Epoch) { mat.currentEpoch = epoch.Seq mat.epochStartTime = epoch.StartTime } diff --git a/core/execution/common/market_activity_tracker_test.go b/core/execution/common/market_activity_tracker_test.go index cf07ac993db..043e0af149e 100644 --- a/core/execution/common/market_activity_tracker_test.go +++ b/core/execution/common/market_activity_tracker_test.go @@ -60,7 +60,7 @@ func TestMarketTracker(t *testing.T) { teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) tracker.SetEligibilityChecker(&EligibilityChecker{}) tracker.MarketProposed("asset1", "market1", "me") @@ -134,7 +134,7 @@ func TestMarketTracker(t *testing.T) { require.NoError(t, err) teams2 := mocks.NewMockTeams(ctrl) balanceChecker2 := mocks.NewMockAccountBalanceChecker(ctrl) - trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams2, balanceChecker2) + trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), teams2, balanceChecker2) pl := snapshotpb.Payload{} require.NoError(t, proto.Unmarshal(state1, &pl)) @@ -151,7 +151,8 @@ func TestRemoveMarket(t *testing.T) { teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&EligibilityChecker{}) tracker.MarketProposed("asset1", "market1", "me") tracker.MarketProposed("asset1", "market2", "me2") @@ -175,7 +176,8 @@ func TestGetScores(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&EligibilityChecker{}) tracker.MarketProposed("asset1", "market1", "me") tracker.MarketProposed("asset1", "market2", "me2") @@ -215,23 +217,23 @@ func TestGetScores(t *testing.T) { transfersM1 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(100)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(400)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(300)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(900)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) transfersM2 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(500)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, } tracker.UpdateFeesFromTransfers("asset1", "market2", transfersM2) @@ -283,10 +285,10 @@ func TestGetScores(t *testing.T) { epochService.target(context.Background(), types.Epoch{Seq: 3, Action: vgproto.EpochAction_EPOCH_ACTION_START}) transfersM1 = []*types.Transfer{ - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1200)}}, } transfersM2 = []*types.Transfer{ - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) tracker.UpdateFeesFromTransfers("asset1", "market2", transfersM2) @@ -312,7 +314,8 @@ func TestGetScoresIndividualsDifferentScopes(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&EligibilityChecker{}) tracker.MarketProposed("asset1", "market1", "me") tracker.MarketProposed("asset1", "market2", "me2") @@ -352,23 +355,23 @@ func TestGetScoresIndividualsDifferentScopes(t *testing.T) { transfersM1 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(100)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(400)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(300)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(900)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) transfersM2 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(500)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, } tracker.UpdateFeesFromTransfers("asset1", "market2", transfersM2) @@ -420,10 +423,10 @@ func TestGetScoresIndividualsDifferentScopes(t *testing.T) { epochService.target(context.Background(), types.Epoch{Seq: 3, Action: vgproto.EpochAction_EPOCH_ACTION_START}) transfersM1 = []*types.Transfer{ - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1200)}}, } transfersM2 = []*types.Transfer{ - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) tracker.UpdateFeesFromTransfers("asset1", "market2", transfersM2) @@ -450,7 +453,7 @@ func TestMarketTrackerStateChange(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) tracker.SetEligibilityChecker(&EligibilityChecker{}) state1, _, err := tracker.GetState(key) @@ -477,23 +480,24 @@ func TestFeesTrackerWith0(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochEngine.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) epochEngine.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START}) tracker.MarketProposed("asset1", "market1", "me") transfersM1 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.UintZero()}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) epochEngine.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_END}) @@ -506,7 +510,8 @@ func TestFeesTracker(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochEngine.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) epochEngine.target(context.Background(), types.Epoch{Seq: 1, Action: vgproto.EpochAction_EPOCH_ACTION_START}) tracker.SetEligibilityChecker(&EligibilityChecker{}) @@ -524,16 +529,16 @@ func TestFeesTracker(t *testing.T) { transfersM1 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(100)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(400)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(300)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(900)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) @@ -566,7 +571,7 @@ func TestFeesTracker(t *testing.T) { require.Equal(t, "0.6666666666666667", scores[1].Score.String()) require.Equal(t, "party2", scores[1].Party) - // asset1 TransferTypeLiquidityFeeDistribute + // asset1 TransferTypeLiquidityFeeNetDistribute // party1 paid 800 // party2 paid 1700 scores = tracker.CalculateMetricForIndividuals(&vgproto.DispatchStrategy{AssetForMetric: "asset1", Metric: vgproto.DispatchMetric_DISPATCH_METRIC_LP_FEES_RECEIVED, IndividualScope: vgproto.IndividualScope_INDIVIDUAL_SCOPE_ALL, WindowLength: 1, Markets: []string{"market1"}}) @@ -597,7 +602,8 @@ func TestFeesTracker(t *testing.T) { ctrl = gomock.NewController(t) teams = mocks.NewMockTeams(ctrl) balanceChecker = mocks.NewMockAccountBalanceChecker(ctrl) - trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngineLoad, teams, balanceChecker) + trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochEngineLoad.NotifyOnEpoch(trackerLoad.OnEpochEvent, trackerLoad.OnEpochRestore) pl := snapshotpb.Payload{} require.NoError(t, proto.Unmarshal(state2, &pl)) @@ -660,7 +666,7 @@ func TestSnapshot(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams, balanceChecker) + trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) pl := snapshotpb.Payload{} require.NoError(t, proto.Unmarshal(state1, &pl)) @@ -679,7 +685,7 @@ func TestCheckpoint(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams, balanceChecker) + trackerLoad := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) trackerLoad.Load(context.Background(), b) bLoad, err := trackerLoad.Checkpoint() @@ -691,12 +697,12 @@ func TestSnapshotRoundTripViaEngine(t *testing.T) { transfersM5 := []*types.Transfer{ {Owner: "party3", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(100)}}, {Owner: "party3", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party3", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, + {Owner: "party3", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, } transfersM6 := []*types.Transfer{ {Owner: "party4", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset2", Amount: num.NewUint(500)}}, {Owner: "party4", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset2", Amount: num.NewUint(1500)}}, - {Owner: "party4", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset2", Amount: num.NewUint(1500)}}, + {Owner: "party4", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset2", Amount: num.NewUint(1500)}}, } ctx := vgtest.VegaContext("chainid", 100) @@ -740,7 +746,7 @@ func TestSnapshotRoundTripViaEngine(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker2 := common.NewMarketActivityTracker(logging.NewTestLogger(), &TestEpochEngine{}, teams, balanceChecker) + tracker2 := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) snapshotEngine2, err := snp.NewEngine(vegaPath, config, log, timeService, statsData.Blockchain) require.NoError(t, err) defer snapshotEngine2.Close() @@ -777,7 +783,8 @@ func TestMarketProposerBonusScenarios(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) tracker.SetEligibilityChecker(&EligibilityChecker{}) // setup 4 market for settlement asset1 2 of them proposed by the same proposer, and 2 markets for settlement asset 2 @@ -904,7 +911,8 @@ func TestPositionMetric(t *testing.T) { ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) epochStartTime := time.Now() epochService.target(context.Background(), types.Epoch{Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: epochStartTime}) @@ -1008,7 +1016,9 @@ func TestRelativeReturnMetric(t *testing.T) { teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) + epochStartTime := time.Now() epochService.target(context.Background(), types.Epoch{Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: epochStartTime}) tracker.SetEligibilityChecker(&EligibilityChecker{}) @@ -1097,7 +1107,9 @@ func setupDefaultTrackerForTest(t *testing.T) *common.MarketActivityTracker { teams := mocks.NewMockTeams(ctrl) balanceChecker := mocks.NewMockAccountBalanceChecker(ctrl) - tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochService, teams, balanceChecker) + tracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, balanceChecker) + epochService.NotifyOnEpoch(tracker.OnEpochEvent, tracker.OnEpochRestore) + epochStartTime := time.Now() epochService.target(context.Background(), types.Epoch{Action: vgproto.EpochAction_EPOCH_ACTION_START, StartTime: epochStartTime}) tracker.SetEligibilityChecker(&EligibilityChecker{}) @@ -1121,23 +1133,23 @@ func setupDefaultTrackerForTest(t *testing.T) *common.MarketActivityTracker { transfersM1 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(100)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(400)}}, {Owner: "party1", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(300)}}, - {Owner: "party1", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, + {Owner: "party1", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(900)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(800)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(700)}}, {Owner: "party2", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(600)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(200)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1000)}}, } tracker.UpdateFeesFromTransfers("asset1", "market1", transfersM1) transfersM2 := []*types.Transfer{ {Owner: "party1", Type: types.TransferTypeMakerFeeReceive, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(500)}}, {Owner: "party2", Type: types.TransferTypeMakerFeePay, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, - {Owner: "party2", Type: types.TransferTypeLiquidityFeeDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, + {Owner: "party2", Type: types.TransferTypeLiquidityFeeNetDistribute, Amount: &types.FinancialAmount{Asset: "asset1", Amount: num.NewUint(1500)}}, } tracker.UpdateFeesFromTransfers("asset2", "market2", transfersM2) diff --git a/core/execution/engine_snapshot_test.go b/core/execution/engine_snapshot_test.go index 8623792b14d..4fb0a62c01d 100644 --- a/core/execution/engine_snapshot_test.go +++ b/core/execution/engine_snapshot_test.go @@ -96,7 +96,9 @@ func getMockedEngine(t *testing.T) *engineFake { volumeDiscount.EXPECT().VolumeDiscountFactorForParty(gomock.Any()).Return(num.DecimalZero()).AnyTimes() referralDiscountReward.EXPECT().GetReferrer(gomock.Any()).Return(types.PartyID(""), errors.New("not a referrer")).AnyTimes() - exec := execution.NewEngine(log, execConfig, timeService, collateralService, oracleService, broker, statevar, common.NewMarketActivityTracker(log, epochEngine, teams, balanceChecker), asset, referralDiscountReward, volumeDiscount) + mat := common.NewMarketActivityTracker(log, teams, balanceChecker) + exec := execution.NewEngine(log, execConfig, timeService, collateralService, oracleService, broker, statevar, mat, asset, referralDiscountReward, volumeDiscount) + epochEngine.NotifyOnEpoch(mat.OnEpochEvent, mat.OnEpochRestore) return &engineFake{ Engine: exec, ctrl: ctrl, @@ -155,8 +157,10 @@ func createEngine(t *testing.T) (*execution.Engine, *gomock.Controller) { referralDiscountReward.EXPECT().RewardsFactorMultiplierAppliedForParty(gomock.Any()).Return(num.DecimalZero()).AnyTimes() volumeDiscount.EXPECT().VolumeDiscountFactorForParty(gomock.Any()).Return(num.DecimalZero()).AnyTimes() referralDiscountReward.EXPECT().GetReferrer(gomock.Any()).Return(types.PartyID(""), errors.New("not a referrer")).AnyTimes() - - return execution.NewEngine(log, executionConfig, timeService, collateralService, oracleService, broker, statevar, common.NewMarketActivityTracker(log, epochEngine, teams, balanceChecker), asset, referralDiscountReward, volumeDiscount), ctrl + mat := common.NewMarketActivityTracker(log, teams, balanceChecker) + e := execution.NewEngine(log, executionConfig, timeService, collateralService, oracleService, broker, statevar, mat, asset, referralDiscountReward, volumeDiscount) + epochEngine.NotifyOnEpoch(mat.OnEpochEvent, mat.OnEpochRestore) + return e, ctrl } func TestEmptyMarkets(t *testing.T) { diff --git a/core/execution/future/market_snapshot_test.go b/core/execution/future/market_snapshot_test.go index 8ff88d486b7..ba39ddb211a 100644 --- a/core/execution/future/market_snapshot_test.go +++ b/core/execution/future/market_snapshot_test.go @@ -191,7 +191,8 @@ func newMarketFromSnapshot(t *testing.T, ctrl *gomock.Controller, em *types.Exec epochEngine.EXPECT().NotifyOnEpoch(gomock.Any(), gomock.Any()).Times(1) teams := mocks.NewMockTeams(ctrl) bc := mocks.NewMockAccountBalanceChecker(ctrl) - marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, bc) + marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epochEngine.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) broker := bmocks.NewMockBroker(ctrl) broker.EXPECT().Send(gomock.Any()).AnyTimes() diff --git a/core/execution/future/market_test.go b/core/execution/future/market_test.go index 2c24e0fde76..148d3fc2b1b 100644 --- a/core/execution/future/market_test.go +++ b/core/execution/future/market_test.go @@ -234,7 +234,8 @@ func (tm *testMarket) Run(ctx context.Context, mktCfg types.Market) *testMarket teams := mocks.NewMockTeams(tm.ctrl) bc := mocks.NewMockAccountBalanceChecker(tm.ctrl) - marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, bc) + marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epochEngine.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) referralDiscountReward := fmocks.NewMockReferralDiscountRewardService(tm.ctrl) volumeDiscount := fmocks.NewMockVolumeDiscountService(tm.ctrl) @@ -638,7 +639,8 @@ func getTestMarket2WithDP( epoch.EXPECT().NotifyOnEpoch(gomock.Any(), gomock.Any()).Times(1) teams := mocks.NewMockTeams(tm.ctrl) bc := mocks.NewMockAccountBalanceChecker(tm.ctrl) - marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epoch, teams, bc) + marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epoch.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) referralDiscountReward := fmocks.NewMockReferralDiscountRewardService(tm.ctrl) volumeDiscount := fmocks.NewMockVolumeDiscountService(tm.ctrl) diff --git a/core/execution/snapshot_test.go b/core/execution/snapshot_test.go index 0a8968ba602..8fb1490501a 100644 --- a/core/execution/snapshot_test.go +++ b/core/execution/snapshot_test.go @@ -588,7 +588,8 @@ func getEngine(t *testing.T, vegaPath paths.Paths, now time.Time) *snapshotTestD ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) bc := mocks.NewMockAccountBalanceChecker(ctrl) - marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, bc) + marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epochEngine.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) ethAsset := types.Asset{ ID: "Ethereum/Ether", @@ -650,7 +651,8 @@ func getEngineWithParties(t *testing.T, now time.Time, balance *num.Uint, partie ctrl := gomock.NewController(t) teams := mocks.NewMockTeams(ctrl) bc := mocks.NewMockAccountBalanceChecker(ctrl) - marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), epochEngine, teams, bc) + marketActivityTracker := common.NewMarketActivityTracker(logging.NewTestLogger(), teams, bc) + epochEngine.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) ethAsset := types.Asset{ ID: "Ethereum/Ether", diff --git a/core/execution/spot/market_test.go b/core/execution/spot/market_test.go index 8b049fa1a88..2d733679f4e 100644 --- a/core/execution/spot/market_test.go +++ b/core/execution/spot/market_test.go @@ -203,7 +203,8 @@ func newTestMarket( teams := mocks.NewMockTeams(ctrl) bc := mocks.NewMockAccountBalanceChecker(ctrl) - mat := common.NewMarketActivityTracker(log, epoch, teams, bc) + mat := common.NewMarketActivityTracker(log, teams, bc) + epoch.NotifyOnEpoch(mat.OnEpochEvent, mat.OnEpochRestore) baseAsset := NewAssetStub(base, baseDP) quoteAsset := NewAssetStub(quote, quoteDP) diff --git a/core/governance/market_cp_restore_test.go b/core/governance/market_cp_restore_test.go index c867a329ba2..9a74afed78a 100644 --- a/core/governance/market_cp_restore_test.go +++ b/core/governance/market_cp_restore_test.go @@ -198,7 +198,8 @@ func createExecutionEngine(t *testing.T, tm time.Time) (*execution.Engine, *gove asset := assets.New(log, assets.NewDefaultConfig(), getNodeWallet().Ethereum, nil, broker, bridgeView, notary, false) teams := emocks.NewMockTeams(ctrl) bc := emocks.NewMockAccountBalanceChecker(ctrl) - marketTracker := common.NewMarketActivityTracker(log, epochEngine, teams, bc) + marketTracker := common.NewMarketActivityTracker(log, teams, bc) + epochEngine.NotifyOnEpoch(marketTracker.OnEpochEvent, marketTracker.OnEpochRestore) referralDiscountReward := fmocks.NewMockReferralDiscountRewardService(ctrl) volumeDiscount := fmocks.NewMockVolumeDiscountService(ctrl) referralDiscountReward.EXPECT().GetReferrer(gomock.Any()).Return(types.PartyID(""), errors.New("no referrer")).AnyTimes() diff --git a/core/integration/features/rewards/lp_reward.feature b/core/integration/features/rewards/lp_reward.feature new file mode 100644 index 00000000000..f6c75145c73 --- /dev/null +++ b/core/integration/features/rewards/lp_reward.feature @@ -0,0 +1,122 @@ +Feature: Rewards for liquidity fees recieved + + Background: + + # Initialise the network + Given time is updated to "2023-01-01T00:00:00Z" + And the average block duration is "1" + And the following network parameters are set: + | name | value | + | market.fee.factors.makerFee | 0.001 | + | network.markPriceUpdateMaximumFrequency | 0s | + | market.auction.minimumDuration | 1 | + | validators.epoch.length | 60s | + | limits.markets.maxPeggedOrders | 4 | + | referralProgram.minStakedVegaTokens | 0 | + + # Initialise the markets + And the following assets are registered: + | id | decimal places | quantum | + | USD-1-10 | 1 | 10 | + And the markets: + | id | quote name | asset | risk model | margin calculator | auction duration | fees | price monitoring | data source config | linear slippage factor | quadratic slippage factor | sla params | decimal places | position decimal places | + | ETH/USD-1-10 | ETH | USD-1-10 | default-log-normal-risk-model | default-margin-calculator | 1 | default-none | default-none | default-eth-for-future | 1e-3 | 0 | default-futures | 0 | 0 | + + # Initialise the parties + Given the parties deposit on asset's general account the following amount: + | party | asset | amount | + | lpprov | USD-1-10 | 10000000000 | + | aux1 | USD-1-10 | 10000000 | + | aux2 | USD-1-10 | 10000000 | + | referrer1 | USD-1-10 | 10000000 | + | referee1 | USD-1-10 | 10000000 | + | referee2 | USD-1-10 | 10000000 | + | referee3 | USD-1-10 | 10000000 | + | a3c024b4e23230c89884a54a813b1ecb4cb0f827a38641c66eeca466da6b2ddf | USD-1-10 | 10000000 | + + # Exit opening auctions + Given the parties submit the following liquidity provision: + | id | party | market id | commitment amount | fee | lp type | + | lp1 | lpprov | ETH/USD-1-10 | 1000000 | 0.01 | submission | + And the parties place the following pegged iceberg orders: + | party | market id | peak size | minimum visible size | side | pegged reference | volume | offset | + | lpprov | ETH/USD-1-10 | 5000 | 1000 | buy | BID | 10000 | 1 | + | lpprov | ETH/USD-1-10 | 5000 | 1000 | sell | ASK | 10000 | 1 | + When the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | + | aux1 | ETH/USD-1-10 | buy | 1 | 990 | 0 | TYPE_LIMIT | TIF_GTC | + | aux1 | ETH/USD-1-10 | buy | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | aux2 | ETH/USD-1-10 | sell | 1 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | aux2 | ETH/USD-1-10 | sell | 1 | 1100 | 0 | TYPE_LIMIT | TIF_GTC | + And the opening auction period ends for market "ETH/USD-1-10" + When the network moves ahead "1" blocks + And the trading mode should be "TRADING_MODE_CONTINUOUS" for the market "ETH/USD-1-10" + + # Create the teams + Given the parties create the following referral codes: + | party | code | is_team | team | + | referrer1 | referral-code-1 | true | team1 | + And the parties apply the following referral codes: + | party | code | is_team | team | + | lpprov | referral-code-1 | true | team1 | + And the team "team1" has the following members: + | party | + | referrer1 | + | lpprov | + + Scenario: Party funds reward pool with lp received fees and dispatch metric scoping individuals + + Given the parties submit the following recurring transfers: + | id | from | from_account_type | to | to_account_type | entity_scope | asset | amount | start_epoch | end_epoch | factor | metric | metric_asset | markets | + | 1 | a3c024b4e23230c89884a54a813b1ecb4cb0f827a38641c66eeca466da6b2ddf | ACCOUNT_TYPE_GENERAL | 0000000000000000000000000000000000000000000000000000000000000000 | ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES | INDIVIDUALS | USD-1-10 | 10000 | 1 | | 1 | DISPATCH_METRIC_LP_FEES_RECEIVED | USD-1-10 | ETH/USD-1-10 | + And the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | + | aux1 | ETH/USD-1-10 | sell | 10 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee1 | ETH/USD-1-10 | buy | 10 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + | aux1 | ETH/USD-1-10 | sell | 10 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee2 | ETH/USD-1-10 | buy | 10 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + | aux1 | ETH/USD-1-10 | sell | 5 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee3 | ETH/USD-1-10 | buy | 5 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + When the network moves ahead "1" epochs + # Confirm lpprov did indeed receive fees + Then the following transfers should happen: + | from | to | from account | to account | market id | amount | asset | + | | lpprov | ACCOUNT_TYPE_FEES_LIQUIDITY | ACCOUNT_TYPE_LP_LIQUIDITY_FEES | ETH/USD-1-10 | 2500 | USD-1-10 | + | lpprov | lpprov | ACCOUNT_TYPE_LP_LIQUIDITY_FEES | ACCOUNT_TYPE_GENERAL | ETH/USD-1-10 | 2500 | USD-1-10 | + # We would expect the lp to recieve the full reward + Then parties should have the following vesting account balances: + | party | asset | balance | + | lpprov | USD-1-10 | 10000 | + + + Scenario: Party funds reward pool with lp received fees dispatch metric and scoping teams + + Given the parties submit the following recurring transfers: + | id | from | from_account_type | to | to_account_type | entity_scope | teams | ntop | asset | amount | start_epoch | end_epoch | factor | metric | metric_asset | markets | + | 1 | a3c024b4e23230c89884a54a813b1ecb4cb0f827a38641c66eeca466da6b2ddf | ACCOUNT_TYPE_GENERAL | 0000000000000000000000000000000000000000000000000000000000000000 | ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES | TEAMS | team1 | 1 | USD-1-10 | 10000 | 1 | | 1 | DISPATCH_METRIC_LP_FEES_RECEIVED | USD-1-10 | ETH/USD-1-10 | + And the parties place the following orders: + | party | market id | side | volume | price | resulting trades | type | tif | + | aux1 | ETH/USD-1-10 | sell | 10 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee1 | ETH/USD-1-10 | buy | 10 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + | aux1 | ETH/USD-1-10 | sell | 10 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee2 | ETH/USD-1-10 | buy | 10 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + | aux1 | ETH/USD-1-10 | sell | 5 | 1000 | 0 | TYPE_LIMIT | TIF_GTC | + | referee3 | ETH/USD-1-10 | buy | 5 | 1000 | 1 | TYPE_LIMIT | TIF_GTC | + When the network moves ahead "1" epochs + # Confirm lpprov did indeed receive fees + Then the following transfers should happen: + | from | to | from account | to account | market id | amount | asset | + | | lpprov | ACCOUNT_TYPE_FEES_LIQUIDITY | ACCOUNT_TYPE_LP_LIQUIDITY_FEES | ETH/USD-1-10 | 2500 | USD-1-10 | + | lpprov | lpprov | ACCOUNT_TYPE_LP_LIQUIDITY_FEES | ACCOUNT_TYPE_GENERAL | ETH/USD-1-10 | 2500 | USD-1-10 | + + # We would expect the lp to recieve the full reward + Then parties should have the following vesting account balances: + | party | asset | balance | + | lpprov | USD-1-10 | 10000 | + + + + + + + diff --git a/core/integration/setup_test.go b/core/integration/setup_test.go index 901dc411476..f79b58f9355 100644 --- a/core/integration/setup_test.go +++ b/core/integration/setup_test.go @@ -175,7 +175,7 @@ func newExecutionTestSetup() *executionTestSetup { execsetup.teamsEngine = teams.NewEngine(execsetup.broker, execsetup.timeService) execsetup.stateVarEngine = stubs.NewStateVar() - marketActivityTracker := common.NewMarketActivityTracker(execsetup.log, execsetup.epochEngine, execsetup.teamsEngine, execsetup.stakingAccount) + marketActivityTracker := common.NewMarketActivityTracker(execsetup.log, execsetup.teamsEngine, execsetup.stakingAccount) execsetup.notary = notary.NewWithSnapshot(execsetup.log, notary.NewDefaultConfig(), execsetup.topology, execsetup.broker, commander) @@ -204,6 +204,7 @@ func newExecutionTestSetup() *executionTestSetup { execsetup.broker, ) execsetup.epochEngine.NotifyOnEpoch(execsetup.executionEngine.OnEpochEvent, execsetup.executionEngine.OnEpochRestore) + execsetup.epochEngine.NotifyOnEpoch(marketActivityTracker.OnEpochEvent, marketActivityTracker.OnEpochRestore) execsetup.banking = banking.New(execsetup.log, banking.NewDefaultConfig(), execsetup.collateralEngine, execsetup.witness, execsetup.timeService, execsetup.assetsEngine, execsetup.notary, execsetup.broker, execsetup.topology, execsetup.epochEngine, marketActivityTracker, stubs.NewBridgeViewStub(), eventForwarder) diff --git a/core/protocol/all_services.go b/core/protocol/all_services.go index 567468180dd..3228ca21809 100644 --- a/core/protocol/all_services.go +++ b/core/protocol/all_services.go @@ -260,7 +260,7 @@ func newServices( svcs.teamsEngine = teams.NewSnapshottedEngine(svcs.broker, svcs.timeService) svcs.statevar = statevar.New(svcs.log, svcs.conf.StateVar, svcs.broker, svcs.topology, svcs.commander) - svcs.marketActivityTracker = common.NewMarketActivityTracker(svcs.log, svcs.epochService, svcs.teamsEngine, svcs.stakingAccounts) + svcs.marketActivityTracker = common.NewMarketActivityTracker(svcs.log, svcs.teamsEngine, svcs.stakingAccounts) svcs.notary = notary.NewWithSnapshot(svcs.log, svcs.conf.Notary, svcs.topology, svcs.broker, svcs.commander) @@ -294,7 +294,7 @@ func newServices( svcs.log, svcs.conf.Execution, svcs.timeService, svcs.collateral, svcs.oracle, svcs.broker, svcs.statevar, svcs.marketActivityTracker, svcs.assets, svcs.referralProgram, svcs.volumeDiscount, ) svcs.epochService.NotifyOnEpoch(svcs.executionEngine.OnEpochEvent, svcs.executionEngine.OnEpochRestore) - + svcs.epochService.NotifyOnEpoch(svcs.marketActivityTracker.OnEpochEvent, svcs.marketActivityTracker.OnEpochRestore) svcs.gastimator = processor.NewGastimator(svcs.executionEngine) svcs.banking = banking.New(svcs.log, svcs.conf.Banking, svcs.collateral, svcs.witness, svcs.timeService, svcs.assets, svcs.notary, svcs.broker, svcs.topology, svcs.epochService, svcs.marketActivityTracker, svcs.erc20BridgeView, svcs.eventForwarderEngine) diff --git a/datanode/gateway/graphql/new_transfer_resolver.go b/datanode/gateway/graphql/new_transfer_resolver.go index 4b4b6db3bfb..5f8053f9df5 100644 --- a/datanode/gateway/graphql/new_transfer_resolver.go +++ b/datanode/gateway/graphql/new_transfer_resolver.go @@ -55,7 +55,7 @@ func (r *newTransferResolver) Destination(ctx context.Context, obj *vega.NewTran } func (r *newTransferResolver) DestinationType(ctx context.Context, obj *vega.NewTransfer) (vega.AccountType, error) { - return obj.Changes.SourceType, nil + return obj.Changes.DestinationType, nil } func (r *newTransferResolver) Asset(ctx context.Context, obj *vega.NewTransfer) (*vega.Asset, error) {