From 4283fc072dc6ea373ec55b994f23642f144aeb1f Mon Sep 17 00:00:00 2001 From: affan Date: Wed, 18 Sep 2024 00:27:49 -0400 Subject: [PATCH 1/3] write e2e tests --- .../codegen/dydxprotocol/revshare/genesis.ts | 21 +- .../src/codegen/dydxprotocol/stats/genesis.ts | 88 +++- proto/dydxprotocol/revshare/genesis.proto | 4 + proto/dydxprotocol/stats/genesis.proto | 11 + .../app/testdata/default_genesis_state.json | 6 +- .../scripts/genesis/sample_pregenesis.json | 6 +- protocol/testutil/app/app.go | 6 +- .../revshare/e2e/revshare_place_order_test.go | 442 ++++++++++++++++++ protocol/x/revshare/genesis.go | 8 + protocol/x/revshare/types/genesis.go | 3 + protocol/x/revshare/types/genesis.pb.go | 81 +++- protocol/x/stats/genesis.go | 4 + protocol/x/stats/types/genesis.go | 1 + protocol/x/stats/types/genesis.pb.go | 328 ++++++++++++- 14 files changed, 981 insertions(+), 28 deletions(-) create mode 100644 protocol/x/revshare/e2e/revshare_place_order_test.go diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/revshare/genesis.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/revshare/genesis.ts index 68e61a5119..1fb77cd32e 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/revshare/genesis.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/revshare/genesis.ts @@ -1,20 +1,30 @@ import { MarketMapperRevenueShareParams, MarketMapperRevenueShareParamsSDKType } from "./params"; +import { UnconditionalRevShareConfig, UnconditionalRevShareConfigSDKType } from "./revshare"; import * as _m0 from "protobufjs/minimal"; import { DeepPartial } from "../../helpers"; /** GenesisState defines `x/revshare`'s genesis state. */ export interface GenesisState { + /** params is the market mapper revenue share params. */ params?: MarketMapperRevenueShareParams; + /** unconditional_rev_share_config is the unconditional rev share config. */ + + unconditionalRevShareConfig?: UnconditionalRevShareConfig; } /** GenesisState defines `x/revshare`'s genesis state. */ export interface GenesisStateSDKType { + /** params is the market mapper revenue share params. */ params?: MarketMapperRevenueShareParamsSDKType; + /** unconditional_rev_share_config is the unconditional rev share config. */ + + unconditional_rev_share_config?: UnconditionalRevShareConfigSDKType; } function createBaseGenesisState(): GenesisState { return { - params: undefined + params: undefined, + unconditionalRevShareConfig: undefined }; } @@ -24,6 +34,10 @@ export const GenesisState = { MarketMapperRevenueShareParams.encode(message.params, writer.uint32(10).fork()).ldelim(); } + if (message.unconditionalRevShareConfig !== undefined) { + UnconditionalRevShareConfig.encode(message.unconditionalRevShareConfig, writer.uint32(18).fork()).ldelim(); + } + return writer; }, @@ -40,6 +54,10 @@ export const GenesisState = { message.params = MarketMapperRevenueShareParams.decode(reader, reader.uint32()); break; + case 2: + message.unconditionalRevShareConfig = UnconditionalRevShareConfig.decode(reader, reader.uint32()); + break; + default: reader.skipType(tag & 7); break; @@ -52,6 +70,7 @@ export const GenesisState = { fromPartial(object: DeepPartial): GenesisState { const message = createBaseGenesisState(); message.params = object.params !== undefined && object.params !== null ? MarketMapperRevenueShareParams.fromPartial(object.params) : undefined; + message.unconditionalRevShareConfig = object.unconditionalRevShareConfig !== undefined && object.unconditionalRevShareConfig !== null ? UnconditionalRevShareConfig.fromPartial(object.unconditionalRevShareConfig) : undefined; return message; } diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/genesis.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/genesis.ts index e03a7a1d4d..dc31550352 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/genesis.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/stats/genesis.ts @@ -1,4 +1,5 @@ import { Params, ParamsSDKType } from "./params"; +import { UserStats, UserStatsSDKType } from "./stats"; import * as _m0 from "protobufjs/minimal"; import { DeepPartial } from "../../helpers"; /** GenesisState defines the stats module's genesis state. */ @@ -6,17 +7,38 @@ import { DeepPartial } from "../../helpers"; export interface GenesisState { /** The parameters of the module. */ params?: Params; + addressToUserStats: AddressToUserStats[]; } /** GenesisState defines the stats module's genesis state. */ export interface GenesisStateSDKType { /** The parameters of the module. */ params?: ParamsSDKType; + address_to_user_stats: AddressToUserStatsSDKType[]; +} +/** AddressToUserStats is a struct that contains the user stats for an address. */ + +export interface AddressToUserStats { + /** The address of the user. */ + address: string; + /** The user stats for the address. */ + + userStats?: UserStats; +} +/** AddressToUserStats is a struct that contains the user stats for an address. */ + +export interface AddressToUserStatsSDKType { + /** The address of the user. */ + address: string; + /** The user stats for the address. */ + + user_stats?: UserStatsSDKType; } function createBaseGenesisState(): GenesisState { return { - params: undefined + params: undefined, + addressToUserStats: [] }; } @@ -26,6 +48,10 @@ export const GenesisState = { Params.encode(message.params, writer.uint32(10).fork()).ldelim(); } + for (const v of message.addressToUserStats) { + AddressToUserStats.encode(v!, writer.uint32(18).fork()).ldelim(); + } + return writer; }, @@ -42,6 +68,10 @@ export const GenesisState = { message.params = Params.decode(reader, reader.uint32()); break; + case 2: + message.addressToUserStats.push(AddressToUserStats.decode(reader, reader.uint32())); + break; + default: reader.skipType(tag & 7); break; @@ -54,6 +84,62 @@ export const GenesisState = { fromPartial(object: DeepPartial): GenesisState { const message = createBaseGenesisState(); message.params = object.params !== undefined && object.params !== null ? Params.fromPartial(object.params) : undefined; + message.addressToUserStats = object.addressToUserStats?.map(e => AddressToUserStats.fromPartial(e)) || []; + return message; + } + +}; + +function createBaseAddressToUserStats(): AddressToUserStats { + return { + address: "", + userStats: undefined + }; +} + +export const AddressToUserStats = { + encode(message: AddressToUserStats, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.address !== "") { + writer.uint32(10).string(message.address); + } + + if (message.userStats !== undefined) { + UserStats.encode(message.userStats, writer.uint32(18).fork()).ldelim(); + } + + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): AddressToUserStats { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAddressToUserStats(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + case 1: + message.address = reader.string(); + break; + + case 2: + message.userStats = UserStats.decode(reader, reader.uint32()); + break; + + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(object: DeepPartial): AddressToUserStats { + const message = createBaseAddressToUserStats(); + message.address = object.address ?? ""; + message.userStats = object.userStats !== undefined && object.userStats !== null ? UserStats.fromPartial(object.userStats) : undefined; return message; } diff --git a/proto/dydxprotocol/revshare/genesis.proto b/proto/dydxprotocol/revshare/genesis.proto index 981a514080..be2c077f67 100644 --- a/proto/dydxprotocol/revshare/genesis.proto +++ b/proto/dydxprotocol/revshare/genesis.proto @@ -3,10 +3,14 @@ package dydxprotocol.revshare; import "gogoproto/gogo.proto"; import "dydxprotocol/revshare/params.proto"; +import "dydxprotocol/revshare/revshare.proto"; option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/revshare/types"; // GenesisState defines `x/revshare`'s genesis state. message GenesisState { + // params is the market mapper revenue share params. MarketMapperRevenueShareParams params = 1 [ (gogoproto.nullable) = false ]; + // unconditional_rev_share_config is the unconditional rev share config. + UnconditionalRevShareConfig unconditional_rev_share_config = 2 [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/proto/dydxprotocol/stats/genesis.proto b/proto/dydxprotocol/stats/genesis.proto index 1ad57efde0..6df362f3fc 100644 --- a/proto/dydxprotocol/stats/genesis.proto +++ b/proto/dydxprotocol/stats/genesis.proto @@ -2,7 +2,9 @@ syntax = "proto3"; package dydxprotocol.stats; import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; import "dydxprotocol/stats/params.proto"; +import "dydxprotocol/stats/stats.proto"; option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/stats/types"; @@ -10,4 +12,13 @@ option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/stats/types"; message GenesisState { // The parameters of the module. Params params = 1 [ (gogoproto.nullable) = false ]; + repeated AddressToUserStats address_to_user_stats = 2; } + +// AddressToUserStats is a struct that contains the user stats for an address. +message AddressToUserStats { + // The address of the user. + string address = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + // The user stats for the address. + UserStats user_stats = 2; +} \ No newline at end of file diff --git a/protocol/app/testdata/default_genesis_state.json b/protocol/app/testdata/default_genesis_state.json index e8fd038a30..877c2c7d13 100644 --- a/protocol/app/testdata/default_genesis_state.json +++ b/protocol/app/testdata/default_genesis_state.json @@ -432,6 +432,9 @@ "address": "dydx17xpfvakm2amg962yls6f84z3kell8c5leqdyt2", "revenue_share_ppm": 0, "valid_days": 0 + }, + "unconditional_rev_share_config": { + "configs": [] } }, "rewards": { @@ -475,7 +478,8 @@ "stats": { "params": { "window_duration": "2592000s" - } + }, + "address_to_user_stats": [] }, "subaccounts": { "subaccounts": [] diff --git a/protocol/scripts/genesis/sample_pregenesis.json b/protocol/scripts/genesis/sample_pregenesis.json index bcb8311a75..63549af749 100644 --- a/protocol/scripts/genesis/sample_pregenesis.json +++ b/protocol/scripts/genesis/sample_pregenesis.json @@ -3876,6 +3876,9 @@ "address": "dydx17xpfvakm2amg962yls6f84z3kell8c5leqdyt2", "revenue_share_ppm": 0, "valid_days": 0 + }, + "unconditional_rev_share_config": { + "configs": [] } }, "rewards": { @@ -3917,6 +3920,7 @@ "validators": [] }, "stats": { + "address_to_user_stats": [], "params": { "window_duration": "2592000s" } @@ -3980,7 +3984,7 @@ ] } }, - "app_version": "5.2.1-103-g5c95dd72", + "app_version": "5.2.1-119-g77487f61", "chain_id": "dydx-sample-1", "consensus": { "params": { diff --git a/protocol/testutil/app/app.go b/protocol/testutil/app/app.go index 44f34b4b70..9b98b49113 100644 --- a/protocol/testutil/app/app.go +++ b/protocol/testutil/app/app.go @@ -49,6 +49,7 @@ import ( "github.com/dydxprotocol/v4-chain/protocol/testutil/appoptions" "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" testlog "github.com/dydxprotocol/v4-chain/protocol/testutil/logger" + affiliatestypes "github.com/dydxprotocol/v4-chain/protocol/x/affiliates/types" assettypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" blocktimetypes "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/types" bridgetypes "github.com/dydxprotocol/v4-chain/protocol/x/bridge/types" @@ -207,7 +208,8 @@ type GenesisStates interface { govplus.GenesisState | vaulttypes.GenesisState | revsharetypes.GenesisState | - marketmapmoduletypes.GenesisState + marketmapmoduletypes.GenesisState | + affiliatestypes.GenesisState } // UpdateGenesisDocWithAppStateForModule updates the supplied genesis doc using the provided function. The function @@ -269,6 +271,8 @@ func UpdateGenesisDocWithAppStateForModule[T GenesisStates](genesisDoc *types.Ge moduleName = marketmapmoduletypes.ModuleName case listingtypes.GenesisState: moduleName = listingtypes.ModuleName + case affiliatestypes.GenesisState: + moduleName = affiliatestypes.ModuleName default: panic(fmt.Errorf("Unsupported type %T", t)) } diff --git a/protocol/x/revshare/e2e/revshare_place_order_test.go b/protocol/x/revshare/e2e/revshare_place_order_test.go new file mode 100644 index 0000000000..ee7567f875 --- /dev/null +++ b/protocol/x/revshare/e2e/revshare_place_order_test.go @@ -0,0 +1,442 @@ +package revshare_test + +import ( + "math/big" + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + abcitypes "github.com/cometbft/cometbft/abci/types" + + cometbfttypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dydxprotocol/v4-chain/protocol/dtypes" + "github.com/dydxprotocol/v4-chain/protocol/indexer" + indexerevents "github.com/dydxprotocol/v4-chain/protocol/indexer/events" + "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" + "github.com/dydxprotocol/v4-chain/protocol/indexer/msgsender" + "github.com/dydxprotocol/v4-chain/protocol/lib" + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + clobtestutils "github.com/dydxprotocol/v4-chain/protocol/testutil/clob" + "github.com/dydxprotocol/v4-chain/protocol/testutil/constants" + testtx "github.com/dydxprotocol/v4-chain/protocol/testutil/tx" + testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/util" + "github.com/dydxprotocol/v4-chain/protocol/x/affiliates/types" + assettypes "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" + statstypes "github.com/dydxprotocol/v4-chain/protocol/x/stats/types" + satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" +) + +func TestPlaceOrderWithAffiliate(t *testing.T) { + testCases := []struct { + name string + initialUserStateStats *statstypes.UserStats + initialUnconditionalRevShareConfig *revsharetypes.UnconditionalRevShareConfig + initialMarketMapperRevShareParams *revsharetypes.MarketMapperRevenueShareParams + expectedTakerFeeQuantums int64 + expectedMakerFeeQuantums int64 + expectedAffiliateRevShareQuantums int64 + expectedUnconditionalRevShareQuantums int64 + expectedMarketMapperRevShareQuantums int64 + }{ + { + name: "affiliate revshare", + initialUserStateStats: nil, + initialUnconditionalRevShareConfig: nil, + initialMarketMapperRevShareParams: nil, + expectedTakerFeeQuantums: 2000, + expectedMakerFeeQuantums: 550, + expectedAffiliateRevShareQuantums: 300, + expectedUnconditionalRevShareQuantums: 0, + expectedMarketMapperRevShareQuantums: 0, + }, + { + name: "Affiliate over limit", + initialUserStateStats: &statstypes.UserStats{ + TakerNotional: uint64(35_000_000_000_000), + MakerNotional: uint64(35_000_000_000_000), + }, + initialUnconditionalRevShareConfig: nil, + initialMarketMapperRevShareParams: nil, + expectedTakerFeeQuantums: 1750, + expectedMakerFeeQuantums: 550, + expectedAffiliateRevShareQuantums: 0, + expectedUnconditionalRevShareQuantums: 0, + expectedMarketMapperRevShareQuantums: 0, + }, + { + name: "affiliate revshare + unconditional revshare", + initialUserStateStats: nil, + initialUnconditionalRevShareConfig: &revsharetypes.UnconditionalRevShareConfig{ + Configs: []revsharetypes.UnconditionalRevShareConfig_RecipientConfig{ + { + Address: constants.Carl_Num0.Owner, + SharePpm: 100_000, + }, + }, + }, + initialMarketMapperRevShareParams: nil, + expectedTakerFeeQuantums: 2000, + expectedMakerFeeQuantums: 550, + expectedAffiliateRevShareQuantums: 300, + expectedUnconditionalRevShareQuantums: 145, + expectedMarketMapperRevShareQuantums: 0, + }, + { + name: "affiliate + market mapper revshare", + initialUserStateStats: nil, + initialUnconditionalRevShareConfig: nil, + initialMarketMapperRevShareParams: &revsharetypes.MarketMapperRevenueShareParams{ + Address: constants.DaveAccAddress.String(), + RevenueSharePpm: 100_000, // 10% + ValidDays: 1, + }, + expectedTakerFeeQuantums: 2000, + expectedMakerFeeQuantums: 550, + expectedAffiliateRevShareQuantums: 300, + expectedUnconditionalRevShareQuantums: 0, + expectedMarketMapperRevShareQuantums: 145, + }, + { + name: "affiliate + market mapper revshare + unconditional revshare", + initialUserStateStats: nil, + initialUnconditionalRevShareConfig: &revsharetypes.UnconditionalRevShareConfig{ + Configs: []revsharetypes.UnconditionalRevShareConfig_RecipientConfig{ + { + Address: constants.Carl_Num0.Owner, + SharePpm: 100_000, // 10% + }, + }, + }, + initialMarketMapperRevShareParams: &revsharetypes.MarketMapperRevenueShareParams{ + Address: constants.DaveAccAddress.String(), + RevenueSharePpm: 100_000, // 10% + ValidDays: 1, + }, + expectedTakerFeeQuantums: 2000, + expectedMakerFeeQuantums: 550, + expectedAffiliateRevShareQuantums: 300, + expectedUnconditionalRevShareQuantums: 145, + expectedMarketMapperRevShareQuantums: 145, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Setup + tApp, ctx, msgSender := setupTest(t, tc.initialUserStateStats, + tc.initialUnconditionalRevShareConfig, tc.initialMarketMapperRevShareParams) + + bankKeeper := tApp.App.BankKeeper + carlBankBalance := bankKeeper.GetBalance(ctx, constants.CarlAccAddress, assettypes.AssetUsdc.GetDenom()) + aliceBankBalance := bankKeeper.GetBalance(ctx, constants.AliceAccAddress, assettypes.AssetUsdc.GetDenom()) + daveBankBalance := bankKeeper.GetBalance(ctx, constants.DaveAccAddress, assettypes.AssetUsdc.GetDenom()) + // Setup orders + Clob_0, aliceOrder, bobOrder, aliceCheckTx, bobCheckTx, orders := setupOrders(ctx, tApp) + + // Get expected onchain messages + expectedOnchainMessagesInNextBlock := getExpectedOnchainMessagesInNextBlock( + ctx, + Clob_0, + aliceOrder, + bobOrder, + aliceCheckTx.Tx, + bobCheckTx.Tx, + big.NewInt(100000000005000000-tc.expectedTakerFeeQuantums), + big.NewInt(99999999995000000+tc.expectedMakerFeeQuantums), + tc.expectedTakerFeeQuantums, + tc.expectedMakerFeeQuantums, + tc.expectedAffiliateRevShareQuantums, + 4, + ) + + // Place orders + for _, order := range orders { + for _, checkTx := range testapp.MustMakeCheckTxsWithClobMsg(ctx, tApp.App, order) { + resp := tApp.CheckTx(checkTx) + require.Conditionf(t, resp.IsOK, "Expected CheckTx to succeed. Response: %+v", resp) + } + } + // Clear msgSender and advance to next block + msgSender.Clear() + ctx = tApp.AdvanceToBlock(4, testapp.AdvanceToBlockOptions{}) + + // Check onchain messages + require.ElementsMatch(t, expectedOnchainMessagesInNextBlock, msgSender.GetOnchainMessages()) + + // Check bank balances + carlBankBalanceAfter := bankKeeper.GetBalance(ctx, + constants.CarlAccAddress, + assettypes.AssetUsdc.GetDenom()) + aliceBankBalanceAfter := bankKeeper.GetBalance(ctx, + constants.AliceAccAddress, + assettypes.AssetUsdc.GetDenom()) + daveBankBalanceAfter := bankKeeper.GetBalance(ctx, + constants.DaveAccAddress, + assettypes.AssetUsdc.GetDenom()) + require.Equal(t, carlBankBalance.Add(sdk.NewCoin(assettypes.AssetUsdc.GetDenom(), + math.NewInt(tc.expectedUnconditionalRevShareQuantums))), carlBankBalanceAfter) + require.Equal(t, aliceBankBalance.Add(sdk.NewCoin(assettypes.AssetUsdc.GetDenom(), + math.NewInt(tc.expectedAffiliateRevShareQuantums))), aliceBankBalanceAfter) + require.Equal(t, daveBankBalance.Add(sdk.NewCoin(assettypes.AssetUsdc.GetDenom(), + math.NewInt(tc.expectedMarketMapperRevShareQuantums))), daveBankBalanceAfter) + }) + } +} + +func setupTest(t *testing.T, initialUserStateStats *statstypes.UserStats, + initialUnconditionalRevShareConfig *revsharetypes.UnconditionalRevShareConfig, + initialMarketMapperRevShareParams *revsharetypes.MarketMapperRevenueShareParams) (*testapp.TestApp, + sdk.Context, *msgsender.IndexerMessageSenderInMemoryCollector) { + msgSender := msgsender.NewIndexerMessageSenderInMemoryCollector() + appOpts := map[string]interface{}{ + indexer.MsgSenderInstanceForTest: msgSender, + } + + tApp := testapp.NewTestAppBuilder(t).WithAppOptions(appOpts).WithGenesisDocFn( + func() (genesis cometbfttypes.GenesisDoc) { + genesis = testapp.DefaultGenesis() + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *types.GenesisState) { + genesisState.AffiliateTiers = types.DefaultAffiliateTiers + }, + ) + if initialUserStateStats != nil { + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *statstypes.GenesisState) { + genesisState.AddressToUserStats = []*statstypes.AddressToUserStats{ + { + Address: constants.Bob_Num0.Owner, + UserStats: initialUserStateStats, + }, + } + }, + ) + } + if initialUnconditionalRevShareConfig != nil || initialMarketMapperRevShareParams != nil { + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *revsharetypes.GenesisState) { + if initialUnconditionalRevShareConfig != nil { + genesisState.UnconditionalRevShareConfig = *initialUnconditionalRevShareConfig + } + if initialMarketMapperRevShareParams != nil { + genesisState.Params = *initialMarketMapperRevShareParams + } + }, + ) + } + return genesis + }).Build() + ctx := tApp.InitChain() + + return tApp, ctx, msgSender +} + +func setupOrders(ctx sdk.Context, tApp *testapp.TestApp) (clobtypes.ClobPair, + clobtypes.MsgPlaceOrder, + clobtypes.MsgPlaceOrder, + abcitypes.RequestCheckTx, + abcitypes.RequestCheckTx, + []clobtypes.MsgPlaceOrder) { + Clob_0 := testapp.MustGetClobPairsFromGenesis(testapp.DefaultGenesis())[0] + msgRegisterAffiliate := types.MsgRegisterAffiliate{ + Referee: constants.Bob_Num0.Owner, + Affiliate: constants.Alice_Num0.Owner, + } + + checkTxMsgRegisterAffiliate := testapp.MustMakeCheckTx( + ctx, + tApp.App, + testapp.MustMakeCheckTxOptions{ + AccAddressForSigning: constants.Bob_Num0.Owner, + Gas: constants.TestGasLimit, + FeeAmt: constants.TestFeeCoins_5Cents, + }, + &msgRegisterAffiliate, + ) + tApp.CheckTx(checkTxMsgRegisterAffiliate) + + ctx = tApp.AdvanceToBlock(3, testapp.AdvanceToBlockOptions{}) + + aliceOrder := *clobtypes.NewMsgPlaceOrder(testapp.MustScaleOrder( + clobtypes.Order{ + OrderId: clobtypes.OrderId{SubaccountId: constants.Alice_Num0, ClientId: 0, ClobPairId: 0}, + Side: clobtypes.Order_SIDE_BUY, + Quantums: 500_000_000, + Subticks: 10, + GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 20}, + }, + testapp.DefaultGenesis(), + )) + + bobOrder := *clobtypes.NewMsgPlaceOrder(testapp.MustScaleOrder( + clobtypes.Order{ + OrderId: clobtypes.OrderId{SubaccountId: constants.Bob_Num0, ClientId: 0, ClobPairId: 0}, + Side: clobtypes.Order_SIDE_SELL, + Quantums: 500_000_000, + Subticks: 10, + GoodTilOneof: &clobtypes.Order_GoodTilBlock{GoodTilBlock: 20}, + }, + testapp.DefaultGenesis(), + )) + + aliceCheckTx := testapp.MustMakeCheckTx( + ctx, + tApp.App, + testapp.MustMakeCheckTxOptions{ + AccAddressForSigning: constants.Alice_Num0.Owner, + }, + &aliceOrder, + ) + + bobCheckTx := testapp.MustMakeCheckTx( + ctx, + tApp.App, + testapp.MustMakeCheckTxOptions{ + AccAddressForSigning: constants.Bob_Num0.Owner, + }, + &bobOrder, + ) + + orders := []clobtypes.MsgPlaceOrder{ + aliceOrder, + bobOrder, + } + return Clob_0, aliceOrder, bobOrder, aliceCheckTx, bobCheckTx, orders +} + +func getExpectedOnchainMessagesInNextBlock(ctx sdk.Context, Clob_0 clobtypes.ClobPair, + aliceOrder clobtypes.MsgPlaceOrder, bobOrder clobtypes.MsgPlaceOrder, + aliceCheckTxHash []byte, bobCheckTxHash []byte, expectedAliceAssetQuantums *big.Int, + expectedBobAssetQuantums *big.Int, + expectedTakerFeeQuantums int64, expectedMakerFeeQuantums int64, + expectedAffiliateRevShareQuantums int64, blockHeight uint32) []msgsender.Message { + return []msgsender.Message{indexer_manager.CreateIndexerBlockEventMessage( + &indexer_manager.IndexerTendermintBlock{ + Height: blockHeight, + Time: ctx.BlockTime(), + Events: []*indexer_manager.IndexerTendermintEvent{ + { + Subtype: indexerevents.SubtypeSubaccountUpdate, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_TransactionIndex{}, + EventIndex: 0, + Version: indexerevents.SubaccountUpdateEventVersion, + DataBytes: indexer_manager.GetBytes( + indexerevents.NewSubaccountUpdateEvent( + &constants.Bob_Num0, + []*satypes.PerpetualPosition{ + testutil.CreateSinglePerpetualPosition( + Clob_0.MustGetPerpetualId(), + big.NewInt(-int64( + aliceOrder.Order.GetQuantums())), + big.NewInt(0), + big.NewInt(0), + ), + }, + []*satypes.AssetPosition{ + testutil.CreateSingleAssetPosition( + assettypes.AssetUsdc.Id, + expectedAliceAssetQuantums, + ), + }, + nil, + ), + ), + }, + { + Subtype: indexerevents.SubtypeSubaccountUpdate, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_TransactionIndex{}, + EventIndex: 1, + Version: indexerevents.SubaccountUpdateEventVersion, + DataBytes: indexer_manager.GetBytes( + indexerevents.NewSubaccountUpdateEvent( + &constants.Alice_Num0, + []*satypes.PerpetualPosition{ + testutil.CreateSinglePerpetualPosition( + Clob_0.MustGetPerpetualId(), + big.NewInt(int64( + aliceOrder.Order.GetQuantums())), + big.NewInt(0), + big.NewInt(0), + ), + }, + []*satypes.AssetPosition{ + testutil.CreateSingleAssetPosition( + assettypes.AssetUsdc.Id, + expectedBobAssetQuantums, + ), + }, + nil, + ), + ), + }, + { + Subtype: indexerevents.SubtypeOrderFill, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_TransactionIndex{}, + EventIndex: 2, + Version: indexerevents.OrderFillEventVersion, + DataBytes: indexer_manager.GetBytes( + indexerevents.NewOrderFillEvent( + aliceOrder.Order, + bobOrder.Order, + aliceOrder.Order.GetBaseQuantums(), + -expectedMakerFeeQuantums, + expectedTakerFeeQuantums, + aliceOrder.Order.GetBaseQuantums(), + aliceOrder.Order.GetBaseQuantums(), + big.NewInt(expectedAffiliateRevShareQuantums), + ), + ), + }, + { + Subtype: indexerevents.SubtypeOpenInterestUpdate, + OrderingWithinBlock: &indexer_manager.IndexerTendermintEvent_BlockEvent_{ + BlockEvent: indexer_manager.IndexerTendermintEvent_BLOCK_EVENT_END_BLOCK, + }, + Version: indexerevents.OpenInterestUpdateVersion, + DataBytes: indexer_manager.GetBytes( + &indexerevents.OpenInterestUpdateEventV1{ + OpenInterestUpdates: []*indexerevents.OpenInterestUpdate{ + { + PerpetualId: Clob_0.MustGetPerpetualId(), + OpenInterest: dtypes.NewIntFromUint64( + aliceOrder.Order.GetBigQuantums().Uint64(), + ), + }, + }, + }), + }, + }, + TxHashes: []string{string(lib.GetTxHash(testtx.MustGetTxBytes(&clobtypes.MsgProposedOperations{ + OperationsQueue: []clobtypes.OperationRaw{ + { + Operation: &clobtypes.OperationRaw_ShortTermOrderPlacement{ + ShortTermOrderPlacement: aliceCheckTxHash, + }, + }, + { + Operation: &clobtypes.OperationRaw_ShortTermOrderPlacement{ + ShortTermOrderPlacement: bobCheckTxHash, + }, + }, + clobtestutils.NewMatchOperationRaw( + &bobOrder.Order, + []clobtypes.MakerFill{ + { + FillAmount: aliceOrder. + Order.GetBaseQuantums().ToUint64(), + MakerOrderId: aliceOrder.Order.OrderId, + }, + }, + ), + }, + }, + )))}, + })} +} diff --git a/protocol/x/revshare/genesis.go b/protocol/x/revshare/genesis.go index 279196737b..def6b761ca 100644 --- a/protocol/x/revshare/genesis.go +++ b/protocol/x/revshare/genesis.go @@ -13,10 +13,18 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) if err := k.SetMarketMapperRevenueShareParams(ctx, genState.Params); err != nil { panic(err) } + + k.SetUnconditionalRevShareConfigParams(ctx, genState.UnconditionalRevShareConfig) } // ExportGenesis returns the module's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis := types.DefaultGenesis() + genesis.Params = k.GetMarketMapperRevenueShareParams(ctx) + unconditionalRevShareConfig, err := k.GetUnconditionalRevShareConfigParams(ctx) + if err != nil { + panic(err) + } + genesis.UnconditionalRevShareConfig = unconditionalRevShareConfig return genesis } diff --git a/protocol/x/revshare/types/genesis.go b/protocol/x/revshare/types/genesis.go index fa21b9ab96..dd24a7d512 100644 --- a/protocol/x/revshare/types/genesis.go +++ b/protocol/x/revshare/types/genesis.go @@ -4,6 +4,9 @@ package types func DefaultGenesis() *GenesisState { return &GenesisState{ Params: DefaultParams(), + UnconditionalRevShareConfig: UnconditionalRevShareConfig{ + Configs: []UnconditionalRevShareConfig_RecipientConfig{}, + }, } } diff --git a/protocol/x/revshare/types/genesis.pb.go b/protocol/x/revshare/types/genesis.pb.go index 2c8f235ebd..9e2b956d85 100644 --- a/protocol/x/revshare/types/genesis.pb.go +++ b/protocol/x/revshare/types/genesis.pb.go @@ -25,7 +25,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines `x/revshare`'s genesis state. type GenesisState struct { + // params is the market mapper revenue share params. Params MarketMapperRevenueShareParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // unconditional_rev_share_config is the unconditional rev share config. + UnconditionalRevShareConfig UnconditionalRevShareConfig `protobuf:"bytes,2,opt,name=unconditional_rev_share_config,json=unconditionalRevShareConfig,proto3" json:"unconditional_rev_share_config"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -68,6 +71,13 @@ func (m *GenesisState) GetParams() MarketMapperRevenueShareParams { return MarketMapperRevenueShareParams{} } +func (m *GenesisState) GetUnconditionalRevShareConfig() UnconditionalRevShareConfig { + if m != nil { + return m.UnconditionalRevShareConfig + } + return UnconditionalRevShareConfig{} +} + func init() { proto.RegisterType((*GenesisState)(nil), "dydxprotocol.revshare.GenesisState") } @@ -77,21 +87,25 @@ func init() { } var fileDescriptor_f930be52e9995581 = []byte{ - // 221 bytes of a gzipped FileDescriptorProto + // 286 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4e, 0xa9, 0x4c, 0xa9, 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x2f, 0x4a, 0x2d, 0x2b, 0xce, 0x48, 0x2c, 0x4a, 0xd5, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x03, 0xcb, 0x08, 0x89, 0x22, 0x2b, 0xd2, 0x83, 0x29, 0x92, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x0b, 0xeb, 0x83, 0x58, 0x10, 0xc5, - 0x52, 0x4a, 0xd8, 0x4d, 0x2c, 0x48, 0x2c, 0x4a, 0xcc, 0x85, 0x1a, 0xa8, 0x94, 0xcc, 0xc5, 0xe3, - 0x0e, 0xb1, 0x21, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0x28, 0x98, 0x8b, 0x0d, 0x22, 0x2f, 0xc1, 0xa8, - 0xc0, 0xa8, 0xc1, 0x6d, 0x64, 0xaa, 0x87, 0xd5, 0x46, 0x3d, 0xdf, 0xc4, 0xa2, 0xec, 0xd4, 0x12, - 0xdf, 0xc4, 0x82, 0x82, 0xd4, 0xa2, 0xa0, 0xd4, 0xb2, 0xd4, 0xbc, 0xd2, 0xd4, 0x60, 0x90, 0x44, - 0x00, 0x58, 0xb3, 0x13, 0xcb, 0x89, 0x7b, 0xf2, 0x0c, 0x41, 0x50, 0xa3, 0x9c, 0x42, 0x4e, 0x3c, - 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, - 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x2a, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, - 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xc5, 0xb5, 0x65, 0x26, 0xba, 0xc9, 0x19, 0x89, 0x99, 0x79, 0xfa, - 0x70, 0x91, 0x0a, 0x84, 0x0f, 0x4a, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x52, 0xc6, 0x80, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x3b, 0x5c, 0x0c, 0x39, 0x01, 0x00, 0x00, + 0x52, 0x4a, 0xd8, 0x4d, 0x2c, 0x48, 0x2c, 0x4a, 0xcc, 0x85, 0x1a, 0x28, 0xa5, 0x82, 0x5d, 0x0d, + 0x8c, 0x01, 0x51, 0xa5, 0xf4, 0x88, 0x91, 0x8b, 0xc7, 0x1d, 0xe2, 0x90, 0xe0, 0x92, 0xc4, 0x92, + 0x54, 0xa1, 0x60, 0x2e, 0x36, 0x88, 0x31, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0xa6, 0x7a, + 0x58, 0x1d, 0xa6, 0xe7, 0x9b, 0x58, 0x94, 0x9d, 0x5a, 0xe2, 0x9b, 0x58, 0x50, 0x90, 0x5a, 0x14, + 0x94, 0x5a, 0x96, 0x9a, 0x57, 0x9a, 0x1a, 0x0c, 0x92, 0x08, 0x00, 0x6b, 0x76, 0x62, 0x39, 0x71, + 0x4f, 0x9e, 0x21, 0x08, 0x6a, 0x94, 0x50, 0x2d, 0x97, 0x5c, 0x69, 0x5e, 0x72, 0x7e, 0x5e, 0x4a, + 0x66, 0x49, 0x66, 0x7e, 0x5e, 0x62, 0x4e, 0x7c, 0x51, 0x6a, 0x59, 0x3c, 0xd8, 0x9c, 0xf8, 0xe4, + 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x09, 0x26, 0xb0, 0x65, 0x46, 0x38, 0x2c, 0x0b, 0x45, 0xd6, 0x1c, + 0x94, 0x5a, 0x06, 0xb6, 0xc9, 0x19, 0xac, 0x13, 0x6a, 0x93, 0x74, 0x29, 0x1e, 0x25, 0x21, 0x27, + 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, + 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, 0x95, 0x9e, 0x59, 0x92, 0x51, 0x9a, + 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x8f, 0x12, 0x5e, 0x65, 0x26, 0xba, 0xc9, 0x19, 0x89, 0x99, 0x79, + 0xfa, 0x70, 0x91, 0x0a, 0x44, 0x18, 0x96, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0xa5, 0x8c, + 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xca, 0x2f, 0xf5, 0xdf, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -114,6 +128,16 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.UnconditionalRevShareConfig.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -146,6 +170,8 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) + l = m.UnconditionalRevShareConfig.Size() + n += 1 + l + sovGenesis(uint64(l)) return n } @@ -217,6 +243,39 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnconditionalRevShareConfig", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.UnconditionalRevShareConfig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/protocol/x/stats/genesis.go b/protocol/x/stats/genesis.go index 1aefb0f63a..a39370daf9 100644 --- a/protocol/x/stats/genesis.go +++ b/protocol/x/stats/genesis.go @@ -13,6 +13,10 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) if err := k.SetParams(ctx, genState.Params); err != nil { panic(err) } + + for _, addressToUserStats := range genState.AddressToUserStats { + k.SetUserStats(ctx, addressToUserStats.Address, addressToUserStats.UserStats) + } } // ExportGenesis returns the stat module's exported genesis. diff --git a/protocol/x/stats/types/genesis.go b/protocol/x/stats/types/genesis.go index 4ddeccac88..15c559cc73 100644 --- a/protocol/x/stats/types/genesis.go +++ b/protocol/x/stats/types/genesis.go @@ -8,6 +8,7 @@ func DefaultGenesis() *GenesisState { Params: Params{ WindowDuration: time.Duration(30 * 24 * time.Hour), }, + AddressToUserStats: []*AddressToUserStats{}, } } diff --git a/protocol/x/stats/types/genesis.pb.go b/protocol/x/stats/types/genesis.pb.go index 8a84887ab6..606b25cec7 100644 --- a/protocol/x/stats/types/genesis.pb.go +++ b/protocol/x/stats/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -26,7 +27,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the stats module's genesis state. type GenesisState struct { // The parameters of the module. - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + AddressToUserStats []*AddressToUserStats `protobuf:"bytes,2,rep,name=address_to_user_stats,json=addressToUserStats,proto3" json:"address_to_user_stats,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -69,27 +71,98 @@ func (m *GenesisState) GetParams() Params { return Params{} } +func (m *GenesisState) GetAddressToUserStats() []*AddressToUserStats { + if m != nil { + return m.AddressToUserStats + } + return nil +} + +// AddressToUserStats is a struct that contains the user stats for an address. +type AddressToUserStats struct { + // The address of the user. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // The user stats for the address. + UserStats *UserStats `protobuf:"bytes,2,opt,name=user_stats,json=userStats,proto3" json:"user_stats,omitempty"` +} + +func (m *AddressToUserStats) Reset() { *m = AddressToUserStats{} } +func (m *AddressToUserStats) String() string { return proto.CompactTextString(m) } +func (*AddressToUserStats) ProtoMessage() {} +func (*AddressToUserStats) Descriptor() ([]byte, []int) { + return fileDescriptor_8b31bfab9064c65e, []int{1} +} +func (m *AddressToUserStats) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddressToUserStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddressToUserStats.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AddressToUserStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddressToUserStats.Merge(m, src) +} +func (m *AddressToUserStats) XXX_Size() int { + return m.Size() +} +func (m *AddressToUserStats) XXX_DiscardUnknown() { + xxx_messageInfo_AddressToUserStats.DiscardUnknown(m) +} + +var xxx_messageInfo_AddressToUserStats proto.InternalMessageInfo + +func (m *AddressToUserStats) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *AddressToUserStats) GetUserStats() *UserStats { + if m != nil { + return m.UserStats + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "dydxprotocol.stats.GenesisState") + proto.RegisterType((*AddressToUserStats)(nil), "dydxprotocol.stats.AddressToUserStats") } func init() { proto.RegisterFile("dydxprotocol/stats/genesis.proto", fileDescriptor_8b31bfab9064c65e) } var fileDescriptor_8b31bfab9064c65e = []byte{ - // 196 bytes of a gzipped FileDescriptorProto + // 321 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0xa9, 0x4c, 0xa9, 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x2f, 0x2e, 0x49, 0x2c, 0x29, 0xd6, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x03, 0x0b, 0x0b, 0x09, 0x21, 0xab, 0xd0, 0x03, 0xab, - 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x8b, 0xe9, 0x83, 0x58, 0x10, 0x95, 0x52, 0xf2, 0x58, - 0xcc, 0x2a, 0x48, 0x2c, 0x4a, 0xcc, 0x85, 0x1a, 0xa5, 0xe4, 0xc1, 0xc5, 0xe3, 0x0e, 0x31, 0x3b, - 0xb8, 0x24, 0xb1, 0x24, 0x55, 0xc8, 0x82, 0x8b, 0x0d, 0x22, 0x2f, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, - 0x6d, 0x24, 0xa5, 0x87, 0x69, 0x97, 0x5e, 0x00, 0x58, 0x85, 0x13, 0xcb, 0x89, 0x7b, 0xf2, 0x0c, - 0x41, 0x50, 0xf5, 0x4e, 0x81, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, - 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, - 0x9e, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x8f, 0xe2, 0x9e, 0x32, 0x13, - 0xdd, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, 0x7d, 0xb8, 0x48, 0x05, 0xd4, 0x8d, 0x25, 0x95, 0x05, 0xa9, - 0xc5, 0x49, 0x6c, 0x60, 0x71, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0x2c, 0x96, 0x10, - 0x12, 0x01, 0x00, 0x00, + 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x8b, 0xe9, 0x83, 0x58, 0x10, 0x95, 0x52, 0x92, 0xc9, + 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0x10, 0x09, 0x08, 0x07, 0x2a, 0x25, 0x8f, 0xc5, 0x9a, 0x82, + 0xc4, 0xa2, 0xc4, 0x5c, 0x98, 0x02, 0x39, 0x2c, 0x0a, 0xc0, 0x24, 0x44, 0x5e, 0x69, 0x31, 0x23, + 0x17, 0x8f, 0x3b, 0xc4, 0x5d, 0xc1, 0x25, 0x89, 0x25, 0xa9, 0x42, 0x16, 0x5c, 0x6c, 0x10, 0x03, + 0x24, 0x18, 0x15, 0x18, 0x35, 0xb8, 0x8d, 0xa4, 0xf4, 0x30, 0xdd, 0xa9, 0x17, 0x00, 0x56, 0xe1, + 0xc4, 0x72, 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x54, 0xbd, 0x50, 0x24, 0x97, 0x68, 0x62, 0x4a, 0x4a, + 0x51, 0x6a, 0x71, 0x71, 0x7c, 0x49, 0x7e, 0x7c, 0x69, 0x71, 0x6a, 0x51, 0x3c, 0x58, 0xb5, 0x04, + 0x93, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x1a, 0x36, 0x83, 0x1c, 0x21, 0x1a, 0x42, 0xf2, 0x43, 0x8b, + 0x53, 0x8b, 0x40, 0x0e, 0x28, 0x0e, 0x12, 0x4a, 0xc4, 0x10, 0x53, 0x6a, 0x63, 0xe4, 0x12, 0xc2, + 0x54, 0x2a, 0x64, 0xc4, 0xc5, 0x0e, 0x55, 0x0c, 0x76, 0x2c, 0xa7, 0x93, 0xc4, 0xa5, 0x2d, 0xba, + 0x22, 0xd0, 0x00, 0x82, 0xaa, 0x0f, 0x2e, 0x29, 0xca, 0xcc, 0x4b, 0x0f, 0x82, 0x29, 0x14, 0xb2, + 0xe1, 0xe2, 0x42, 0x71, 0x1a, 0xc8, 0x8f, 0xb2, 0xd8, 0x9c, 0x86, 0x70, 0x11, 0x67, 0x29, 0x8c, + 0xe9, 0x14, 0x78, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, + 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xe6, 0xe9, 0x99, + 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x28, 0x61, 0x5e, 0x66, 0xa2, 0x9b, 0x9c, + 0x91, 0x98, 0x99, 0xa7, 0x0f, 0x17, 0xa9, 0x80, 0xc6, 0x43, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, + 0x1b, 0x58, 0xdc, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x27, 0x12, 0xbe, 0xa0, 0x32, 0x02, 0x00, + 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -112,6 +185,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.AddressToUserStats) > 0 { + for iNdEx := len(m.AddressToUserStats) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AddressToUserStats[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -125,6 +212,48 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *AddressToUserStats) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddressToUserStats) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddressToUserStats) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UserStats != nil { + { + size, err := m.UserStats.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -144,6 +273,29 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) + if len(m.AddressToUserStats) > 0 { + for _, e := range m.AddressToUserStats { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *AddressToUserStats) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.UserStats != nil { + l = m.UserStats.Size() + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -215,6 +367,158 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AddressToUserStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AddressToUserStats = append(m.AddressToUserStats, &AddressToUserStats{}) + if err := m.AddressToUserStats[len(m.AddressToUserStats)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddressToUserStats) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddressToUserStats: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddressToUserStats: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UserStats == nil { + m.UserStats = &UserStats{} + } + if err := m.UserStats.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) From 14ed93f0bdf225d31017447d1abebc9ba43ebb6f Mon Sep 17 00:00:00 2001 From: affan Date: Wed, 18 Sep 2024 10:07:57 -0400 Subject: [PATCH 2/3] fix test --- proto/dydxprotocol/revshare/genesis.proto | 3 ++- protocol/x/stats/genesis.go | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/proto/dydxprotocol/revshare/genesis.proto b/proto/dydxprotocol/revshare/genesis.proto index be2c077f67..e0d21891db 100644 --- a/proto/dydxprotocol/revshare/genesis.proto +++ b/proto/dydxprotocol/revshare/genesis.proto @@ -12,5 +12,6 @@ message GenesisState { // params is the market mapper revenue share params. MarketMapperRevenueShareParams params = 1 [ (gogoproto.nullable) = false ]; // unconditional_rev_share_config is the unconditional rev share config. - UnconditionalRevShareConfig unconditional_rev_share_config = 2 [ (gogoproto.nullable) = false ]; + UnconditionalRevShareConfig unconditional_rev_share_config = 2 + [ (gogoproto.nullable) = false ]; } \ No newline at end of file diff --git a/protocol/x/stats/genesis.go b/protocol/x/stats/genesis.go index a39370daf9..de7a8197b6 100644 --- a/protocol/x/stats/genesis.go +++ b/protocol/x/stats/genesis.go @@ -21,7 +21,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) // ExportGenesis returns the stat module's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - return &types.GenesisState{ - Params: k.GetParams(ctx), - } + genesis := types.DefaultGenesis() + genesis.Params = k.GetParams(ctx) + return genesis } From 5d531861194b8f4573adca9702046648476d75ba Mon Sep 17 00:00:00 2001 From: affan Date: Wed, 25 Sep 2024 17:25:26 -0400 Subject: [PATCH 3/3] update e2e tests with new logic --- .../x/revshare/e2e/revshare_place_order_test.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/protocol/x/revshare/e2e/revshare_place_order_test.go b/protocol/x/revshare/e2e/revshare_place_order_test.go index ee7567f875..a4c56690cb 100644 --- a/protocol/x/revshare/e2e/revshare_place_order_test.go +++ b/protocol/x/revshare/e2e/revshare_place_order_test.go @@ -49,15 +49,16 @@ func TestPlaceOrderWithAffiliate(t *testing.T) { initialMarketMapperRevShareParams: nil, expectedTakerFeeQuantums: 2000, expectedMakerFeeQuantums: 550, - expectedAffiliateRevShareQuantums: 300, + expectedAffiliateRevShareQuantums: 300, // 15% of 2000 expectedUnconditionalRevShareQuantums: 0, expectedMarketMapperRevShareQuantums: 0, }, { name: "Affiliate over limit", initialUserStateStats: &statstypes.UserStats{ - TakerNotional: uint64(35_000_000_000_000), - MakerNotional: uint64(35_000_000_000_000), + // cap is 50 million + TakerNotional: uint64(60_000_000_000_000), + MakerNotional: uint64(60_000_000_000_000), }, initialUnconditionalRevShareConfig: nil, initialMarketMapperRevShareParams: nil, @@ -82,7 +83,7 @@ func TestPlaceOrderWithAffiliate(t *testing.T) { expectedTakerFeeQuantums: 2000, expectedMakerFeeQuantums: 550, expectedAffiliateRevShareQuantums: 300, - expectedUnconditionalRevShareQuantums: 145, + expectedUnconditionalRevShareQuantums: 115, // 10% of(2000 - 550 - 300) expectedMarketMapperRevShareQuantums: 0, }, { @@ -98,7 +99,7 @@ func TestPlaceOrderWithAffiliate(t *testing.T) { expectedMakerFeeQuantums: 550, expectedAffiliateRevShareQuantums: 300, expectedUnconditionalRevShareQuantums: 0, - expectedMarketMapperRevShareQuantums: 145, + expectedMarketMapperRevShareQuantums: 115, // 10% of (2000 - 550 - 300) }, { name: "affiliate + market mapper revshare + unconditional revshare", @@ -119,8 +120,8 @@ func TestPlaceOrderWithAffiliate(t *testing.T) { expectedTakerFeeQuantums: 2000, expectedMakerFeeQuantums: 550, expectedAffiliateRevShareQuantums: 300, - expectedUnconditionalRevShareQuantums: 145, - expectedMarketMapperRevShareQuantums: 145, + expectedUnconditionalRevShareQuantums: 115, // 10% of (2000 - 550 - 300) + expectedMarketMapperRevShareQuantums: 115, // 10% of (2000 - 550 - 300) }, }