Skip to content

Commit 15cc595

Browse files
committed
add claim msg
1 parent 8487c28 commit 15cc595

File tree

11 files changed

+1808
-247
lines changed

11 files changed

+1808
-247
lines changed

api/side/farming/farming.pulsar.go

Lines changed: 154 additions & 62 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/side/farming/tx.pulsar.go

Lines changed: 1005 additions & 72 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/side/farming/tx_grpc.pb.go

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/side/farming/farming.proto

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ message Staking {
6262
(gogoproto.nullable) = false
6363
];
6464
cosmos.base.v1beta1.Coin effective_amount = 7 [(gogoproto.nullable) = false];
65-
google.protobuf.Timestamp start_time = 8 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
66-
StakingStatus status = 9;
65+
cosmos.base.v1beta1.Coin pending_reward = 8 [(gogoproto.nullable) = false];
66+
google.protobuf.Timestamp start_time = 9 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
67+
StakingStatus status = 10;
6768
}
6869

6970
// TotalStaking defines total staking per phase and denom

proto/side/farming/tx.proto

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ service Msg {
1818
rpc CreatePhase(MsgCreatePhase) returns (MsgCreatePhaseResponse);
1919
rpc Stake(MsgStake) returns (MsgStakeResponse);
2020
rpc Unstake(MsgUnstake) returns (MsgUnstakeResponse);
21+
rpc Claim(MsgClaim) returns (MsgClaimResponse);
2122

2223
// UpdateParams defines a governance operation for updating the x/farming module
2324
// parameters. The authority defaults to the x/gov module account.
@@ -73,6 +74,17 @@ message MsgUnstake {
7374

7475
message MsgUnstakeResponse {}
7576

77+
message MsgClaim {
78+
option (cosmos.msg.v1.signer) = "staker";
79+
80+
// Staker address
81+
string staker = 1;
82+
// Staking id
83+
uint64 id = 2;
84+
}
85+
86+
message MsgClaimResponse {}
87+
7688
// MsgUpdateParams is the Msg/UpdateParams request type.
7789
//
7890
// Since: cosmos-sdk 0.47

x/farming/keeper/msg_server.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55

66
errorsmod "cosmossdk.io/errors"
7+
sdkmath "cosmossdk.io/math"
78
sdk "github.com/cosmos/cosmos-sdk/types"
89
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
910

@@ -98,6 +99,7 @@ func (m msgServer) Stake(goCtx context.Context, msg *types.MsgStake) (*types.Msg
9899
LockDuration: lockDuration,
99100
LockMultiplier: lockMultiplier,
100101
EffectiveAmount: types.GetEffectiveAmount(msg.Amount, lockMultiplier),
102+
PendingReward: sdk.NewCoin(phase.RewardsPerInterval.Denom, sdkmath.ZeroInt()),
101103
StartTime: ctx.BlockTime(),
102104
Status: types.StakingStatus_STAKING_STATUS_STAKED,
103105
}
@@ -141,6 +143,13 @@ func (m msgServer) Unstake(goCtx context.Context, msg *types.MsgUnstake) (*types
141143
return nil, err
142144
}
143145

146+
// claim pending reward if any
147+
if staking.PendingReward.IsPositive() {
148+
if err := m.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.MustAccAddressFromBech32(msg.Staker), sdk.NewCoins(staking.PendingReward)); err != nil {
149+
return nil, err
150+
}
151+
}
152+
144153
// update status
145154
staking.Status = types.StakingStatus_STAKING_STATUS_UNSTAKED
146155
m.SetStaking(ctx, staking)
@@ -151,6 +160,38 @@ func (m msgServer) Unstake(goCtx context.Context, msg *types.MsgUnstake) (*types
151160
return &types.MsgUnstakeResponse{}, nil
152161
}
153162

163+
// Claim implements types.MsgServer.
164+
func (m msgServer) Claim(goCtx context.Context, msg *types.MsgClaim) (*types.MsgClaimResponse, error) {
165+
if err := msg.ValidateBasic(); err != nil {
166+
return nil, err
167+
}
168+
169+
ctx := sdk.UnwrapSDKContext(goCtx)
170+
171+
if !m.HasStaking(ctx, msg.Id) {
172+
return nil, errorsmod.Wrapf(types.ErrStakingDoesNotExist, "id: %d", msg.Id)
173+
}
174+
175+
staking := m.GetStaking(ctx, msg.Id)
176+
if staking.Address != msg.Staker {
177+
return nil, errorsmod.Wrap(types.ErrUnauthorized, "mismatched staker address")
178+
}
179+
180+
if staking.Status == types.StakingStatus_STAKING_STATUS_UNSTAKED {
181+
return nil, errorsmod.Wrapf(types.ErrInvalidStakingStatus, "already unstaked: %d", msg.Id)
182+
}
183+
184+
if staking.PendingReward.IsZero() {
185+
return nil, types.ErrNoPendingReward
186+
}
187+
188+
if err := m.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.MustAccAddressFromBech32(msg.Staker), sdk.NewCoins(staking.PendingReward)); err != nil {
189+
return nil, err
190+
}
191+
192+
return &types.MsgClaimResponse{}, nil
193+
}
194+
154195
// UpdateParams updates the module params.
155196
func (m msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
156197
if m.authority != msg.Authority {

x/farming/module/abci.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ func distributeRewards(ctx sdk.Context, k keeper.Keeper) {
2626
continue
2727
}
2828

29+
// get the pending reward of the last distribution interval
2930
pendingReward := k.GetPendingReward(ctx, staking.Id)
3031

31-
if err := k.BankKeeper().SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.MustAccAddressFromBech32(""), sdk.NewCoins(pendingReward)); err != nil {
32-
k.Logger(ctx).Error("Failed to distribute reward", "staker", "", "reward", pendingReward, "err", err)
33-
}
32+
// accumulate reward
33+
staking.PendingReward = staking.PendingReward.Add(pendingReward)
34+
k.SetStaking(ctx, staking)
3435
}
3536
}

x/farming/types/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var (
1818
ErrStakingDoesNotExist = errorsmod.Register(ModuleName, 1008, "staking does not exist")
1919
ErrInvalidStakingStatus = errorsmod.Register(ModuleName, 1009, "invalid staking status")
2020
ErrLockDurationNotEnded = errorsmod.Register(ModuleName, 1010, "lock duration not ended")
21+
ErrNoPendingReward = errorsmod.Register(ModuleName, 1011, "no pending reward")
2122

2223
ErrInvalidParams = errorsmod.Register(ModuleName, 2000, "invalid params")
2324
)

0 commit comments

Comments
 (0)