Skip to content

Commit

Permalink
Merge pull request #287 from sge-network/feature/campaigntx_mod
Browse files Browse the repository at this point in the history
update code
  • Loading branch information
3eyedraga authored Nov 9, 2023
2 parents ced9be5 + f4af8f4 commit 3bb2898
Show file tree
Hide file tree
Showing 33 changed files with 1,059 additions and 618 deletions.
5 changes: 4 additions & 1 deletion proto/sge/reward/campaign.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,12 @@ message Campaign {
// is_active is the flag to check if the campaign is active or not.
bool is_active = 11;

// claims_per_category is the number of times a user can claim a reward for category of this campaign.
uint64 claims_per_category = 12;

// meta is the metadata of the campaign.
// It is a stringified base64 encoded json.
string meta = 12;
string meta = 13;
}

// Pool is the type for the campaign funding pool.
Expand Down
6 changes: 3 additions & 3 deletions proto/sge/reward/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ message QueryRewardsByAddressRequest {
// QueryRewardsByAddressResponse is response body of the query all rewards by
// address endpoint.
message QueryRewardsByAddressResponse {
repeated Reward rewards = 1 [ (gogoproto.nullable) = false ];
repeated RewardByCategory rewards = 1 [ (gogoproto.nullable) = false ];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

Expand All @@ -134,7 +134,7 @@ message QueryRewardsByAddressAndCategoryRequest {
// QueryRewardsByAddressAndTypeResponse is response body of the query all
// rewards by address and type endpoint.
message QueryRewardsByAddressAndCategoryResponse {
repeated Reward rewards = 1 [ (gogoproto.nullable) = false ];
repeated RewardByCategory rewards = 1 [ (gogoproto.nullable) = false ];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

Expand All @@ -148,6 +148,6 @@ message QueryRewardsByCampaignRequest {
// QueryRewardsByCampaignResponse is response body of the query all rewards by
// campaign endpoint.
message QueryRewardsByCampaignResponse {
repeated Reward rewards = 1 [ (gogoproto.nullable) = false ];
repeated RewardByCampaign rewards = 1 [ (gogoproto.nullable) = false ];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
36 changes: 31 additions & 5 deletions proto/sge/reward/reward.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ message Reward {
string meta = 12;
}

// RewardAmount
message RewardAmount {
// main account reward amount
string main_account_amount = 1 [
Expand All @@ -66,11 +67,36 @@ message RewardAmount {
(gogoproto.moretags) = "yaml:\"subaccount_amount\""
];

// unlock timestamp
uint64 unlock_ts = 3 [
(gogoproto.customname) = "UnlockTS",
(gogoproto.jsontag) = "unlock_ts",
json_name = "unlock_ts"
// unlock period
uint64 unlock_period = 3 [
(gogoproto.customname) = "UnlockPeriod",
(gogoproto.jsontag) = "unlock_period",
json_name = "unlock_period"
];
}

// RewardByCategory
message RewardByCategory {
string uid = 1 [
(gogoproto.customname) = "UID",
(gogoproto.jsontag) = "uid",
json_name = "uid"
];
string addr = 2;
RewardCategory reward_category = 3;
}

// RewardByCampaign
message RewardByCampaign {
string uid = 1 [
(gogoproto.customname) = "UID",
(gogoproto.jsontag) = "uid",
json_name = "uid"
];
string campaign_uid = 2 [
(gogoproto.customname) = "CampaignUID",
(gogoproto.jsontag) = "campaign_uid",
json_name = "campaign_uid"
];
}

Expand Down
17 changes: 5 additions & 12 deletions proto/sge/reward/ticket.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package sgenetwork.sge.reward;

import "gogoproto/gogo.proto";
import "sge/reward/reward.proto";
import "sge/reward/campaign.proto";

option go_package = "github.com/sge-network/sge/x/reward/types";

Expand Down Expand Up @@ -41,9 +40,12 @@ message CreateCampaignPayload {
// is_active is the flag to check if the campaign is active or not.
bool is_active = 9;

// claims_per_category is the number of times a user can claim a reward for category of this campaign.
uint64 claims_per_category = 10;

// meta is the metadata of the campaign.
// It is a stringified base64 encoded json.
string meta = 10;
string meta = 11;
}

// UpdateCampaignPayload is the type for campaign update payload.
Expand All @@ -64,18 +66,9 @@ message WithdrawFundsPayload {
// promoter is the address of campaign promoter.
// Funds would be transferred to this account.
string promoter = 1;

// amount is the funds that needs to be withdrawn.
string amount = 8 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"amount\""
];

// is_active is the flag to check if the campaign is active or not.
bool is_active = 9;
}

// RewardPayloadCommon
message RewardPayloadCommon {
// receiver is the address of the account that receives the reward.
string receiver = 1;
Expand Down
2 changes: 0 additions & 2 deletions proto/sge/reward/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ syntax = "proto3";

package sgenetwork.sge.reward;

import "gogoproto/gogo.proto";

option go_package = "github.com/sge-network/sge/x/reward/types";

// Msg defines the Msg service.
Expand Down
1 change: 0 additions & 1 deletion proto/sge/subaccount/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ message MsgTopUpResponse {}

// MsgWithdrawUnlockedBalances defines the Msg/WithdrawUnlockedBalances request
// type.

message MsgWithdrawUnlockedBalances {
// creator is the subaccount owner.
string creator = 1;
Expand Down
6 changes: 3 additions & 3 deletions x/reward/client/cli/query_reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@ func CmdGetRewardsByCampaign() *cobra.Command {

queryClient := types.NewQueryClient(clientCtx)

argCampaignId := args[0]
argCampaignID := args[0]

pageReq, err := client.ReadPageRequest(cmd.Flags())
if err != nil {
return err
}

params := &types.QueryRewardsByCampaignRequest{
CampaignUid: argCampaignId,
CampaignUid: argCampaignID,
Pagination: pageReq,
}

Expand All @@ -152,7 +152,7 @@ func CmdGetRewardByUserAndCategory() *cobra.Command {
cmd := &cobra.Command{
Use: "rewards-by-user-category [address] [category]",
Short: "shows a list of rewards by user and category",
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx := client.GetClientContextFromCmd(cmd)

Expand Down
10 changes: 6 additions & 4 deletions x/reward/client/cli/tx_reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ import (

func CmdGrantReward() *cobra.Command {
cmd := &cobra.Command{
Use: "apply [campaign uid] [ticket]",
Use: "apply [uid] [campaign uid] [ticket]",
Short: "Apply a new reward",
Args: cobra.ExactArgs(2),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) (err error) {
// Get indexes
argCampaignUID := args[0]
argUID := args[0]
argCampaignUID := args[1]

// Get value arguments
argTicket := args[1]
argTicket := args[2]

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand All @@ -29,6 +30,7 @@ func CmdGrantReward() *cobra.Command {

msg := types.NewMsgGrantReward(
clientCtx.GetFromAddress().String(),
argUID,
argCampaignUID,
argTicket,
)
Expand Down
2 changes: 1 addition & 1 deletion x/reward/keeper/campaign.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (k Keeper) GetAllCampaign(ctx sdk.Context) (list []types.Campaign) {
}

func (k Keeper) UpdateCampaignPool(ctx sdk.Context, campaign types.Campaign, receiver types.Receiver) {
totalAmount := receiver.Amount.Add(receiver.Amount)
totalAmount := receiver.SubAccountAmount.Add(receiver.MainAccountAmount)
campaign.Pool.Spent = campaign.Pool.Spent.Add(totalAmount)

k.SetCampaign(ctx, campaign)
Expand Down
30 changes: 14 additions & 16 deletions x/reward/keeper/distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,32 @@ package keeper

import (
sdkerrors "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/sge-network/sge/x/reward/types"
subaccounttypes "github.com/sge-network/sge/x/subaccount/types"
)

// DistributeRewards distributes the rewards according to the input distribution list.
func (k Keeper) DistributeRewards(ctx sdk.Context, funderAddr string, isSubAccount bool, receiver types.Receiver) error {
if isSubAccount {
if _, err := k.subaccountKeeper.TopUp(ctx, funderAddr, receiver.Addr,
func (k Keeper) DistributeRewards(ctx sdk.Context, funderAddr string, receiver types.Receiver) error {
if receiver.SubAccountAmount.GT(sdk.ZeroInt()) {
if _, err := k.subaccountKeeper.TopUp(ctx, funderAddr, receiver.MainAccountAddr,
[]subaccounttypes.LockedBalance{
{
UnlockTS: receiver.UnlockTS,
Amount: receiver.Amount,
UnlockTS: uint64(ctx.BlockTime().Unix()) + receiver.UnlockPeriod,
Amount: receiver.SubAccountAmount,
},
}); err != nil {
return sdkerrors.Wrapf(types.ErrSubAccRewardTopUp, "subaccount address %s, %s", receiver.Addr, err)
return sdkerrors.Wrapf(types.ErrSubAccRewardTopUp, "subaccount address %s, %s", receiver.SubAccountAddr, err)
}
} else {
if receiver.Amount.GT(sdkmath.ZeroInt()) {
if err := k.modFunder.Refund(
types.RewardPoolFunder{}, ctx,
sdk.MustAccAddressFromBech32(receiver.Addr),
receiver.Amount,
); err != nil {
return err
}
}
if receiver.MainAccountAmount.GT(sdk.ZeroInt()) {
if err := k.modFunder.Refund(
types.RewardPoolFunder{}, ctx,
sdk.MustAccAddressFromBech32(receiver.MainAccountAddr),
receiver.MainAccountAmount,
); err != nil {
return err
}
}

Expand Down
59 changes: 57 additions & 2 deletions x/reward/keeper/msg_server_campaign.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package keeper
import (
"context"

sdkmath "cosmossdk.io/math"

sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrtypes "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -38,7 +40,7 @@ func (k msgServer) CreateCampaign(goCtx context.Context, msg *types.MsgCreateCam

campaign := types.NewCampaign(
msg.Creator, payload.Promoter, msg.Uid,
payload.StartTs, payload.EndTs,
payload.StartTs, payload.EndTs, payload.ClaimsPerCategory,
payload.RewardType,
payload.Category,
payload.RewardAmountType,
Expand Down Expand Up @@ -92,7 +94,7 @@ func (k msgServer) UpdateCampaign(goCtx context.Context, msg *types.MsgUpdateCam
return nil, sdkerrors.Wrap(sdkerrtypes.ErrKeyNotFound, "index not set")
}

// Checks if the the msg creator is the same as the current owner
// Checks if the msg creator is the same as the current owner
if msg.Creator != valFound.Promoter {
if err := utils.ValidateMsgAuthorization(k.authzKeeper, ctx, msg.Creator, valFound.Promoter, msg,
types.ErrAuthorizationNotFound, types.ErrAuthorizationNotAccepted); err != nil {
Expand All @@ -108,3 +110,56 @@ func (k msgServer) UpdateCampaign(goCtx context.Context, msg *types.MsgUpdateCam

return &types.MsgUpdateCampaignResponse{}, nil
}

func (k msgServer) WithdrawFunds(goCtx context.Context, msg *types.MsgWithdrawFunds) (*types.MsgWithdrawFundsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

var payload types.WithdrawFundsPayload
if err := k.ovmKeeper.VerifyTicketUnmarshal(goCtx, msg.Ticket, &payload); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketVerification, "%s", err)
}

// Validate ticket payload
if err := payload.Validate(); err != nil {
return nil, err
}

// Check if the campaign exists
valFound, isFound := k.GetCampaign(ctx, msg.Uid)
if !isFound {
return nil, sdkerrors.Wrap(sdkerrtypes.ErrKeyNotFound, "campaign not found")
}

// Checks if the msg creator is the same as the current owner
if msg.Creator != valFound.Promoter {
if err := utils.ValidateMsgAuthorization(k.authzKeeper, ctx, msg.Creator, valFound.Promoter, msg,
types.ErrAuthorizationNotFound, types.ErrAuthorizationNotAccepted); err != nil {
return nil, err
}
}
availableAmount := valFound.Pool.Total.Sub(valFound.Pool.Spent)
// check if the pool amount is positive
if availableAmount.IsNil() || !availableAmount.GT(sdkmath.ZeroInt()) {
return nil, sdkerrors.Wrapf(types.ErrWithdrawFromCampaignPool, "pool amount should be positive")
}

// transfer the funds present in campaign to the promoter
if err := k.modFunder.Refund(
types.RewardPoolFunder{}, ctx,
sdk.MustAccAddressFromBech32(payload.Promoter),
availableAmount,
); err != nil {
return nil, sdkerrors.Wrapf(types.ErrWithdrawFromCampaignPool, "%s", err)
}
// set the pool amount to zero
valFound.Pool.Total = sdkmath.ZeroInt()
// deactivate the campaign
valFound.IsActive = false

// store the campaign
k.SetCampaign(ctx, valFound)
// emit withdraw event
msg.EmitEvent(&ctx, msg.Uid)

return &types.MsgWithdrawFundsResponse{}, nil
}
4 changes: 2 additions & 2 deletions x/reward/keeper/msg_server_campaign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestCampaignMsgServerCreate(t *testing.T) {
"reward_amount_type": types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED,
"reward_amount": types.RewardAmount{
SubaccountAmount: sdkmath.NewInt(100),
UnlockTS: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()),
UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()),
},
"total_funds": sdkmath.NewInt(1000000),
"is_active": true,
Expand Down Expand Up @@ -113,7 +113,7 @@ func TestCampaignMsgServerUpdate(t *testing.T) {
"reward_amount_type": types.RewardAmountType_REWARD_AMOUNT_TYPE_FIXED,
"reward_amount": types.RewardAmount{
SubaccountAmount: sdkmath.NewInt(100),
UnlockTS: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()),
UnlockPeriod: uint64(ctx.BlockTime().Add(10 * time.Minute).Unix()),
},
"total_funds": sdkmath.NewInt(1000000),
"is_active": true,
Expand Down
Loading

0 comments on commit 3bb2898

Please sign in to comment.