diff --git a/x/reward/keeper/msg_server_campaign_test.go b/x/reward/keeper/msg_server_campaign_test.go index 99300912..117fcc4a 100644 --- a/x/reward/keeper/msg_server_campaign_test.go +++ b/x/reward/keeper/msg_server_campaign_test.go @@ -65,6 +65,78 @@ func TestCampaignMsgServerCreate(t *testing.T) { } } +func TestCampaignMsgServerCreateWithAuthoriation(t *testing.T) { + tApp, k, ctx := setupKeeperAndApp(t) + srv := keeper.NewMsgServerImpl(*k) + ctx = ctx.WithBlockTime(time.Now()) + wctx := sdk.WrapSDKContext(ctx) + + creator := simapp.TestParamUsers["user2"] + promoter := simapp.TestParamUsers["user1"] + + grantAmount := sdkmath.NewInt(1000000) + + expTime := time.Now().Add(5 * time.Minute) + err := tApp.AuthzKeeper.SaveGrant(ctx, + creator.Address, + promoter.Address, + types.NewCreateCampaignAuthorization(grantAmount), + &expTime, + ) + require.NoError(t, err) + + authzBefore, _ := tApp.AuthzKeeper.GetAuthorization( + ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgCreateCampaign{}), + ) + authzBeforeW, ok := authzBefore.(*types.CreateCampaignAuthorization) + require.True(t, ok) + require.Equal(t, grantAmount, authzBeforeW.SpendLimit) + + ticketClaim := jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "promoter": promoter.Address.String(), + "start_ts": time.Now().Unix(), + "end_ts": time.Now().Add(5 * time.Minute).Unix(), + "category": types.RewardType_REWARD_TYPE_SIGNUP, + "reward_type": types.RewardType_REWARD_TYPE_SIGNUP, + "reward_amount_type": types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED, + "reward_amount": types.RewardAmount{ + SubaccountAmount: sdkmath.NewInt(100), + UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), + }, + "is_active": true, + "meta": "sample campaign", + "claims_per_category": 1, + } + ticket, err := simapp.CreateJwtTicket(ticketClaim) + require.Nil(t, err) + + expected := &types.MsgCreateCampaign{ + Creator: creator.Address.String(), + Uid: uuid.NewString(), + Ticket: ticket, + TotalFunds: sdkmath.NewInt(1000000), + } + _, err = srv.CreateCampaign(wctx, expected) + require.NoError(t, err) + rst, found := k.GetCampaign(ctx, + expected.Uid, + ) + require.True(t, found) + require.Equal(t, expected.Creator, rst.Creator) + + authzAfter, _ := tApp.AuthzKeeper.GetAuthorization(ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgCreateCampaign{}), + ) + require.Nil(t, authzAfter) +} + func TestCampaignMsgServerUnAuthorizedCreate(t *testing.T) { k, ctx := setupKeeper(t) srv := keeper.NewMsgServerImpl(*k) @@ -183,3 +255,120 @@ func TestCampaignMsgServerUpdate(t *testing.T) { }) } } + +func TestCampaignMsgServerUpdateWithAuthoriation(t *testing.T) { + tApp, k, ctx := setupKeeperAndApp(t) + srv := keeper.NewMsgServerImpl(*k) + ctx = ctx.WithBlockTime(time.Now()) + wctx := sdk.WrapSDKContext(ctx) + + expectedUID := uuid.NewString() + + creator := simapp.TestParamUsers["user2"] + promoter := simapp.TestParamUsers["user1"] + + grantAmount := sdkmath.NewInt(1000000) + + expTime := time.Now().Add(5 * time.Minute) + err := tApp.AuthzKeeper.SaveGrant(ctx, + creator.Address, + promoter.Address, + types.NewCreateCampaignAuthorization(grantAmount), + &expTime, + ) + require.NoError(t, err) + + authzCreateBefore, _ := tApp.AuthzKeeper.GetAuthorization( + ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgCreateCampaign{}), + ) + authzCreateBeforeW, ok := authzCreateBefore.(*types.CreateCampaignAuthorization) + require.True(t, ok) + require.Equal(t, grantAmount, authzCreateBeforeW.SpendLimit) + + err = tApp.AuthzKeeper.SaveGrant(ctx, + creator.Address, + promoter.Address, + types.NewUpdateCampaignAuthorization(grantAmount), + &expTime, + ) + require.NoError(t, err) + + authzUpdateBefore, _ := tApp.AuthzKeeper.GetAuthorization( + ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgUpdateCampaign{}), + ) + authzUpdateBeforeW, ok := authzUpdateBefore.(*types.UpdateCampaignAuthorization) + require.True(t, ok) + require.Equal(t, grantAmount, authzUpdateBeforeW.SpendLimit) + + ticketClaim := jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "promoter": promoter.Address.String(), + "start_ts": time.Now().Unix(), + "end_ts": time.Now().Add(5 * time.Minute).Unix(), + "category": types.RewardType_REWARD_TYPE_SIGNUP, + "reward_type": types.RewardType_REWARD_TYPE_SIGNUP, + "reward_amount_type": types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED, + "reward_amount": types.RewardAmount{ + SubaccountAmount: sdkmath.NewInt(100), + UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()), + }, + "is_active": true, + "meta": "sample campaign", + "claims_per_category": 1, + } + ticket, err := simapp.CreateJwtTicket(ticketClaim) + require.Nil(t, err) + + expected := &types.MsgCreateCampaign{ + Creator: creator.Address.String(), + Uid: expectedUID, + Ticket: ticket, + TotalFunds: sdkmath.NewInt(1000000), + } + _, err = srv.CreateCampaign(wctx, expected) + require.NoError(t, err) + + ticketClaimUpdate := jwt.MapClaims{ + "exp": time.Now().Add(time.Minute * 5).Unix(), + "iat": time.Now().Unix(), + "end_ts": time.Now().Add(5 * time.Minute).Unix(), + "is_active": true, + } + ticketUpdate, err := simapp.CreateJwtTicket(ticketClaimUpdate) + require.Nil(t, err) + + _, err = srv.UpdateCampaign(wctx, &types.MsgUpdateCampaign{ + Creator: creator.Address.String(), + Uid: expectedUID, + TopupFunds: sdkmath.NewInt(1000000), + Ticket: ticketUpdate, + }) + + require.NoError(t, err) + rst, found := k.GetCampaign(ctx, + expected.Uid, + ) + require.True(t, found) + require.Equal(t, expected.Creator, rst.Creator) + + authzCreateAfter, _ := tApp.AuthzKeeper.GetAuthorization(ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgCreateCampaign{}), + ) + require.Nil(t, authzCreateAfter) + + authzUpdateAfter, _ := tApp.AuthzKeeper.GetAuthorization(ctx, + creator.Address, + promoter.Address, + sdk.MsgTypeURL(&types.MsgUpdateCampaign{}), + ) + require.Nil(t, authzUpdateAfter) +} diff --git a/x/reward/types/campaign_authorizaton.go b/x/reward/types/campaign_authorizaton.go index bd945e86..df758b7c 100644 --- a/x/reward/types/campaign_authorizaton.go +++ b/x/reward/types/campaign_authorizaton.go @@ -81,7 +81,7 @@ func (a UpdateCampaignAuthorization) Accept(_ sdk.Context, msg sdk.Msg) (authz.A limitLeft := a.SpendLimit if msgUpdateCampaign.TopupFunds.GT(sdkmath.ZeroInt()) { - limitLeft := limitLeft.Sub(msgUpdateCampaign.TopupFunds) + limitLeft = limitLeft.Sub(msgUpdateCampaign.TopupFunds) if limitLeft.IsNegative() { return authz.AcceptResponse{}, sdkerrtypes.ErrInsufficientFunds.Wrapf( "requested amount is more than spend limit", diff --git a/x/reward/types/codec.go b/x/reward/types/codec.go index f986f44e..3bc29019 100644 --- a/x/reward/types/codec.go +++ b/x/reward/types/codec.go @@ -7,6 +7,7 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" + "github.com/cosmos/cosmos-sdk/x/authz" ) func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { @@ -22,6 +23,12 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { &MsgGrantReward{}, ) + registry.RegisterImplementations( + (*authz.Authorization)(nil), + &CreateCampaignAuthorization{}, + &UpdateCampaignAuthorization{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/reward/types/key_reward.go b/x/reward/types/key_reward.go index 270c26e8..66043780 100644 --- a/x/reward/types/key_reward.go +++ b/x/reward/types/key_reward.go @@ -51,15 +51,3 @@ func GetRewardsByCampaignPrefix(campaignUID string) []byte { func GetRewardsByCampaignKey(campaignUID, uid string) []byte { return append(utils.StrBytes(campaignUID), utils.StrBytes(uid)...) } - -// GetOneTimeRewardsPrefix returns the store key to retrieve list of all applied one-time rewards of a house -// can be used to prevent double reward grant -// onetimekey: is generated by code logic according to the reward type, -// -// ex: signup reward = signup reward receiver -// referral reward = appended strings of reward referral reward receivers -// -// this should be used with RewardOneTimeKeyPrefix -func GetOneTimeRewardsPrefix(rewardType RewardType, oneTimeKey string) []byte { - return append(utils.Int32ToBytes(int32(rewardType)), utils.StrBytes(oneTimeKey)...) -}