From 1659f9355964d005dc79398bd8c29b5de98cb903 Mon Sep 17 00:00:00 2001 From: Mohammed Affan Date: Mon, 23 Sep 2024 22:39:31 -0400 Subject: [PATCH] [OTE-816] Update Revshare logic for affiliates (#2298) --- protocol/app/app.go | 1 - protocol/testutil/keeper/clob.go | 1 - protocol/testutil/keeper/listing.go | 1 - protocol/testutil/keeper/sending.go | 1 - protocol/testutil/keeper/subaccounts.go | 3 - .../x/clob/keeper/process_single_match.go | 10 +- protocol/x/revshare/keeper/revshare.go | 41 +-- protocol/x/revshare/keeper/revshare_test.go | 170 ++++------ protocol/x/revshare/types/errors.go | 5 + protocol/x/revshare/types/types.go | 2 +- protocol/x/rewards/keeper/keeper.go | 2 +- protocol/x/rewards/keeper/keeper_test.go | 42 +-- protocol/x/subaccounts/keeper/keeper.go | 4 +- protocol/x/subaccounts/keeper/transfer.go | 3 +- .../x/subaccounts/keeper/transfer_test.go | 290 ++++++++---------- .../x/subaccounts/types/expected_keepers.go | 11 - 16 files changed, 245 insertions(+), 342 deletions(-) diff --git a/protocol/app/app.go b/protocol/app/app.go index d06428fb23..d45290bc17 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -1091,7 +1091,6 @@ func New( app.BankKeeper, app.PerpetualsKeeper, app.BlockTimeKeeper, - app.RevShareKeeper, app.IndexerEventManager, app.FullNodeStreamingManager, ) diff --git a/protocol/testutil/keeper/clob.go b/protocol/testutil/keeper/clob.go index 0b75109217..0e544921df 100644 --- a/protocol/testutil/keeper/clob.go +++ b/protocol/testutil/keeper/clob.go @@ -170,7 +170,6 @@ func NewClobKeepersTestContextWithUninitializedMemStore( bankKeeper, ks.PerpetualsKeeper, ks.BlockTimeKeeper, - revShareKeeper, indexerEventsTransientStoreKey, true, ) diff --git a/protocol/testutil/keeper/listing.go b/protocol/testutil/keeper/listing.go index d09633c4cd..7b34551a2a 100644 --- a/protocol/testutil/keeper/listing.go +++ b/protocol/testutil/keeper/listing.go @@ -134,7 +134,6 @@ func ListingKeepers( bankKeeper, perpetualsKeeper, blockTimeKeeper, - revShareKeeper, transientStoreKey, true, ) diff --git a/protocol/testutil/keeper/sending.go b/protocol/testutil/keeper/sending.go index 9661da1107..7adb413cc2 100644 --- a/protocol/testutil/keeper/sending.go +++ b/protocol/testutil/keeper/sending.go @@ -113,7 +113,6 @@ func SendingKeepersWithSubaccountsKeeper(t testing.TB, saKeeper types.Subaccount ks.BankKeeper, ks.PerpetualsKeeper, blockTimeKeeper, - revShareKeeper, transientStoreKey, true, ) diff --git a/protocol/testutil/keeper/subaccounts.go b/protocol/testutil/keeper/subaccounts.go index 51df4c148e..127cdf60ac 100644 --- a/protocol/testutil/keeper/subaccounts.go +++ b/protocol/testutil/keeper/subaccounts.go @@ -100,7 +100,6 @@ func SubaccountsKeepers(t testing.TB, msgSenderEnabled bool) ( bankKeeper, perpetualsKeeper, blocktimeKeeper, - revShareKeeper, transientStoreKey, msgSenderEnabled, ) @@ -132,7 +131,6 @@ func createSubaccountsKeeper( bk types.BankKeeper, pk *perpskeeper.Keeper, btk *blocktimekeeper.Keeper, - rsk *revsharekeeper.Keeper, transientStoreKey storetypes.StoreKey, msgSenderEnabled bool, ) (*keeper.Keeper, storetypes.StoreKey) { @@ -151,7 +149,6 @@ func createSubaccountsKeeper( bk, pk, btk, - rsk, mockIndexerEventsManager, streaming.NewNoopGrpcStreamingManager(), ) diff --git a/protocol/x/clob/keeper/process_single_match.go b/protocol/x/clob/keeper/process_single_match.go index 509a5ccfc0..903e351928 100644 --- a/protocol/x/clob/keeper/process_single_match.go +++ b/protocol/x/clob/keeper/process_single_match.go @@ -14,6 +14,7 @@ import ( "github.com/dydxprotocol/v4-chain/protocol/lib/metrics" assettypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" + revsharetypes "github.com/dydxprotocol/v4-chain/protocol/x/revshare/types" satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" gometrics "github.com/hashicorp/go-metrics" ) @@ -464,14 +465,13 @@ func (k Keeper) persistMatchedOrders( // Distribute the fee amount from subacounts module to fee collector and rev share accounts bigTotalFeeQuoteQuantums := new(big.Int).Add(bigTakerFeeQuoteQuantums, bigMakerFeeQuoteQuantums) revSharesForFill, err := k.revshareKeeper.GetAllRevShares(ctx, fillForProcess, affiliatesWhitelistMap) - + if err != nil { + revSharesForFill = revsharetypes.RevSharesForFill{} + log.ErrorLog(ctx, "error getting rev shares for fill", "error", err) + } if revSharesForFill.AffiliateRevShare != nil { affiliateRevSharesQuoteQuantums = revSharesForFill.AffiliateRevShare.QuoteQuantums } - - if err != nil { - return takerUpdateResult, makerUpdateResult, affiliateRevSharesQuoteQuantums, err - } if err := k.subaccountsKeeper.DistributeFees( ctx, assettypes.AssetUsdc.Id, diff --git a/protocol/x/revshare/keeper/revshare.go b/protocol/x/revshare/keeper/revshare.go index 91d67df6c9..74ea0c0158 100644 --- a/protocol/x/revshare/keeper/revshare.go +++ b/protocol/x/revshare/keeper/revshare.go @@ -3,7 +3,6 @@ package keeper import ( "math/big" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/dydxprotocol/v4-chain/protocol/lib" @@ -163,25 +162,28 @@ func (k Keeper) GetAllRevShares( feeSourceToRevSharePpm := make(map[types.RevShareFeeSource]uint32) feeSourceToQuoteQuantums[types.REV_SHARE_FEE_SOURCE_TAKER_FEE] = big.NewInt(0) feeSourceToRevSharePpm[types.REV_SHARE_FEE_SOURCE_TAKER_FEE] = 0 - feeSourceToQuoteQuantums[types.REV_SHARE_FEE_SOURCE_NET_FEE] = big.NewInt(0) - feeSourceToRevSharePpm[types.REV_SHARE_FEE_SOURCE_NET_FEE] = 0 + feeSourceToQuoteQuantums[types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE] = big.NewInt(0) + feeSourceToRevSharePpm[types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE] = 0 totalFeesShared := big.NewInt(0) takerFees := fill.TakerFeeQuoteQuantums makerFees := fill.MakerFeeQuoteQuantums netFees := big.NewInt(0).Add(takerFees, makerFees) - affiliateRevShares, err := k.getAffiliateRevShares(ctx, fill, affiliatesWhitelistMap) + affiliateRevShares, affiliateFeesShared, err := k.getAffiliateRevShares(ctx, fill, affiliatesWhitelistMap) if err != nil { return types.RevSharesForFill{}, err } + netFeesSubAffiliateFeesShared := new(big.Int).Sub(netFees, affiliateFeesShared) + if netFeesSubAffiliateFeesShared.Sign() <= 0 { + return types.RevSharesForFill{}, types.ErrAffiliateFeesSharedExceedsNetFees + } - unconditionalRevShares, err := k.getUnconditionalRevShares(ctx, netFees) + unconditionalRevShares, err := k.getUnconditionalRevShares(ctx, netFeesSubAffiliateFeesShared) if err != nil { return types.RevSharesForFill{}, err } - - marketMapperRevShares, err := k.getMarketMapperRevShare(ctx, fill.MarketId, netFees) + marketMapperRevShares, err := k.getMarketMapperRevShare(ctx, fill.MarketId, netFeesSubAffiliateFeesShared) if err != nil { return types.RevSharesForFill{}, err } @@ -208,8 +210,7 @@ func (k Keeper) GetAllRevShares( } //check total fees shared is less than or equal to net fees if totalFeesShared.Cmp(netFees) > 0 { - return types.RevSharesForFill{}, errorsmod.Wrap( - types.ErrTotalFeesSharedExceedsNetFees, "total fees shared exceeds net fees") + return types.RevSharesForFill{}, types.ErrTotalFeesSharedExceedsNetFees } return types.RevSharesForFill{ @@ -224,20 +225,20 @@ func (k Keeper) getAffiliateRevShares( ctx sdk.Context, fill clobtypes.FillForProcess, affiliatesWhitelistMap map[string]uint32, -) ([]types.RevShare, error) { +) ([]types.RevShare, *big.Int, error) { takerAddr := fill.TakerAddr takerFee := fill.TakerFeeQuoteQuantums if fill.MonthlyRollingTakerVolumeQuantums >= types.MaxReferee30dVolumeForAffiliateShareQuantums { - return nil, nil + return nil, big.NewInt(0), nil } takerAffiliateAddr, feeSharePpm, exists, err := k.affiliatesKeeper.GetTakerFeeShare( ctx, takerAddr, affiliatesWhitelistMap) if err != nil { - return nil, err + return nil, big.NewInt(0), err } if !exists { - return nil, nil + return nil, big.NewInt(0), nil } feesShared := lib.BigMulPpm(takerFee, lib.BigU(feeSharePpm), false) return []types.RevShare{ @@ -248,12 +249,12 @@ func (k Keeper) getAffiliateRevShares( QuoteQuantums: feesShared, RevSharePpm: feeSharePpm, }, - }, nil + }, feesShared, nil } func (k Keeper) getUnconditionalRevShares( ctx sdk.Context, - netFees *big.Int, + netFeesSubAffiliateFeesShared *big.Int, ) ([]types.RevShare, error) { revShares := []types.RevShare{} unconditionalRevShareConfig, err := k.GetUnconditionalRevShareConfigParams(ctx) @@ -261,10 +262,10 @@ func (k Keeper) getUnconditionalRevShares( return nil, err } for _, revShare := range unconditionalRevShareConfig.Configs { - feeShared := lib.BigMulPpm(netFees, lib.BigU(revShare.SharePpm), false) + feeShared := lib.BigMulPpm(netFeesSubAffiliateFeesShared, lib.BigU(revShare.SharePpm), false) revShare := types.RevShare{ Recipient: revShare.Address, - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: feeShared, RevSharePpm: revShare.SharePpm, @@ -277,7 +278,7 @@ func (k Keeper) getUnconditionalRevShares( func (k Keeper) getMarketMapperRevShare( ctx sdk.Context, marketId uint32, - netFees *big.Int, + netFeesSubAffiliateFeesShared *big.Int, ) ([]types.RevShare, error) { revShares := []types.RevShare{} marketMapperRevshareAddress, revenueSharePpm, err := k.GetMarketMapperRevenueShareForMarket(ctx, marketId) @@ -288,10 +289,10 @@ func (k Keeper) getMarketMapperRevShare( return nil, nil } - marketMapperRevshareAmount := lib.BigMulPpm(netFees, lib.BigU(revenueSharePpm), false) + marketMapperRevshareAmount := lib.BigMulPpm(netFeesSubAffiliateFeesShared, lib.BigU(revenueSharePpm), false) revShares = append(revShares, types.RevShare{ Recipient: marketMapperRevshareAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, QuoteQuantums: marketMapperRevshareAmount, RevSharePpm: revenueSharePpm, diff --git a/protocol/x/revshare/keeper/revshare_test.go b/protocol/x/revshare/keeper/revshare_test.go index 7ecc596393..488a908679 100644 --- a/protocol/x/revshare/keeper/revshare_test.go +++ b/protocol/x/revshare/keeper/revshare_test.go @@ -324,31 +324,34 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { expectedRevSharesForFill: types.RevSharesForFill{ AllRevShares: []types.RevShare{ { + // BobAddress has 500000000000000000000000 coins staked + // via genesis. Which puts Bob at the highest tier + // and gives him a 15% taker fee share. Recipient: constants.BobAccAddress.String(), RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_TAKER_FEE, RevShareType: types.REV_SHARE_TYPE_AFFILIATE, - QuoteQuantums: big.NewInt(1_500_000), + QuoteQuantums: big.NewInt(1_500_000), // 15 % of 10 million taker fee quote quantums RevSharePpm: 150_000, }, { Recipient: constants.BobAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, - QuoteQuantums: big.NewInt(2_400_000), + QuoteQuantums: big.NewInt(2_100_000), // (10 + 2 - 1.5) * 20% RevSharePpm: 200_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, - QuoteQuantums: big.NewInt(3_600_000), + QuoteQuantums: big.NewInt(3_150_000), // (10 + 2 - 1.5) * 30% RevSharePpm: 300_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, - QuoteQuantums: big.NewInt(1_200_000), + QuoteQuantums: big.NewInt(1_050_000), // (10 + 2 - 1.5) * 10% RevSharePpm: 100_000, }, }, @@ -356,16 +359,17 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { Recipient: constants.BobAccAddress.String(), RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_TAKER_FEE, RevShareType: types.REV_SHARE_TYPE_AFFILIATE, - QuoteQuantums: big.NewInt(1_500_000), + QuoteQuantums: big.NewInt(1_500_000), // 15 % of 10 million taker fee quote quantums RevSharePpm: 150_000, }, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(7_200_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), // affiliate rev share fees + // unconditional + market mapper rev shares fees + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(6_300_000), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, - types.REV_SHARE_FEE_SOURCE_NET_FEE: 600_000, + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, // affiliate rev share fee ppm + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 600_000, // unconditional + market mapper rev share fee ppm }, }, fill: clobtypes.FillForProcess{ @@ -408,7 +412,7 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, }, { - name: "Valid rev-share from affiliates, negative unconditional and market mapper", + name: "Valid rev-share from affiliates, negative maker fee and unconditional and market mapper", expectedRevSharesForFill: types.RevSharesForFill{ AllRevShares: []types.RevShare{ { @@ -420,33 +424,33 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, { Recipient: constants.BobAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, - QuoteQuantums: big.NewInt(1_600_000), + QuoteQuantums: big.NewInt(1_300_000), RevSharePpm: 200_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, - QuoteQuantums: big.NewInt(2_400_000), + QuoteQuantums: big.NewInt(1_950_000), RevSharePpm: 300_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, - QuoteQuantums: big.NewInt(800_000), + QuoteQuantums: big.NewInt(650_000), RevSharePpm: 100_000, }, }, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(4_800_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(3_900_000), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, - types.REV_SHARE_FEE_SOURCE_NET_FEE: 600_000, + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 600_000, }, AffiliateRevShare: &types.RevShare{ Recipient: constants.BobAccAddress.String(), @@ -511,21 +515,21 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { AllRevShares: []types.RevShare{ { Recipient: constants.BobAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(2_400_000), RevSharePpm: 200_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(3_600_000), RevSharePpm: 300_000, }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, QuoteQuantums: big.NewInt(1_200_000), RevSharePpm: 100_000, @@ -533,12 +537,12 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, AffiliateRevShare: nil, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(7_200_000), - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(7_200_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: 600_000, - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 600_000, + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, }, }, setup: func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, @@ -582,19 +586,19 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, - QuoteQuantums: big.NewInt(1_200_000), + QuoteQuantums: big.NewInt(1_050_000), RevSharePpm: 100_000, // 10% }, }, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(1_200_000), - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(1_050_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: 100_000, // 10% - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, // 15% + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, // 15% }, AffiliateRevShare: &types.RevShare{ Recipient: constants.BobAccAddress.String(), @@ -643,19 +647,19 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, { Recipient: constants.BobAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_UNCONDITIONAL, - QuoteQuantums: big.NewInt(2_400_000), + QuoteQuantums: big.NewInt(2_100_000), RevSharePpm: 200_000, // 20% }, }, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(2_400_000), - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(2_100_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(1_500_000), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: 200_000, // 20% - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, // 15% + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 200_000, // 20% + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 150_000, // 15% }, AffiliateRevShare: &types.RevShare{ Recipient: constants.BobAccAddress.String(), @@ -705,9 +709,9 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { }, { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: types.REV_SHARE_TYPE_MARKET_MAPPER, - QuoteQuantums: big.NewInt(1_200_000), + QuoteQuantums: big.NewInt(950_000), RevSharePpm: 100_000, // 10% }, }, @@ -719,12 +723,12 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { RevSharePpm: 250_000, // 25% }, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(1_200_000), - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(2_500_000), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(950_000), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(2_500_000), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: 100_000, // 10% - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 250_000, // 25% + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 250_000, // 25% }, }, fill: clobtypes.FillForProcess{ @@ -767,12 +771,12 @@ func TestKeeper_GetAllRevShares_Valid(t *testing.T) { AllRevShares: []types.RevShare{}, AffiliateRevShare: nil, FeeSourceToQuoteQuantums: map[types.RevShareFeeSource]*big.Int{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(0), - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(0), + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), }, FeeSourceToRevSharePpm: map[types.RevShareFeeSource]uint32{ - types.REV_SHARE_FEE_SOURCE_NET_FEE: 0, - types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, + types.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 0, + types.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, }, }, fill: clobtypes.FillForProcess{ @@ -821,17 +825,17 @@ func TestKeeper_GetAllRevShares_Invalid(t *testing.T) { name string revenueSharePpmNetFees uint32 revenueSharePpmTakerFees uint32 - expectedError error monthlyRollingTakerVolumeQuantums uint64 + expectedError error setup func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, affiliatesKeeper *affiliateskeeper.Keeper) }{ { name: "Total fees shared exceeds net fees from all sources", - revenueSharePpmNetFees: 950_000, // 95%, - revenueSharePpmTakerFees: 150_000, // 15% - expectedError: types.ErrTotalFeesSharedExceedsNetFees, + revenueSharePpmNetFees: 950_000, // 95%, + revenueSharePpmTakerFees: 150_000, // 15% monthlyRollingTakerVolumeQuantums: 1_000_000_000_000, // 1 million USDC + expectedError: types.ErrTotalFeesSharedExceedsNetFees, setup: func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, affiliatesKeeper *affiliateskeeper.Keeper) { err := keeper.SetMarketMapperRevenueShareParams(ctx, types.MarketMapperRevenueShareParams{ @@ -845,7 +849,7 @@ func TestKeeper_GetAllRevShares_Invalid(t *testing.T) { Configs: []types.UnconditionalRevShareConfig_RecipientConfig{ { Address: constants.BobAccAddress.String(), - SharePpm: 150_000, // 15% + SharePpm: 250_000, // 25% }, }, }) @@ -856,58 +860,12 @@ func TestKeeper_GetAllRevShares_Invalid(t *testing.T) { require.NoError(t, err) }, }, - { - name: "Total fees shared exceeds net fees from market mapper and affiliates", - revenueSharePpmNetFees: 950_000, // 95%, - revenueSharePpmTakerFees: 150_000, // 15% - expectedError: types.ErrTotalFeesSharedExceedsNetFees, - monthlyRollingTakerVolumeQuantums: 1_000_000_000_000, // 1 million USDC - setup: func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, - affiliatesKeeper *affiliateskeeper.Keeper) { - err := keeper.SetMarketMapperRevenueShareParams(ctx, types.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - RevenueSharePpm: 950_000, // 95% - ValidDays: 1, - }) - require.NoError(t, err) - - err = affiliatesKeeper.UpdateAffiliateTiers(ctx, affiliatetypes.DefaultAffiliateTiers) - require.NoError(t, err) - err = affiliatesKeeper.RegisterAffiliate(ctx, constants.AliceAccAddress.String(), - constants.BobAccAddress.String()) - require.NoError(t, err) - }, - }, - { - name: "Total fees shared exceeds net fees from affiliates and unconditional rev shares", - revenueSharePpmNetFees: 950_000, // 95%, - revenueSharePpmTakerFees: 150_000, // 15% - expectedError: types.ErrTotalFeesSharedExceedsNetFees, - monthlyRollingTakerVolumeQuantums: 1_000_000_000_000, // 1 million USDC - setup: func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, - affiliatesKeeper *affiliateskeeper.Keeper) { - keeper.SetUnconditionalRevShareConfigParams(ctx, types.UnconditionalRevShareConfig{ - Configs: []types.UnconditionalRevShareConfig_RecipientConfig{ - { - Address: constants.BobAccAddress.String(), - SharePpm: 950_000, // 95% - }, - }, - }) - - err := affiliatesKeeper.UpdateAffiliateTiers(ctx, affiliatetypes.DefaultAffiliateTiers) - require.NoError(t, err) - err = affiliatesKeeper.RegisterAffiliate(ctx, constants.AliceAccAddress.String(), - constants.BobAccAddress.String()) - require.NoError(t, err) - }, - }, { name: "Total fees shared exceeds net fees - no affiliate rev shares", - revenueSharePpmNetFees: 1_150_000, // 115%, - revenueSharePpmTakerFees: 0, // 0% - expectedError: types.ErrTotalFeesSharedExceedsNetFees, + revenueSharePpmNetFees: 1_150_000, // 115%, + revenueSharePpmTakerFees: 0, // 0% monthlyRollingTakerVolumeQuantums: 1_000_000_000_000, // 1 million USDC + expectedError: types.ErrTotalFeesSharedExceedsNetFees, setup: func(tApp *testapp.TestApp, ctx sdk.Context, keeper *keeper.Keeper, affiliatesKeeper *affiliateskeeper.Keeper) { err := keeper.SetMarketMapperRevenueShareParams(ctx, types.MarketMapperRevenueShareParams{ diff --git a/protocol/x/revshare/types/errors.go b/protocol/x/revshare/types/errors.go index 59a45c415f..702ae92d15 100644 --- a/protocol/x/revshare/types/errors.go +++ b/protocol/x/revshare/types/errors.go @@ -36,4 +36,9 @@ var ( 6, "total fees shared exceeds net fees", ) + ErrAffiliateFeesSharedExceedsNetFees = errorsmod.Register( + ModuleName, + 7, + "affiliate fees shared exceeds net fees", + ) ) diff --git a/protocol/x/revshare/types/types.go b/protocol/x/revshare/types/types.go index c17a50584d..17ecd548a3 100644 --- a/protocol/x/revshare/types/types.go +++ b/protocol/x/revshare/types/types.go @@ -41,7 +41,7 @@ type RevShareFeeSource int const ( REV_SHARE_FEE_SOURCE_UNSPECIFIED RevShareFeeSource = iota - REV_SHARE_FEE_SOURCE_NET_FEE + REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE REV_SHARE_FEE_SOURCE_TAKER_FEE ) diff --git a/protocol/x/rewards/keeper/keeper.go b/protocol/x/rewards/keeper/keeper.go index f9daa60fac..ad15888005 100644 --- a/protocol/x/rewards/keeper/keeper.go +++ b/protocol/x/rewards/keeper/keeper.go @@ -146,7 +146,7 @@ func (k Keeper) AddRewardSharesForFill( maxMakerRebatePpm := lib.Min(int32(0), lowestMakerFee) totalNetFeeRevSharePpm := uint32(0) - if value, ok := revSharesForFill.FeeSourceToRevSharePpm[revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE]; ok { + if value, ok := revSharesForFill.FeeSourceToRevSharePpm[revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE]; ok { totalNetFeeRevSharePpm = value } maxPossibleTakerFeeRevShare := big.NewInt(0) diff --git a/protocol/x/rewards/keeper/keeper_test.go b/protocol/x/rewards/keeper/keeper_test.go index 5a018227f1..e5db22d37b 100644 --- a/protocol/x/rewards/keeper/keeper_test.go +++ b/protocol/x/rewards/keeper/keeper_test.go @@ -343,19 +343,19 @@ func TestAddRewardSharesForFill(t *testing.T) { AllRevShares: []revsharetypes.RevShare{ { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(200_000), RevSharePpm: 100_000, // 10% }, }, FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(200_000), - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(200_000), + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), }, FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: 100_000, // 10% - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, }, AffiliateRevShare: nil, }, @@ -391,26 +391,26 @@ func TestAddRewardSharesForFill(t *testing.T) { AllRevShares: []revsharetypes.RevShare{ { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(200_000), RevSharePpm: 100_000, // 10% }, { Recipient: constants.BobAccAddress.String(), - RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(200_000), RevSharePpm: 100_000, // 10% }, }, FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(400_000), - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(400_000), + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), }, FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: 200_000, // 20% - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 200_000, // 20% + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, }, AffiliateRevShare: nil, }, @@ -446,7 +446,7 @@ func TestAddRewardSharesForFill(t *testing.T) { AllRevShares: []revsharetypes.RevShare{ { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(200_000), RevSharePpm: 100_000, // 10% @@ -460,12 +460,12 @@ func TestAddRewardSharesForFill(t *testing.T) { }, }, FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(200_000), - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(200_000), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(200_000), + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(200_000), }, FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: 100_000, // 10% - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 100_000, // 10% + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 100_000, // 10% }, AffiliateRevShare: &revsharetypes.RevShare{ Recipient: takerAddress, @@ -507,7 +507,7 @@ func TestAddRewardSharesForFill(t *testing.T) { AllRevShares: []revsharetypes.RevShare{ { Recipient: constants.AliceAccAddress.String(), - RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE, + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, QuoteQuantums: big.NewInt(200_000), RevSharePpm: 100_000, // 10% @@ -521,12 +521,12 @@ func TestAddRewardSharesForFill(t *testing.T) { }, }, FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: big.NewInt(200_000), - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(200_000), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(200_000), + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(200_000), }, FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ - revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE: 100_000, // 10% - revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 100_000, // 10% + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 100_000, // 10% }, AffiliateRevShare: &revsharetypes.RevShare{ Recipient: takerAddress, diff --git a/protocol/x/subaccounts/keeper/keeper.go b/protocol/x/subaccounts/keeper/keeper.go index 1d82f9d1ea..d1727b7da5 100644 --- a/protocol/x/subaccounts/keeper/keeper.go +++ b/protocol/x/subaccounts/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "fmt" + streamingtypes "github.com/dydxprotocol/v4-chain/protocol/streaming/types" "cosmossdk.io/log" @@ -20,7 +21,6 @@ type ( bankKeeper types.BankKeeper perpetualsKeeper types.PerpetualsKeeper blocktimeKeeper types.BlocktimeKeeper - revShareKeeper types.RevShareKeeper indexerEventManager indexer_manager.IndexerEventManager streamingManager streamingtypes.FullNodeStreamingManager } @@ -33,7 +33,6 @@ func NewKeeper( bankKeeper types.BankKeeper, perpetualsKeeper types.PerpetualsKeeper, blocktimeKeeper types.BlocktimeKeeper, - revShareKeeper types.RevShareKeeper, indexerEventManager indexer_manager.IndexerEventManager, streamingManager streamingtypes.FullNodeStreamingManager, ) *Keeper { @@ -44,7 +43,6 @@ func NewKeeper( bankKeeper: bankKeeper, perpetualsKeeper: perpetualsKeeper, blocktimeKeeper: blocktimeKeeper, - revShareKeeper: revShareKeeper, indexerEventManager: indexerEventManager, streamingManager: streamingManager, } diff --git a/protocol/x/subaccounts/keeper/transfer.go b/protocol/x/subaccounts/keeper/transfer.go index 5724fbd777..ecf79952be 100644 --- a/protocol/x/subaccounts/keeper/transfer.go +++ b/protocol/x/subaccounts/keeper/transfer.go @@ -268,7 +268,8 @@ func (k Keeper) DistributeFees( totalTakerFeeRevShareQuantums = value } totalNetFeeRevShareQuantums := big.NewInt(0) - if value, ok := revSharesForFill.FeeSourceToQuoteQuantums[revsharetypes.REV_SHARE_FEE_SOURCE_NET_FEE]; ok { + if value, ok := + revSharesForFill.FeeSourceToQuoteQuantums[revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE]; ok { totalNetFeeRevShareQuantums = value } diff --git a/protocol/x/subaccounts/keeper/transfer_test.go b/protocol/x/subaccounts/keeper/transfer_test.go index 6fc7e33117..eefe09c4d3 100644 --- a/protocol/x/subaccounts/keeper/transfer_test.go +++ b/protocol/x/subaccounts/keeper/transfer_test.go @@ -20,7 +20,6 @@ import ( keepertest "github.com/dydxprotocol/v4-chain/protocol/testutil/keeper" sample_testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/sample" testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/util" - affiliatetypes "github.com/dydxprotocol/v4-chain/protocol/x/affiliates/types" asstypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" revsharetypes "github.com/dydxprotocol/v4-chain/protocol/x/revshare/types" @@ -1172,8 +1171,6 @@ func TestTransferFundsFromSubaccountToSubaccount_Failure(t *testing.T) { } func TestDistributeFees(t *testing.T) { - refereeAccAddr := constants.AliceAccAddress.String() - defaultUnconditionalRevSharePpm := uint32(100_000) tests := map[string]struct { skipSetUpUsdc bool @@ -1190,11 +1187,7 @@ func TestDistributeFees(t *testing.T) { affiliateRevShareAcctAddr string marketMapperRevShareAcctAddr string unconditionalRevShareAcctAddr string - - // Revenue share details - revshareParams revsharetypes.MarketMapperRevenueShareParams - setRevenueShare bool - revShareExpiration int64 + revShare revsharetypes.RevSharesForFill // Expectations. expectedErr error @@ -1219,15 +1212,13 @@ func TestDistributeFees(t *testing.T) { MarketId: uint32(0), MonthlyRollingTakerVolumeQuantums: 1_000_000, }, - collateralPoolAddr: types.ModuleAddress, - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 - expectedFeeModuleAccBalance: big.NewInt(3000), // 500 + 2500 - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + collateralPoolAddr: types.ModuleAddress, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 + expectedFeeModuleAccBalance: big.NewInt(3000), // 500 + 2500 + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1249,15 +1240,13 @@ func TestDistributeFees(t *testing.T) { collateralPoolAddr: authtypes.NewModuleAddress( types.ModuleName + ":" + lib.IntToString(3), ), - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 - expectedFeeModuleAccBalance: big.NewInt(3000), // 500 + 2500 - marketMapperAccBalance: big.NewInt(0), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 + expectedFeeModuleAccBalance: big.NewInt(3000), // 500 + 2500 + marketMapperAccBalance: big.NewInt(0), + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1276,17 +1265,15 @@ func TestDistributeFees(t *testing.T) { MarketId: uint32(3), MonthlyRollingTakerVolumeQuantums: 1_000_000, }, - collateralPoolAddr: types.ModuleAddress, - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedSubaccountsModuleAccBalance: big.NewInt(300), - expectedFeeModuleAccBalance: big.NewInt(2500), - expectedErr: sdkerrors.ErrInsufficientFunds, - marketMapperAccBalance: big.NewInt(0), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + collateralPoolAddr: types.ModuleAddress, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedSubaccountsModuleAccBalance: big.NewInt(300), + expectedFeeModuleAccBalance: big.NewInt(2500), + expectedErr: sdkerrors.ErrInsufficientFunds, + marketMapperAccBalance: big.NewInt(0), + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1308,16 +1295,14 @@ func TestDistributeFees(t *testing.T) { collateralPoolAddr: authtypes.NewModuleAddress( types.ModuleName + ":" + lib.IntToString(3), ), - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedSubaccountsModuleAccBalance: big.NewInt(300), - expectedFeeModuleAccBalance: big.NewInt(2500), - expectedErr: sdkerrors.ErrInsufficientFunds, - marketMapperAccBalance: big.NewInt(0), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedSubaccountsModuleAccBalance: big.NewInt(300), + expectedFeeModuleAccBalance: big.NewInt(2500), + expectedErr: sdkerrors.ErrInsufficientFunds, + marketMapperAccBalance: big.NewInt(0), + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1337,17 +1322,15 @@ func TestDistributeFees(t *testing.T) { MarketId: uint32(3), MonthlyRollingTakerVolumeQuantums: 1_000_000, }, - collateralPoolAddr: types.ModuleAddress, - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedErr: asstypes.ErrAssetDoesNotExist, - expectedSubaccountsModuleAccBalance: big.NewInt(500), - expectedFeeModuleAccBalance: big.NewInt(1500), - marketMapperAccBalance: big.NewInt(0), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + collateralPoolAddr: types.ModuleAddress, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedErr: asstypes.ErrAssetDoesNotExist, + expectedSubaccountsModuleAccBalance: big.NewInt(500), + expectedFeeModuleAccBalance: big.NewInt(1500), + marketMapperAccBalance: big.NewInt(0), + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1366,17 +1349,15 @@ func TestDistributeFees(t *testing.T) { MarketId: uint32(3), MonthlyRollingTakerVolumeQuantums: 1_000_000, }, - collateralPoolAddr: types.ModuleAddress, - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedErr: types.ErrAssetTransferThroughBankNotImplemented, - expectedSubaccountsModuleAccBalance: big.NewInt(500), - expectedFeeModuleAccBalance: big.NewInt(1500), - marketMapperAccBalance: big.NewInt(0), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - }, + collateralPoolAddr: types.ModuleAddress, + affiliateRevShareAcctAddr: "", + marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), + unconditionalRevShareAcctAddr: "", + expectedErr: types.ErrAssetTransferThroughBankNotImplemented, + expectedSubaccountsModuleAccBalance: big.NewInt(500), + expectedFeeModuleAccBalance: big.NewInt(1500), + marketMapperAccBalance: big.NewInt(0), + revShare: revsharetypes.RevSharesForFill{}, expectedMarketMapperAccBalance: big.NewInt(0), expectedAffiliateAccBalance: big.NewInt(0), expectedUnconditionalRevShareAccBalance: big.NewInt(0), @@ -1407,48 +1388,26 @@ func TestDistributeFees(t *testing.T) { affiliateRevShareAcctAddr: "", marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), unconditionalRevShareAcctAddr: "", - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - RevenueSharePpm: 100_000, // 10% - ValidDays: 240, - }, - setRevenueShare: true, - revShareExpiration: 100, - }, - "success - market mapper rev share expired": { - asset: *constants.Usdc, - feeModuleAccBalance: big.NewInt(2500), - subaccountModuleAccBalance: big.NewInt(600), - marketMapperAccBalance: big.NewInt(0), - fill: clobtypes.FillForProcess{ - TakerAddr: constants.AliceAccAddress.String(), - TakerFeeQuoteQuantums: big.NewInt(250), - MakerAddr: constants.BobAccAddress.String(), - MakerFeeQuoteQuantums: big.NewInt(250), - FillQuoteQuantums: big.NewInt(500), - ProductId: uint32(4), - MarketId: uint32(4), - MonthlyRollingTakerVolumeQuantums: 1_000_000, - }, - affiliateRevShareAcctAddr: "", - marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), - unconditionalRevShareAcctAddr: "", - expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 - expectedFeeModuleAccBalance: big.NewInt(3000), // 500 + 2500 - expectedMarketMapperAccBalance: big.NewInt(0), - expectedAffiliateAccBalance: big.NewInt(0), - expectedUnconditionalRevShareAccBalance: big.NewInt(0), - collateralPoolAddr: authtypes.NewModuleAddress( - types.ModuleName + ":" + lib.IntToString(4), - ), - - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - RevenueSharePpm: 100_000, // 10% - ValidDays: 240, + revShare: revsharetypes.RevSharesForFill{ + AffiliateRevShare: nil, + FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(50), + }, + FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, // 0% + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 100_000, // 10% + }, + AllRevShares: []revsharetypes.RevShare{ + { + Recipient: constants.AliceAccAddress.String(), + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, + RevShareType: revsharetypes.REV_SHARE_TYPE_MARKET_MAPPER, + QuoteQuantums: big.NewInt(50), + RevSharePpm: 100_000, // 10% + }, + }, }, - setRevenueShare: true, - revShareExpiration: -10, }, "success - market mapper rev share rounded down to 0": { asset: *constants.Usdc, @@ -1476,13 +1435,18 @@ func TestDistributeFees(t *testing.T) { affiliateRevShareAcctAddr: "", marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), unconditionalRevShareAcctAddr: "", - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - RevenueSharePpm: 100_000, // 10% - ValidDays: 240, + revShare: revsharetypes.RevSharesForFill{ + AffiliateRevShare: nil, + FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(0), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(0), + }, + FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 0, // 0% + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 0, // 0% + }, + AllRevShares: []revsharetypes.RevShare{}, }, - setRevenueShare: true, - revShareExpiration: 100, }, "success - distribute fees to market mapper, unconditional rev share, affiliate and fee collector": { asset: *constants.Usdc, @@ -1500,23 +1464,56 @@ func TestDistributeFees(t *testing.T) { MonthlyRollingTakerVolumeQuantums: 1_000_000, }, expectedSubaccountsModuleAccBalance: big.NewInt(100), // 600 - 500 - expectedFeeModuleAccBalance: big.NewInt(2888), // 2500 + 500 - 50 - expectedMarketMapperAccBalance: big.NewInt(50), // 10% of 500 + expectedFeeModuleAccBalance: big.NewInt(2892), // 2500 + 500 - 108 + expectedMarketMapperAccBalance: big.NewInt(48), // 10% of 488 expectedAffiliateAccBalance: big.NewInt(12), // 5% of 250 - expectedUnconditionalRevShareAccBalance: big.NewInt(50), // 10% of 500 + expectedUnconditionalRevShareAccBalance: big.NewInt(48), // 10% of 488 collateralPoolAddr: authtypes.NewModuleAddress( types.ModuleName + ":" + lib.IntToString(4), ), affiliateRevShareAcctAddr: constants.BobAccAddress.String(), marketMapperRevShareAcctAddr: constants.AliceAccAddress.String(), unconditionalRevShareAcctAddr: constants.CarlAccAddress.String(), - revshareParams: revsharetypes.MarketMapperRevenueShareParams{ - Address: constants.AliceAccAddress.String(), - RevenueSharePpm: 100_000, // 10% - ValidDays: 240, + revShare: revsharetypes.RevSharesForFill{ + AffiliateRevShare: &revsharetypes.RevShare{ + Recipient: constants.BobAccAddress.String(), + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE, + RevShareType: revsharetypes.REV_SHARE_TYPE_AFFILIATE, + QuoteQuantums: big.NewInt(12), + RevSharePpm: 50_000, // 5% + }, + FeeSourceToQuoteQuantums: map[revsharetypes.RevShareFeeSource]*big.Int{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: big.NewInt(12), + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: big.NewInt(96), + }, + FeeSourceToRevSharePpm: map[revsharetypes.RevShareFeeSource]uint32{ + revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE: 50_000, // 5% + revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE: 200_000, // 20% + }, + AllRevShares: []revsharetypes.RevShare{ + { + Recipient: constants.BobAccAddress.String(), + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_TAKER_FEE, + RevShareType: revsharetypes.REV_SHARE_TYPE_AFFILIATE, + QuoteQuantums: big.NewInt(12), + RevSharePpm: 50_000, // 5% + }, + { + Recipient: constants.AliceAccAddress.String(), + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, + RevShareType: revsharetypes.REV_SHARE_TYPE_MARKET_MAPPER, + QuoteQuantums: big.NewInt(48), + RevSharePpm: 100_000, // 10% + }, + { + Recipient: constants.CarlAccAddress.String(), + RevShareFeeSource: revsharetypes.REV_SHARE_FEE_SOURCE_NET_PROTOCOL_REVENUE, + RevShareType: revsharetypes.REV_SHARE_TYPE_UNCONDITIONAL, + QuoteQuantums: big.NewInt(48), + RevSharePpm: 100_000, // 10% + }, + }, }, - setRevenueShare: true, - revShareExpiration: 100, }, // TODO(DEC-715): Add more test for non-USDC assets, after asset update // is implemented. @@ -1525,7 +1522,7 @@ func TestDistributeFees(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { ctx, keeper, pricesKeeper, perpetualsKeeper, accountKeeper, - bankKeeper, assetsKeeper, _, revShareKeeper, affiliatesKeeper, _ := + bankKeeper, assetsKeeper, _, _, _, _ := keepertest.SubaccountsKeepers(t, true) keepertest.CreateTestMarkets(t, ctx, pricesKeeper) keepertest.CreateTestLiquidityTiers(t, ctx, perpetualsKeeper) @@ -1609,46 +1606,7 @@ func TestDistributeFees(t *testing.T) { require.NoError(t, err) } - // Set market mapper revenue share - err = revShareKeeper.SetMarketMapperRevenueShareParams( - ctx, - tc.revshareParams, - ) - require.NoError(t, err) - - if tc.setRevenueShare { - revShareKeeper.SetMarketMapperRevShareDetails( - ctx, - tc.fill.MarketId, - revsharetypes.MarketMapperRevShareDetails{ - ExpirationTs: uint64(ctx.BlockTime().Unix() + tc.revShareExpiration), - }, - ) - } - err = affiliatesKeeper.UpdateAffiliateTiers(ctx, affiliatetypes.DefaultAffiliateTiers) - require.NoError(t, err) - if tc.affiliateRevShareAcctAddr != "" { - err := affiliatesKeeper.RegisterAffiliate(ctx, refereeAccAddr, tc.affiliateRevShareAcctAddr) - require.NoError(t, err) - } - if tc.unconditionalRevShareAcctAddr != "" { - err := affiliatesKeeper.UpdateAffiliateTiers(ctx, affiliatetypes.DefaultAffiliateTiers) - require.NoError(t, err) - revShareKeeper.SetUnconditionalRevShareConfigParams(ctx, - revsharetypes.UnconditionalRevShareConfig{ - Configs: []revsharetypes.UnconditionalRevShareConfig_RecipientConfig{ - { - Address: tc.unconditionalRevShareAcctAddr, - SharePpm: defaultUnconditionalRevSharePpm, - }, - }, - }) - } - affiliateWhitelistMap, err := affiliatesKeeper.GetAffiliateWhitelistMap(ctx) - require.NoError(t, err) - revSharesForFill, err := revShareKeeper.GetAllRevShares(ctx, tc.fill, affiliateWhitelistMap) - require.NoError(t, err) - err = keeper.DistributeFees(ctx, tc.asset.Id, revSharesForFill, tc.fill) + err = keeper.DistributeFees(ctx, tc.asset.Id, tc.revShare, tc.fill) if tc.expectedErr != nil { require.ErrorIs(t, diff --git a/protocol/x/subaccounts/types/expected_keepers.go b/protocol/x/subaccounts/types/expected_keepers.go index 9d770273eb..a9e3f88f94 100644 --- a/protocol/x/subaccounts/types/expected_keepers.go +++ b/protocol/x/subaccounts/types/expected_keepers.go @@ -96,14 +96,3 @@ type BankKeeper interface { type BlocktimeKeeper interface { GetDowntimeInfoFor(ctx sdk.Context, duration time.Duration) blocktimetypes.AllDowntimeInfo_DowntimeInfo } - -type RevShareKeeper interface { - GetMarketMapperRevenueShareForMarket( - ctx sdk.Context, - marketId uint32, - ) ( - address sdk.AccAddress, - revenueSharePpm uint32, - err error, - ) -}