diff --git a/proto/sge/reward/ticket.proto b/proto/sge/reward/ticket.proto index a8b07d5f..90654c27 100644 --- a/proto/sge/reward/ticket.proto +++ b/proto/sge/reward/ticket.proto @@ -82,5 +82,16 @@ message RewardPayloadCommon { // GrantSignupRewardPayload is the type for signup reward grant payload. message GrantSignupRewardPayload { // common is the common properties of a reward - RewardPayloadCommon common = 2 [ (gogoproto.nullable) = false ]; + RewardPayloadCommon common = 1 [ (gogoproto.nullable) = false ]; } + +// GrantSignupReferrerRewardPayload is the type for signup referrer reward grant +// payload. +message GrantSignupReferrerRewardPayload { + // common is the common properties of a reward + RewardPayloadCommon common = 1 [ (gogoproto.nullable) = false ]; + + // referee is the address of the account that used this referrer address as + // source_uid + string referee = 2; +} \ No newline at end of file diff --git a/x/reward/keeper/msg_server_reward.go b/x/reward/keeper/msg_server_reward.go index 109164ac..fe65c48c 100644 --- a/x/reward/keeper/msg_server_reward.go +++ b/x/reward/keeper/msg_server_reward.go @@ -36,17 +36,19 @@ func (k msgServer) GrantReward(goCtx context.Context, msg *types.MsgGrantReward) return nil, sdkerrors.Wrap(sdkerrtypes.ErrInvalidRequest, "failed to retrieve reward factory") } - receiver, rewardCommon, err := rewardFactory.Calculate(goCtx, ctx, + factData, err := rewardFactory.Calculate(goCtx, ctx, types.RewardFactoryKeepers{ OVMKeeper: k.ovmKeeper, BetKeeper: k.betKeeper, SubAccountKeeper: k.subaccountKeeper, + RewardKeeper: k.Keeper, + AccountKeeper: k.accountKeeper, }, campaign, msg.Ticket, msg.Creator) if err != nil { return nil, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidRequest, "distribution calculation failed %s", err) } - rewards, err := k.GetRewardsByAddressAndCategory(ctx, receiver.MainAccountAddr, campaign.RewardCategory) + rewards, err := k.GetRewardsByAddressAndCategory(ctx, factData.Receiver.MainAccountAddr, campaign.RewardCategory) if err != nil { return nil, sdkerrors.Wrap(sdkerrtypes.ErrInvalidRequest, "failed to retrieve rewards for user.") } @@ -54,25 +56,25 @@ func (k msgServer) GrantReward(goCtx context.Context, msg *types.MsgGrantReward) return nil, sdkerrors.Wrap(sdkerrtypes.ErrInvalidRequest, "maximum rewards claimed for the given category.") } - if err := campaign.CheckPoolBalance(receiver.SubAccountAmount.Add(receiver.MainAccountAmount)); err != nil { + if err := campaign.CheckPoolBalance(factData.Receiver.SubAccountAmount.Add(factData.Receiver.MainAccountAmount)); err != nil { return nil, types.ErrInsufficientPoolBalance } - if err := k.DistributeRewards(ctx, receiver); err != nil { + if err := k.DistributeRewards(ctx, factData.Receiver); err != nil { return nil, sdkerrors.Wrapf(types.ErrInDistributionOfRewards, "%s", err) } - k.UpdateCampaignPool(ctx, campaign, receiver) + k.UpdateCampaignPool(ctx, campaign, factData.Receiver) k.SetReward(ctx, types.NewReward( - msg.Uid, msg.Creator, receiver.MainAccountAddr, + msg.Uid, msg.Creator, factData.Receiver.MainAccountAddr, msg.CampaignUid, campaign.RewardAmount, - rewardCommon.SourceUID, - rewardCommon.Meta, + factData.Common.SourceUID, + factData.Common.Meta, )) - k.SetRewardByReceiver(ctx, types.NewRewardByCategory(msg.Uid, receiver.MainAccountAddr, campaign.RewardCategory)) + k.SetRewardByReceiver(ctx, types.NewRewardByCategory(msg.Uid, factData.Receiver.MainAccountAddr, campaign.RewardCategory)) k.SetRewardByCampaign(ctx, types.NewRewardByCampaign(msg.Uid, campaign.UID)) - msg.EmitEvent(&ctx, msg.CampaignUid, msg.Uid, campaign.Promoter, *campaign.RewardAmount, receiver) + msg.EmitEvent(&ctx, msg.CampaignUid, msg.Uid, campaign.Promoter, *campaign.RewardAmount, factData.Receiver) return &types.MsgGrantRewardResponse{}, nil } diff --git a/x/reward/keeper/msg_server_reward_test.go b/x/reward/keeper/msg_server_reward_test.go index e83362a1..edabd8ef 100644 --- a/x/reward/keeper/msg_server_reward_test.go +++ b/x/reward/keeper/msg_server_reward_test.go @@ -26,7 +26,7 @@ func getDefaultClaim(creator string) jwt.MapClaims { "promoter": creator, "start_ts": time.Now().Unix(), "end_ts": time.Now().Add(5 * time.Minute).Unix(), - "category": types.RewardType_REWARD_TYPE_SIGNUP, + "category": types.RewardCategory_REWARD_CATEGORY_SIGNUP, "claims_per_category": 1, "is_active": true, "meta": "sample campaign", @@ -34,13 +34,13 @@ func getDefaultClaim(creator string) jwt.MapClaims { } func createCampaign(t *testing.T, k *keeper.Keeper, srv types.MsgServer, ctx sdk.Context, - funder string, claims jwt.MapClaims, + promoter string, claims jwt.MapClaims, ) string { ticket, err := simapp.CreateJwtTicket(claims) require.Nil(t, err) expected := &types.MsgCreateCampaign{ - Creator: funder, + Creator: promoter, Uid: uuid.NewString(), Ticket: ticket, TotalFunds: sdkmath.NewInt(1000000), @@ -61,7 +61,7 @@ func TestMsgApplySignupReward(t *testing.T) { ctx = ctx.WithBlockTime(time.Now()) wctx := sdk.WrapSDKContext(ctx) - funder := simapp.TestParamUsers["user1"].Address.String() + promoter := simapp.TestParamUsers["user1"].Address.String() receiverAddr := simapp.TestParamUsers["user2"].Address.String() _, err := tApp.SubaccountKeeper.CreateSubAccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{ @@ -72,7 +72,7 @@ func TestMsgApplySignupReward(t *testing.T) { }) require.NoError(t, err) - campClaims := getDefaultClaim(funder) + campClaims := getDefaultClaim(promoter) campClaims["reward_type"] = types.RewardType_REWARD_TYPE_SIGNUP campClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED campClaims["reward_amount"] = types.RewardAmount{ @@ -80,7 +80,7 @@ func TestMsgApplySignupReward(t *testing.T) { UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), } - campUID := createCampaign(t, k, srv, ctx, funder, campClaims) + campUID := createCampaign(t, k, srv, ctx, promoter, campClaims) for _, tc := range []struct { desc string @@ -103,7 +103,95 @@ func TestMsgApplySignupReward(t *testing.T) { "iat": time.Now().Unix(), "common": types.RewardPayloadCommon{ Receiver: receiverAddr, - SourceUID: "source id", + SourceUID: "", + Meta: "signup reward for example user", + }, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ticket, err := simapp.CreateJwtTicket(tc.claims) + require.Nil(t, err) + reward := &types.MsgGrantReward{ + Uid: uuid.NewString(), + Creator: promoter, + CampaignUid: campUID, + Ticket: ticket, + } + _, err = srv.GrantReward(wctx, reward) + if tc.err != nil { + require.ErrorContains(t, err, tc.err.Error()) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgApplySignupRefereeReward(t *testing.T) { + tApp, k, ctx := setupKeeperAndApp(t) + srv := keeper.NewMsgServerImpl(*k) + ctx = ctx.WithBlockTime(time.Now()) + wctx := sdk.WrapSDKContext(ctx) + + promoter := simapp.TestParamUsers["user1"].Address.String() + receiverAddr := simapp.TestParamUsers["user2"].Address.String() + + referrer := simapp.TestParamUsers["user3"].Address.String() + + _, err := tApp.SubaccountKeeper.CreateSubAccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{ + { + Amount: sdk.ZeroInt(), + UnlockTS: uint64(ctx.BlockTime().Add(60 * time.Minute).Unix()), + }, + }) + require.NoError(t, err) + + campClaims := getDefaultClaim(promoter) + campClaims["reward_type"] = types.RewardType_REWARD_TYPE_REFERRAL_SIGNUP + campClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED + campClaims["reward_amount"] = types.RewardAmount{ + SubaccountAmount: sdkmath.NewInt(100), + UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), + } + + campUID := createCampaign(t, k, srv, ctx, promoter, campClaims) + + for _, tc := range []struct { + desc string + claims jwt.MapClaims + err error + }{ + { + desc: "invalid ticket", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": "invalid", + }, + err: types.ErrInTicketVerification, + }, + { + desc: "invalid referrer", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": types.RewardPayloadCommon{ + Receiver: receiverAddr, + SourceUID: "", + Meta: "signup reward for example user", + }, + }, + err: sdkerrtypes.ErrInvalidRequest, + }, + { + desc: "valid", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": types.RewardPayloadCommon{ + Receiver: receiverAddr, + SourceUID: referrer, Meta: "signup reward for example user", }, }, @@ -114,7 +202,7 @@ func TestMsgApplySignupReward(t *testing.T) { require.Nil(t, err) reward := &types.MsgGrantReward{ Uid: uuid.NewString(), - Creator: funder, + Creator: promoter, CampaignUid: campUID, Ticket: ticket, } @@ -128,16 +216,148 @@ func TestMsgApplySignupReward(t *testing.T) { } } +func TestMsgApplySignupReferrerReward(t *testing.T) { + tApp, k, ctx := setupKeeperAndApp(t) + srv := keeper.NewMsgServerImpl(*k) + ctx = ctx.WithBlockTime(time.Now()) + wctx := sdk.WrapSDKContext(ctx) + + promoter := simapp.TestParamUsers["user1"].Address.String() + receiverAddr := simapp.TestParamUsers["user2"].Address.String() + + referee := simapp.TestParamUsers["user3"].Address.String() + referrer := simapp.TestParamUsers["user4"].Address.String() + + _, err := tApp.SubaccountKeeper.CreateSubAccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{ + { + Amount: sdk.ZeroInt(), + UnlockTS: uint64(ctx.BlockTime().Add(60 * time.Minute).Unix()), + }, + }) + require.NoError(t, err) + + // referral signup campaign + referralSignupCampClaims := getDefaultClaim(promoter) + referralSignupCampClaims["reward_type"] = types.RewardType_REWARD_TYPE_REFERRAL_SIGNUP + referralSignupCampClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED + referralSignupCampClaims["reward_amount"] = types.RewardAmount{ + SubaccountAmount: sdkmath.NewInt(100), + UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), + } + referralSignupCampUID := createCampaign(t, k, srv, ctx, promoter, referralSignupCampClaims) + + // referral campaign + referralCampClaims := getDefaultClaim(promoter) + referralCampClaims["category"] = types.RewardCategory_REWARD_CATEGORY_REFERRAL + referralCampClaims["reward_type"] = types.RewardType_REWARD_TYPE_REFERRAL + referralCampClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED + referralCampClaims["reward_amount"] = types.RewardAmount{ + SubaccountAmount: sdkmath.NewInt(100), + UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), + } + referralCampUID := createCampaign(t, k, srv, ctx, promoter, referralCampClaims) + + refereeClaims := jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": types.RewardPayloadCommon{ + Receiver: referee, + SourceUID: referrer, + Meta: "signup reward for example user", + }, + } + refereeTicket, err := simapp.CreateJwtTicket(refereeClaims) + require.Nil(t, err) + reward := &types.MsgGrantReward{ + Uid: uuid.NewString(), + Creator: promoter, + CampaignUid: referralSignupCampUID, + Ticket: refereeTicket, + } + _, err = srv.GrantReward(wctx, reward) + require.NoError(t, err) + + rewardGrant, err := k.GetRewardsByAddressAndCategory(ctx, referee, types.RewardCategory_REWARD_CATEGORY_SIGNUP) + require.NoError(t, err) + require.Equal(t, types.RewardByCategory{ + UID: reward.Uid, + Addr: referee, + RewardCategory: types.RewardCategory_REWARD_CATEGORY_SIGNUP, + }, rewardGrant[0]) + + require.True(t, k.HasRewardByReceiver(ctx, referee, types.RewardCategory_REWARD_CATEGORY_SIGNUP)) + + for _, tc := range []struct { + desc string + claims jwt.MapClaims + err error + }{ + { + desc: "invalid ticket", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": "invalid", + }, + err: types.ErrInTicketVerification, + }, + { + desc: "invalid referrer", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": types.RewardPayloadCommon{ + Receiver: receiverAddr, + SourceUID: "", + Meta: "signup reward for example user", + }, + "referee": "invalid", + }, + err: sdkerrtypes.ErrInvalidRequest, + }, + { + desc: "valid", + claims: jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "common": types.RewardPayloadCommon{ + Receiver: receiverAddr, + SourceUID: "", + Meta: "signup reward for example user", + }, + "referee": referee, + }, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + ticket, err := simapp.CreateJwtTicket(tc.claims) + require.Nil(t, err) + reward := &types.MsgGrantReward{ + Uid: uuid.NewString(), + Creator: promoter, + CampaignUid: referralCampUID, + Ticket: ticket, + } + _, err = srv.GrantReward(wctx, reward) + if tc.err != nil { + require.ErrorContains(t, err, tc.err.Error()) + } else { + require.NoError(t, err) + } + }) + } +} + func TestMsgApplySignupRewardSubAcc(t *testing.T) { tApp, k, ctx := setupKeeperAndApp(t) srv := keeper.NewMsgServerImpl(*k) ctx = ctx.WithBlockTime(time.Now()) wctx := sdk.WrapSDKContext(ctx) - funder := simapp.TestParamUsers["user1"].Address.String() + promoter := simapp.TestParamUsers["user1"].Address.String() receiverAddr := simapp.TestParamUsers["user2"].Address.String() - campClaims := getDefaultClaim(funder) + campClaims := getDefaultClaim(promoter) campClaims["reward_type"] = types.RewardType_REWARD_TYPE_SIGNUP campClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED campClaims["reward_amount"] = types.RewardAmount{ @@ -145,7 +365,7 @@ func TestMsgApplySignupRewardSubAcc(t *testing.T) { UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), } - campUID := createCampaign(t, k, srv, ctx, funder, campClaims) + campUID := createCampaign(t, k, srv, ctx, promoter, campClaims) _, err := tApp.SubaccountKeeper.CreateSubAccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{ { @@ -212,7 +432,7 @@ func TestMsgApplySignupRewardSubAcc(t *testing.T) { require.Nil(t, err) reward := &types.MsgGrantReward{ Uid: uuid.NewString(), - Creator: funder, + Creator: promoter, CampaignUid: campUID, Ticket: ticket, } @@ -232,12 +452,12 @@ func TestMsgApplySubAccFunds(t *testing.T) { ctx = ctx.WithBlockTime(time.Now()) wctx := sdk.WrapSDKContext(ctx) - funder := simapp.TestParamUsers["user1"].Address.String() + promoter := simapp.TestParamUsers["user1"].Address.String() receiverAddr := simapp.TestParamUsers["user2"].Address.String() rewardAmount := int64(100) - campClaims := getDefaultClaim(funder) + campClaims := getDefaultClaim(promoter) campClaims["type"] = types.RewardType_REWARD_TYPE_SIGNUP campClaims["reward_type"] = types.RewardType_REWARD_TYPE_SIGNUP campClaims["reward_amount_type"] = types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED @@ -246,7 +466,7 @@ func TestMsgApplySubAccFunds(t *testing.T) { UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), } - campUID := createCampaign(t, k, srv, ctx, funder, campClaims) + campUID := createCampaign(t, k, srv, ctx, promoter, campClaims) claims := jwt.MapClaims{ "exp": time.Now().Add(time.Minute * 5).Unix(), @@ -263,7 +483,7 @@ func TestMsgApplySubAccFunds(t *testing.T) { reward := &types.MsgGrantReward{ Uid: uuid.NewString(), - Creator: funder, + Creator: promoter, CampaignUid: campUID, Ticket: ticket, } diff --git a/x/reward/keeper/reward.go b/x/reward/keeper/reward.go index 9c2a721b..48a4151e 100644 --- a/x/reward/keeper/reward.go +++ b/x/reward/keeper/reward.go @@ -62,11 +62,11 @@ func (k Keeper) SetRewardByReceiver(ctx sdk.Context, rByCategory types.RewardByC // GetRewardsByAddressAndCategory returns all rewards by address and category. func (k Keeper) GetRewardsByAddressAndCategory( ctx sdk.Context, - address string, + addr string, category types.RewardCategory, ) (list []types.RewardByCategory, err error) { store := k.getRewardByReceiverAndCategoryStore(ctx) - iterator := sdk.KVStorePrefixIterator(store, types.GetRewardsByCategoryPrefix(address, category)) + iterator := sdk.KVStorePrefixIterator(store, types.GetRewardsByCategoryPrefix(addr, category)) defer func() { err = iterator.Close() @@ -81,6 +81,15 @@ func (k Keeper) GetRewardsByAddressAndCategory( return } +// HasRewardByReceiver returns true if there is a record for the category and reward receiver +func (k Keeper) HasRewardByReceiver(ctx sdk.Context, addr string, category types.RewardCategory) bool { + rewardsByCat, err := k.GetRewardsByAddressAndCategory(ctx, addr, category) + if err != nil || len(rewardsByCat) > 0 { + return true + } + return false +} + // GetAllRewardsByReceiverAndCategory returns all rewards by receiver and category func (k Keeper) GetAllRewardsByReceiverAndCategory(ctx sdk.Context) (list []types.RewardByCategory) { store := k.getRewardByReceiverAndCategoryStore(ctx) diff --git a/x/reward/types/campaign.go b/x/reward/types/campaign.go index f9493c47..01df0f7c 100644 --- a/x/reward/types/campaign.go +++ b/x/reward/types/campaign.go @@ -38,6 +38,10 @@ func (c *Campaign) GetRewardsFactory() (IRewardFactory, error) { switch c.RewardType { case RewardType_REWARD_TYPE_SIGNUP: return NewSignUpReward(), nil + case RewardType_REWARD_TYPE_REFERRAL_SIGNUP: + return NewSignUpRefereelReward(), nil + case RewardType_REWARD_TYPE_REFERRAL: + return NewSignUpReferrerReward(), nil default: return nil, sdkerrors.Wrapf(ErrUnknownRewardType, "%d", c.RewardType) } diff --git a/x/reward/types/expected_keepers.go b/x/reward/types/expected_keepers.go index ef825239..7445762e 100644 --- a/x/reward/types/expected_keepers.go +++ b/x/reward/types/expected_keepers.go @@ -68,3 +68,8 @@ type SubAccountKeeper interface { CreateSubAccount(ctx sdk.Context, creator, owner string, lockedBalances []subaccounttypes.LockedBalance) (string, error) IsSubAccount(ctx sdk.Context, subAccAddr sdk.AccAddress) bool } + +// RewardKeeper defines the expected interface needed to get and filter the rewards. +type RewardKeeper interface { + HasRewardByReceiver(ctx sdk.Context, addr string, category RewardCategory) bool +} diff --git a/x/reward/types/reward.go b/x/reward/types/reward.go index 0f7b68e4..e830e5c7 100644 --- a/x/reward/types/reward.go +++ b/x/reward/types/reward.go @@ -4,8 +4,10 @@ import ( context "context" "github.com/mrz1836/go-sanitize" + subaccounttypes "github.com/sge-network/sge/x/subaccount/types" yaml "gopkg.in/yaml.v2" + sdkerrors "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,6 +25,38 @@ type RewardFactoryKeepers struct { OVMKeeper BetKeeper SubAccountKeeper + RewardKeeper + AccountKeeper +} + +func (keepers *RewardFactoryKeepers) getSubAccAddr(ctx sdk.Context, creator, receiver string) (string, error) { + var ( + subAccountAddressString string + err error + ) + subAccountAddress, found := keepers.SubAccountKeeper.GetSubAccountByOwner(ctx, sdk.MustAccAddressFromBech32(receiver)) + if !found { + subAccountAddressString, err = keepers.SubAccountKeeper.CreateSubAccount(ctx, creator, receiver, []subaccounttypes.LockedBalance{}) + if err != nil { + return "", sdkerrors.Wrapf(ErrSubAccountCreationFailed, "%s", receiver) + } + } else { + subAccountAddressString = subAccountAddress.String() + } + return subAccountAddressString, nil +} + +// RewardFactoryData holds the data usable by reward types methods. +type RewardFactoryData struct { + Receiver Receiver + Common RewardPayloadCommon +} + +func NewRewardFactoryData(receiver Receiver, common RewardPayloadCommon) RewardFactoryData { + return RewardFactoryData{ + Receiver: receiver, + Common: common, + } } func NewReward( @@ -62,10 +96,10 @@ type IRewardFactory interface { ValidateCampaign(campaign Campaign, blockTime uint64) error Calculate( goCtx context.Context, ctx sdk.Context, keepers RewardFactoryKeepers, campaign Campaign, ticket, creator string, - ) (Receiver, RewardPayloadCommon, error) + ) (RewardFactoryData, error) } -// NewReceiver creates reveiver object. +// NewReceiver creates receiver object. func NewReceiver(saAddr, maAddr string, saAmount, maAmount sdkmath.Int, unlockPeriod uint64) Receiver { return Receiver{ SubAccountAddr: saAddr, diff --git a/x/reward/types/reward_signup.go b/x/reward/types/reward_signup.go index 5a57f01c..cde44519 100644 --- a/x/reward/types/reward_signup.go +++ b/x/reward/types/reward_signup.go @@ -7,8 +7,6 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrtypes "github.com/cosmos/cosmos-sdk/types/errors" - - subaccounttypes "github.com/sge-network/sge/x/subaccount/types" ) // SignUpReward is the type for signup rewards calculations @@ -20,10 +18,10 @@ func NewSignUpReward() SignUpReward { return SignUpReward{} } // VaidateCampaign validates campaign definitions. func (sur SignUpReward) ValidateCampaign(campaign Campaign, blockTime uint64) error { if campaign.RewardCategory != RewardCategory_REWARD_CATEGORY_SIGNUP { - return sdkerrors.Wrapf(ErrWrongRewardCategory, "signup rewards can only have single definition") + return sdkerrors.Wrapf(ErrWrongRewardCategory, "signup referral rewards can only have single definition") } if campaign.RewardAmount.SubaccountAmount.LTE(sdkmath.ZeroInt()) { - return sdkerrors.Wrapf(ErrWrongAmountForType, "signup rewards for subaccount should be positive") + return sdkerrors.Wrapf(ErrWrongAmountForType, "signup referral rewards for subaccount should be positive") } if campaign.RewardAmountType != RewardAmountType_REWARD_AMOUNT_TYPE_FIXED { return sdkerrors.Wrapf(ErrWrongRewardAmountType, "reward amount type not supported for given reward type.") @@ -35,41 +33,34 @@ func (sur SignUpReward) ValidateCampaign(campaign Campaign, blockTime uint64) er // Calculate parses ticket payload and returns the distribution list of signup reward. func (sur SignUpReward) Calculate(goCtx context.Context, ctx sdk.Context, keepers RewardFactoryKeepers, campaign Campaign, ticket, creator string, -) (Receiver, RewardPayloadCommon, error) { +) (RewardFactoryData, error) { var payload GrantSignupRewardPayload if err := keepers.OVMKeeper.VerifyTicketUnmarshal(goCtx, ticket, &payload); err != nil { - return Receiver{}, payload.Common, sdkerrors.Wrapf(ErrInTicketVerification, "%s", err) + return RewardFactoryData{}, sdkerrors.Wrapf(ErrInTicketVerification, "%s", err) } - var ( - subAccountAddressString string - err error - ) - addr, err := sdk.AccAddressFromBech32(payload.Common.Receiver) if err != nil { - return Receiver{}, payload.Common, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) } if keepers.SubAccountKeeper.IsSubAccount(ctx, addr) { - return Receiver{}, payload.Common, ErrReceiverAddrCanNotBeSubAcc + return RewardFactoryData{}, ErrReceiverAddrCanNotBeSubAcc } - subAccountAddress, found := keepers.SubAccountKeeper.GetSubAccountByOwner(ctx, sdk.MustAccAddressFromBech32(payload.Common.Receiver)) - if !found { - subAccountAddressString, err = keepers.SubAccountKeeper.CreateSubAccount(ctx, creator, payload.Common.Receiver, []subaccounttypes.LockedBalance{}) - if err != nil { - return Receiver{}, payload.Common, sdkerrors.Wrapf(ErrSubAccountCreationFailed, "%s", payload.Common.Receiver) - } - } else { - subAccountAddressString = subAccountAddress.String() + subAccountAddressString, err := keepers.getSubAccAddr(ctx, creator, payload.Common.Receiver) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) } - return NewReceiver( - subAccountAddressString, - payload.Common.Receiver, - campaign.RewardAmount.SubaccountAmount, - campaign.RewardAmount.MainAccountAmount, - campaign.RewardAmount.UnlockPeriod, - ), payload.Common, nil + return NewRewardFactoryData( + NewReceiver( + subAccountAddressString, + payload.Common.Receiver, + campaign.RewardAmount.SubaccountAmount, + campaign.RewardAmount.MainAccountAmount, + campaign.RewardAmount.UnlockPeriod, + ), + payload.Common, + ), nil } diff --git a/x/reward/types/reward_signup_referee.go b/x/reward/types/reward_signup_referee.go new file mode 100644 index 00000000..5192df70 --- /dev/null +++ b/x/reward/types/reward_signup_referee.go @@ -0,0 +1,75 @@ +package types + +import ( + context "context" + + sdkerrors "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrtypes "github.com/cosmos/cosmos-sdk/types/errors" +) + +// SignUpRefereelReward is the type for signup referral rewards calculations +type SignUpRefereelReward struct{} + +// NewSignUpRefereelReward create new object of signup referral reward calculator type. +func NewSignUpRefereelReward() SignUpRefereelReward { return SignUpRefereelReward{} } + +// ValidateCampaign validates campaign definitions. +func (sur SignUpRefereelReward) ValidateCampaign(campaign Campaign, blockTime uint64) error { + if campaign.RewardCategory != RewardCategory_REWARD_CATEGORY_SIGNUP { + return sdkerrors.Wrapf(ErrWrongRewardCategory, "wrong reward category") + } + if campaign.RewardAmount.SubaccountAmount.LTE(sdkmath.ZeroInt()) { + return sdkerrors.Wrapf(ErrWrongAmountForType, "signup rewards for subaccount should be positive") + } + if campaign.RewardAmountType != RewardAmountType_REWARD_AMOUNT_TYPE_FIXED { + return sdkerrors.Wrapf(ErrWrongRewardAmountType, "reward amount type not supported for given reward type.") + } + + return nil +} + +// Calculate parses ticket payload and returns the distribution list of signup reward. +func (sur SignUpRefereelReward) Calculate(goCtx context.Context, ctx sdk.Context, keepers RewardFactoryKeepers, + campaign Campaign, ticket, creator string, +) (RewardFactoryData, error) { + var payload GrantSignupRewardPayload + if err := keepers.OVMKeeper.VerifyTicketUnmarshal(goCtx, ticket, &payload); err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(ErrInTicketVerification, "%s", err) + } + + receiverAddr, err := sdk.AccAddressFromBech32(payload.Common.Receiver) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) + } + + sourceUIDAddr, err := sdk.AccAddressFromBech32(payload.Common.SourceUID) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "source address is invalid %s", err) + } + + if acc := keepers.AccountKeeper.GetAccount(ctx, sourceUIDAddr); acc == nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "source id is not a valid account %s", payload.Common.SourceUID) + } + + if keepers.SubAccountKeeper.IsSubAccount(ctx, receiverAddr) { + return RewardFactoryData{}, ErrReceiverAddrCanNotBeSubAcc + } + + subAccAddrStr, err := keepers.getSubAccAddr(ctx, creator, payload.Common.Receiver) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) + } + + return NewRewardFactoryData( + NewReceiver( + subAccAddrStr, + payload.Common.Receiver, + campaign.RewardAmount.SubaccountAmount, + campaign.RewardAmount.MainAccountAmount, + campaign.RewardAmount.UnlockPeriod, + ), + payload.Common, + ), nil +} diff --git a/x/reward/types/reward_signup_referrer.go b/x/reward/types/reward_signup_referrer.go new file mode 100644 index 00000000..7b90fc8d --- /dev/null +++ b/x/reward/types/reward_signup_referrer.go @@ -0,0 +1,70 @@ +package types + +import ( + context "context" + + sdkerrors "cosmossdk.io/errors" + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrtypes "github.com/cosmos/cosmos-sdk/types/errors" +) + +// SignUpReferrerReward is the type for signup referrer rewards calculations +type SignUpReferrerReward struct{} + +// NewSignUpReferrerlReward create new object of signup referrer reward calculator type. +func NewSignUpReferrerReward() SignUpReferrerReward { return SignUpReferrerReward{} } + +// ValidateCampaign validates campaign definitions. +func (sur SignUpReferrerReward) ValidateCampaign(campaign Campaign, blockTime uint64) error { + if campaign.RewardCategory != RewardCategory_REWARD_CATEGORY_REFERRAL { + return sdkerrors.Wrapf(ErrWrongRewardCategory, "wrong reward category") + } + if campaign.RewardAmount.SubaccountAmount.LTE(sdkmath.ZeroInt()) { + return sdkerrors.Wrapf(ErrWrongAmountForType, "signup rewards for subaccount should be positive") + } + if campaign.RewardAmountType != RewardAmountType_REWARD_AMOUNT_TYPE_FIXED { + return sdkerrors.Wrapf(ErrWrongRewardAmountType, "reward amount type not supported for given reward type.") + } + + return nil +} + +// Calculate parses ticket payload and returns the distribution list of signup reward. +func (sur SignUpReferrerReward) Calculate(goCtx context.Context, ctx sdk.Context, keepers RewardFactoryKeepers, + campaign Campaign, ticket, creator string, +) (RewardFactoryData, error) { + var payload GrantSignupReferrerRewardPayload + if err := keepers.OVMKeeper.VerifyTicketUnmarshal(goCtx, ticket, &payload); err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(ErrInTicketVerification, "%s", err) + } + + receiverAddr, err := sdk.AccAddressFromBech32(payload.Common.Receiver) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) + } + + if !keepers.RewardKeeper.HasRewardByReceiver(ctx, payload.Referee, RewardCategory_REWARD_CATEGORY_SIGNUP) { + return RewardFactoryData{}, sdkerrors.Wrap(sdkerrtypes.ErrInvalidRequest, "referee account has signed up yet, there is no referee claim record") + } + + if keepers.SubAccountKeeper.IsSubAccount(ctx, receiverAddr) { + return RewardFactoryData{}, ErrReceiverAddrCanNotBeSubAcc + } + + subAccAddrStr, err := keepers.getSubAccAddr(ctx, creator, payload.Common.Receiver) + if err != nil { + return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err) + } + + return NewRewardFactoryData( + NewReceiver( + subAccAddrStr, + payload.Common.Receiver, + campaign.RewardAmount.SubaccountAmount, + campaign.RewardAmount.MainAccountAmount, + campaign.RewardAmount.UnlockPeriod, + ), + payload.Common, + ), nil +} diff --git a/x/reward/types/ticket.pb.go b/x/reward/types/ticket.pb.go index d222c94e..6766acae 100644 --- a/x/reward/types/ticket.pb.go +++ b/x/reward/types/ticket.pb.go @@ -326,7 +326,7 @@ func (m *RewardPayloadCommon) GetMeta() string { // GrantSignupRewardPayload is the type for signup reward grant payload. type GrantSignupRewardPayload struct { // common is the common properties of a reward - Common RewardPayloadCommon `protobuf:"bytes,2,opt,name=common,proto3" json:"common"` + Common RewardPayloadCommon `protobuf:"bytes,1,opt,name=common,proto3" json:"common"` } func (m *GrantSignupRewardPayload) Reset() { *m = GrantSignupRewardPayload{} } @@ -369,52 +369,111 @@ func (m *GrantSignupRewardPayload) GetCommon() RewardPayloadCommon { return RewardPayloadCommon{} } +// GrantSignupReferrerRewardPayload is the type for signup referrer reward grant +// payload. +type GrantSignupReferrerRewardPayload struct { + // common is the common properties of a reward + Common RewardPayloadCommon `protobuf:"bytes,1,opt,name=common,proto3" json:"common"` + // referee is the address of the account that used this referrer address as source_uid + Referee string `protobuf:"bytes,2,opt,name=referee,proto3" json:"referee,omitempty"` +} + +func (m *GrantSignupReferrerRewardPayload) Reset() { *m = GrantSignupReferrerRewardPayload{} } +func (m *GrantSignupReferrerRewardPayload) String() string { return proto.CompactTextString(m) } +func (*GrantSignupReferrerRewardPayload) ProtoMessage() {} +func (*GrantSignupReferrerRewardPayload) Descriptor() ([]byte, []int) { + return fileDescriptor_5d710bc1249ca8ae, []int{5} +} +func (m *GrantSignupReferrerRewardPayload) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GrantSignupReferrerRewardPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GrantSignupReferrerRewardPayload.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 *GrantSignupReferrerRewardPayload) XXX_Merge(src proto.Message) { + xxx_messageInfo_GrantSignupReferrerRewardPayload.Merge(m, src) +} +func (m *GrantSignupReferrerRewardPayload) XXX_Size() int { + return m.Size() +} +func (m *GrantSignupReferrerRewardPayload) XXX_DiscardUnknown() { + xxx_messageInfo_GrantSignupReferrerRewardPayload.DiscardUnknown(m) +} + +var xxx_messageInfo_GrantSignupReferrerRewardPayload proto.InternalMessageInfo + +func (m *GrantSignupReferrerRewardPayload) GetCommon() RewardPayloadCommon { + if m != nil { + return m.Common + } + return RewardPayloadCommon{} +} + +func (m *GrantSignupReferrerRewardPayload) GetReferee() string { + if m != nil { + return m.Referee + } + return "" +} + func init() { proto.RegisterType((*CreateCampaignPayload)(nil), "sgenetwork.sge.reward.CreateCampaignPayload") proto.RegisterType((*UpdateCampaignPayload)(nil), "sgenetwork.sge.reward.UpdateCampaignPayload") proto.RegisterType((*WithdrawFundsPayload)(nil), "sgenetwork.sge.reward.WithdrawFundsPayload") proto.RegisterType((*RewardPayloadCommon)(nil), "sgenetwork.sge.reward.RewardPayloadCommon") proto.RegisterType((*GrantSignupRewardPayload)(nil), "sgenetwork.sge.reward.GrantSignupRewardPayload") + proto.RegisterType((*GrantSignupReferrerRewardPayload)(nil), "sgenetwork.sge.reward.GrantSignupReferrerRewardPayload") } func init() { proto.RegisterFile("sge/reward/ticket.proto", fileDescriptor_5d710bc1249ca8ae) } var fileDescriptor_5d710bc1249ca8ae = []byte{ - // 536 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x6e, 0xd3, 0x40, - 0x10, 0x86, 0xe3, 0x26, 0x4d, 0x9d, 0x09, 0x20, 0xd8, 0x36, 0xc2, 0xa4, 0x92, 0x13, 0x82, 0x10, - 0x01, 0x09, 0x47, 0x0a, 0x47, 0x4e, 0x49, 0x10, 0x14, 0x71, 0xa9, 0xdc, 0x44, 0x48, 0x5c, 0xac, - 0xad, 0x3d, 0x72, 0x57, 0xad, 0xbd, 0xd6, 0xee, 0xba, 0x21, 0x57, 0x9e, 0x80, 0xc7, 0xea, 0xb1, - 0x47, 0x4e, 0x11, 0x4a, 0x6e, 0x1c, 0x78, 0x06, 0x94, 0x75, 0xea, 0x3a, 0xa8, 0x8a, 0x7a, 0xf2, - 0xcc, 0xce, 0x3f, 0x5f, 0x66, 0xff, 0xc9, 0xc2, 0x53, 0x19, 0x62, 0x4f, 0xe0, 0x94, 0x8a, 0xa0, - 0xa7, 0x98, 0x7f, 0x8e, 0xca, 0x49, 0x04, 0x57, 0x9c, 0x34, 0x64, 0x88, 0x31, 0xaa, 0x29, 0x17, - 0xe7, 0x8e, 0x0c, 0xd1, 0xc9, 0x34, 0xcd, 0x83, 0x90, 0x87, 0x5c, 0x2b, 0x7a, 0xab, 0x28, 0x13, - 0x37, 0x8b, 0x94, 0xec, 0x93, 0x15, 0x3a, 0x7f, 0xcb, 0xd0, 0x18, 0x09, 0xa4, 0x0a, 0x47, 0x34, - 0x4a, 0x28, 0x0b, 0xe3, 0x63, 0x3a, 0xbb, 0xe0, 0x34, 0x20, 0x4d, 0x30, 0x13, 0xc1, 0x23, 0xae, - 0x50, 0x58, 0x46, 0xdb, 0xe8, 0xd6, 0xdc, 0x3c, 0x27, 0xcf, 0xc0, 0x94, 0x8a, 0x0a, 0xe5, 0x29, - 0x69, 0xed, 0xb4, 0x8d, 0x6e, 0xc5, 0xdd, 0xd3, 0xf9, 0x58, 0x92, 0x06, 0x54, 0x31, 0x0e, 0x56, - 0x85, 0xb2, 0x2e, 0xec, 0x62, 0x1c, 0x8c, 0x25, 0x19, 0x80, 0xe9, 0x53, 0x85, 0x21, 0x17, 0x33, - 0xab, 0xd2, 0x36, 0xba, 0x8f, 0xfa, 0x2f, 0x9d, 0x3b, 0x2f, 0xe0, 0xb8, 0xfa, 0x33, 0x5a, 0x8b, - 0xdd, 0xbc, 0x8d, 0x0c, 0xa1, 0x9e, 0x49, 0x3c, 0x35, 0x4b, 0xd0, 0xda, 0xd5, 0x94, 0xe7, 0x5b, - 0x29, 0xe3, 0x59, 0x82, 0x2e, 0x88, 0x3c, 0x26, 0x13, 0x20, 0x6b, 0x06, 0x8d, 0x78, 0x1a, 0xab, - 0x0c, 0x55, 0xd5, 0xa8, 0x57, 0x5b, 0x51, 0x03, 0xad, 0xd7, 0xc0, 0xc7, 0xe2, 0xbf, 0x13, 0x72, - 0x04, 0x0f, 0x37, 0xb0, 0xd6, 0x5e, 0xdb, 0xe8, 0xd6, 0xfb, 0x2f, 0xee, 0x41, 0x74, 0x1f, 0x14, - 0x69, 0xe4, 0x10, 0x6a, 0x4c, 0x7a, 0xd4, 0x57, 0xec, 0x12, 0x2d, 0xb3, 0x6d, 0x74, 0x4d, 0xd7, - 0x64, 0x72, 0xa0, 0x73, 0xe2, 0xc0, 0xbe, 0x7f, 0x41, 0x59, 0x24, 0xbd, 0x04, 0x85, 0x97, 0xfb, - 0x59, 0xd3, 0x46, 0x3f, 0xc9, 0x4a, 0xc7, 0x28, 0x6e, 0xbc, 0x23, 0x04, 0x2a, 0x11, 0x2a, 0x6a, - 0x81, 0x5e, 0x9f, 0x8e, 0x3b, 0x5f, 0xa0, 0x31, 0x49, 0x82, 0x3b, 0xf6, 0x7d, 0xbb, 0x38, 0xa3, - 0xb8, 0xb8, 0x8d, 0x81, 0x76, 0x36, 0x07, 0xea, 0xf4, 0xe1, 0xe0, 0x2b, 0x53, 0x67, 0x81, 0xa0, - 0xd3, 0x8f, 0x69, 0x1c, 0xc8, 0x7b, 0xfc, 0x77, 0x3a, 0x3f, 0x0c, 0xd8, 0xcf, 0x0c, 0x58, 0xab, - 0x47, 0x3c, 0x8a, 0x78, 0xbc, 0xea, 0x11, 0xe8, 0x23, 0xbb, 0xbc, 0xed, 0xb9, 0xc9, 0xc9, 0x7b, - 0x00, 0xc9, 0x53, 0xe1, 0xa3, 0x97, 0xb2, 0x40, 0x4f, 0x51, 0x1b, 0x1e, 0x2e, 0xe6, 0xad, 0xda, - 0x89, 0x3e, 0x9d, 0x7c, 0xfe, 0xf0, 0x67, 0xde, 0x2a, 0x48, 0xdc, 0x42, 0x9c, 0xbb, 0x50, 0x2e, - 0xb8, 0x10, 0x80, 0xf5, 0x49, 0xd0, 0x58, 0x9d, 0xb0, 0x30, 0x4e, 0x93, 0x8d, 0x71, 0xc8, 0x11, - 0x54, 0x7d, 0x3d, 0x92, 0xfe, 0xa1, 0x7a, 0xff, 0xcd, 0xd6, 0x2d, 0x6e, 0x5c, 0x62, 0x58, 0xb9, - 0x9a, 0xb7, 0x4a, 0xee, 0xba, 0x7f, 0x38, 0xba, 0x5a, 0xd8, 0xc6, 0xf5, 0xc2, 0x36, 0x7e, 0x2f, - 0x6c, 0xe3, 0xe7, 0xd2, 0x2e, 0x5d, 0x2f, 0xed, 0xd2, 0xaf, 0xa5, 0x5d, 0xfa, 0xf6, 0x3a, 0x64, - 0xea, 0x2c, 0x3d, 0x75, 0x7c, 0x1e, 0xf5, 0x64, 0x88, 0x6f, 0xd7, 0xf8, 0x55, 0xdc, 0xfb, 0x9e, - 0x3f, 0xf7, 0x59, 0x82, 0xf2, 0xb4, 0xaa, 0x1f, 0xea, 0xbb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x49, 0xdc, 0x8f, 0x6a, 0x09, 0x04, 0x00, 0x00, + // 564 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x41, 0x6f, 0xd3, 0x4c, + 0x10, 0xcd, 0xb6, 0x69, 0x62, 0x6f, 0xbe, 0x0f, 0xc1, 0xb6, 0x11, 0x26, 0x95, 0x1c, 0x13, 0x84, + 0x08, 0x48, 0x38, 0x52, 0x38, 0x72, 0x4a, 0x82, 0xa0, 0x88, 0x4b, 0xe5, 0x26, 0x42, 0xe2, 0x62, + 0x6d, 0xed, 0xc1, 0xb5, 0x5a, 0x7b, 0xad, 0xdd, 0x75, 0x43, 0xae, 0x1c, 0x38, 0xf3, 0xb3, 0x7a, + 0xec, 0x91, 0x53, 0x84, 0x92, 0x1b, 0x07, 0x7e, 0x03, 0xca, 0x3a, 0x71, 0x6d, 0x54, 0x45, 0xbd, + 0x70, 0xf2, 0xcc, 0xce, 0x9b, 0x37, 0xb3, 0xef, 0x59, 0x8b, 0x1f, 0x8a, 0x00, 0x7a, 0x1c, 0xa6, + 0x94, 0xfb, 0x3d, 0x19, 0x7a, 0xe7, 0x20, 0xed, 0x84, 0x33, 0xc9, 0x48, 0x53, 0x04, 0x10, 0x83, + 0x9c, 0x32, 0x7e, 0x6e, 0x8b, 0x00, 0xec, 0x0c, 0xd3, 0x3a, 0x08, 0x58, 0xc0, 0x14, 0xa2, 0xb7, + 0x8a, 0x32, 0x70, 0xab, 0xc8, 0x92, 0x7d, 0xb2, 0x42, 0xe7, 0xf7, 0x2e, 0x6e, 0x8e, 0x38, 0x50, + 0x09, 0x23, 0x1a, 0x25, 0x34, 0x0c, 0xe2, 0x63, 0x3a, 0xbb, 0x60, 0xd4, 0x27, 0x2d, 0xac, 0x25, + 0x9c, 0x45, 0x4c, 0x02, 0x37, 0x90, 0x85, 0xba, 0xba, 0x93, 0xe7, 0xe4, 0x11, 0xd6, 0x84, 0xa4, + 0x5c, 0xba, 0x52, 0x18, 0x3b, 0x16, 0xea, 0x56, 0x9d, 0xba, 0xca, 0xc7, 0x82, 0x34, 0x71, 0x0d, + 0x62, 0x7f, 0x55, 0xd8, 0x55, 0x85, 0x3d, 0x88, 0xfd, 0xb1, 0x20, 0x03, 0xac, 0x79, 0x54, 0x42, + 0xc0, 0xf8, 0xcc, 0xa8, 0x5a, 0xa8, 0x7b, 0xaf, 0xff, 0xd4, 0xbe, 0xf5, 0x02, 0xb6, 0xa3, 0x3e, + 0xa3, 0x35, 0xd8, 0xc9, 0xdb, 0xc8, 0x10, 0x37, 0x32, 0x88, 0x2b, 0x67, 0x09, 0x18, 0x7b, 0x8a, + 0xe5, 0xf1, 0x56, 0x96, 0xf1, 0x2c, 0x01, 0x07, 0xf3, 0x3c, 0x26, 0x13, 0x4c, 0xd6, 0x1c, 0x34, + 0x62, 0x69, 0x2c, 0x33, 0xaa, 0x9a, 0xa2, 0x7a, 0xb6, 0x95, 0x6a, 0xa0, 0xf0, 0x8a, 0xf0, 0x3e, + 0xff, 0xeb, 0x84, 0x1c, 0xe1, 0xff, 0x4b, 0xb4, 0x46, 0xdd, 0x42, 0xdd, 0x46, 0xff, 0xc9, 0x1d, + 0x18, 0x9d, 0xff, 0x8a, 0x6c, 0xe4, 0x10, 0xeb, 0xa1, 0x70, 0xa9, 0x27, 0xc3, 0x4b, 0x30, 0x34, + 0x0b, 0x75, 0x35, 0x47, 0x0b, 0xc5, 0x40, 0xe5, 0xc4, 0xc6, 0xfb, 0xde, 0x05, 0x0d, 0x23, 0xe1, + 0x26, 0xc0, 0xdd, 0x5c, 0x4f, 0x5d, 0x09, 0xfd, 0x20, 0x2b, 0x1d, 0x03, 0xdf, 0x68, 0x47, 0x08, + 0xae, 0x46, 0x20, 0xa9, 0x81, 0x95, 0x7d, 0x2a, 0xee, 0x7c, 0xc0, 0xcd, 0x49, 0xe2, 0xdf, 0xe2, + 0xf7, 0x8d, 0x71, 0xa8, 0x68, 0x5c, 0x69, 0xa1, 0x9d, 0xf2, 0x42, 0x9d, 0x3e, 0x3e, 0xf8, 0x18, + 0xca, 0x33, 0x9f, 0xd3, 0xe9, 0xdb, 0x34, 0xf6, 0xc5, 0x1d, 0xfe, 0x9d, 0xce, 0x57, 0x84, 0xf7, + 0x33, 0x01, 0xd6, 0xe8, 0x11, 0x8b, 0x22, 0x16, 0xaf, 0x7a, 0x38, 0x78, 0x10, 0x5e, 0xde, 0xf4, + 0x6c, 0x72, 0xf2, 0x1a, 0x63, 0xc1, 0x52, 0xee, 0x81, 0x9b, 0x86, 0xbe, 0xda, 0x42, 0x1f, 0x1e, + 0x2e, 0xe6, 0x6d, 0xfd, 0x44, 0x9d, 0x4e, 0xde, 0xbf, 0xf9, 0x35, 0x6f, 0x17, 0x20, 0x4e, 0x21, + 0xce, 0x55, 0xd8, 0x2d, 0xa8, 0xe0, 0x63, 0xe3, 0x1d, 0xa7, 0xb1, 0x3c, 0x09, 0x83, 0x38, 0x4d, + 0x4a, 0xeb, 0x90, 0x23, 0x5c, 0xf3, 0xd4, 0x4a, 0x6a, 0x8d, 0x46, 0xff, 0xc5, 0x56, 0x17, 0x4b, + 0x97, 0x18, 0x56, 0xaf, 0xe6, 0xed, 0x8a, 0xb3, 0xee, 0xef, 0x7c, 0x43, 0xd8, 0x2a, 0x8d, 0xf9, + 0x0c, 0x9c, 0x03, 0xff, 0x47, 0xe3, 0x88, 0x81, 0xeb, 0x7c, 0x35, 0x02, 0x32, 0xa3, 0x74, 0x67, + 0x93, 0x0e, 0x47, 0x57, 0x0b, 0x13, 0x5d, 0x2f, 0x4c, 0xf4, 0x73, 0x61, 0xa2, 0xef, 0x4b, 0xb3, + 0x72, 0xbd, 0x34, 0x2b, 0x3f, 0x96, 0x66, 0xe5, 0xd3, 0xf3, 0x20, 0x94, 0x67, 0xe9, 0xa9, 0xed, + 0xb1, 0xa8, 0x27, 0x02, 0x78, 0xb9, 0x1e, 0xbc, 0x8a, 0x7b, 0x5f, 0xf2, 0x77, 0x67, 0x96, 0x80, + 0x38, 0xad, 0xa9, 0x17, 0xe3, 0xd5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8d, 0xef, 0x39, 0x99, + 0x92, 0x04, 0x00, 0x00, } func (m *CreateCampaignPayload) Marshal() (dAtA []byte, err error) { @@ -647,7 +706,47 @@ func (m *GrantSignupRewardPayload) MarshalToSizedBuffer(dAtA []byte) (int, error i = encodeVarintTicket(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *GrantSignupReferrerRewardPayload) 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 *GrantSignupReferrerRewardPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GrantSignupReferrerRewardPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Referee) > 0 { + i -= len(m.Referee) + copy(dAtA[i:], m.Referee) + i = encodeVarintTicket(dAtA, i, uint64(len(m.Referee))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Common.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTicket(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -764,6 +863,21 @@ func (m *GrantSignupRewardPayload) Size() (n int) { return n } +func (m *GrantSignupReferrerRewardPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Common.Size() + n += 1 + l + sovTicket(uint64(l)) + l = len(m.Referee) + if l > 0 { + n += 1 + l + sovTicket(uint64(l)) + } + return n +} + func sovTicket(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1400,7 +1514,90 @@ func (m *GrantSignupRewardPayload) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: GrantSignupRewardPayload: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 2: + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Common", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTicket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTicket + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTicket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Common.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTicket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTicket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GrantSignupReferrerRewardPayload) 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 ErrIntOverflowTicket + } + 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: GrantSignupReferrerRewardPayload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GrantSignupReferrerRewardPayload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Common", wireType) } @@ -1433,6 +1630,38 @@ func (m *GrantSignupRewardPayload) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Referee", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTicket + } + 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 ErrInvalidLengthTicket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTicket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Referee = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTicket(dAtA[iNdEx:])