mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
[R4R] re-enable claiming rewards validator vesting accounts (#920)
* feat: add new msg types for claim rewards from validator vesting accounts * fix: validate owner is validator vesting account * feat: add validator vesting tests for incent claims * address review comments * fix: client command name and example
This commit is contained in:
parent
fc85052522
commit
4d6f6aab3c
@ -1,154 +1,175 @@
|
||||
// nolint
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/incentive/types
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/incentive/keeper
|
||||
package incentive
|
||||
|
||||
// DO NOT EDIT - generated by aliasgen tool (github.com/rhuairahrighairidh/aliasgen)
|
||||
|
||||
import (
|
||||
"github.com/kava-labs/kava/x/incentive/keeper"
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
)
|
||||
|
||||
const (
|
||||
BeginningOfMonth = keeper.BeginningOfMonth
|
||||
MidMonth = keeper.MidMonth
|
||||
PaymentHour = keeper.PaymentHour
|
||||
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
||||
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
||||
AttributeKeyClaimType = types.AttributeKeyClaimType
|
||||
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
||||
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
USDXMintingClaimType = types.USDXMintingClaimType
|
||||
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
||||
BondDenom = types.BondDenom
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
EventTypeClaim = types.EventTypeClaim
|
||||
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
||||
EventTypeClaimPeriod = types.EventTypeClaimPeriod
|
||||
EventTypeClaimPeriodExpiry = types.EventTypeClaimPeriodExpiry
|
||||
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
||||
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
||||
Large = types.Large
|
||||
Medium = types.Medium
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
||||
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
||||
AttributeKeyClaimType = types.AttributeKeyClaimType
|
||||
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
||||
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
||||
ModuleName = types.ModuleName
|
||||
StoreKey = types.StoreKey
|
||||
RouterKey = types.RouterKey
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
QuerierRoute = types.QuerierRoute
|
||||
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
||||
Small = types.Small
|
||||
Medium = types.Medium
|
||||
Large = types.Large
|
||||
QueryGetRewards = types.QueryGetRewards
|
||||
QueryGetHardRewards = types.QueryGetHardRewards
|
||||
QueryGetHardRewardsUnsynced = types.QueryGetHardRewardsUnsynced
|
||||
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
||||
QueryGetUSDXMintingRewardsUnsynced = types.QueryGetUSDXMintingRewardsUnsynced
|
||||
QueryGetRewardFactors = types.QueryGetRewardFactors
|
||||
QueryGetParams = types.QueryGetParams
|
||||
QueryGetRewardPeriods = types.QueryGetRewardPeriods
|
||||
QueryGetRewards = types.QueryGetRewards
|
||||
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
||||
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
||||
RestClaimCollateralType = types.RestClaimCollateralType
|
||||
RestClaimOwner = types.RestClaimOwner
|
||||
RestClaimType = types.RestClaimType
|
||||
RouterKey = types.RouterKey
|
||||
Small = types.Small
|
||||
StoreKey = types.StoreKey
|
||||
USDXMintingClaimType = types.USDXMintingClaimType
|
||||
RestUnsynced = types.RestUnsynced
|
||||
BeginningOfMonth = keeper.BeginningOfMonth
|
||||
MidMonth = keeper.MidMonth
|
||||
PaymentHour = keeper.PaymentHour
|
||||
)
|
||||
|
||||
var (
|
||||
// function aliases
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
// functions aliases
|
||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
||||
NewMsgClaimHardReward = types.NewMsgClaimHardReward
|
||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||
NewMultiRewardIndex = types.NewMultiRewardIndex
|
||||
NewMultiRewardPeriod = types.NewMultiRewardPeriod
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewRewardIndex = types.NewRewardIndex
|
||||
NewMultiRewardIndex = types.NewMultiRewardIndex
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||
NewMsgClaimUSDXMintingRewardVVesting = types.NewMsgClaimUSDXMintingRewardVVesting
|
||||
NewMsgClaimHardReward = types.NewMsgClaimHardReward
|
||||
NewMsgClaimHardRewardVVesting = types.NewMsgClaimHardRewardVVesting
|
||||
NewParams = types.NewParams
|
||||
DefaultParams = types.DefaultParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewPeriod = types.NewPeriod
|
||||
NewQueryHardRewardsParams = types.NewQueryHardRewardsParams
|
||||
NewQueryRewardsParams = types.NewQueryRewardsParams
|
||||
NewQueryUSDXMintingRewardsParams = types.NewQueryUSDXMintingRewardsParams
|
||||
NewRewardIndex = types.NewRewardIndex
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewQueryUSDXMintingRewardsUnsyncedParams = types.NewQueryUSDXMintingRewardsUnsyncedParams
|
||||
NewQueryHardRewardsParams = types.NewQueryHardRewardsParams
|
||||
NewQueryHardRewardsUnsyncedParams = types.NewQueryHardRewardsUnsyncedParams
|
||||
NewQueryRewardFactorsParams = types.NewQueryRewardFactorsParams
|
||||
NewRewardFactor = types.NewRewardFactor
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
|
||||
// variable aliases
|
||||
DefaultActive = types.DefaultActive
|
||||
DefaultClaimEnd = types.DefaultClaimEnd
|
||||
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
||||
DefaultHardClaims = types.DefaultHardClaims
|
||||
DefaultMultiRewardPeriods = types.DefaultMultiRewardPeriods
|
||||
DefaultMultipliers = types.DefaultMultipliers
|
||||
DefaultRewardPeriods = types.DefaultRewardPeriods
|
||||
DefaultUSDXClaims = types.DefaultUSDXClaims
|
||||
ErrAccountNotFound = types.ErrAccountNotFound
|
||||
ErrClaimExpired = types.ErrClaimExpired
|
||||
ModuleCdc = types.ModuleCdc
|
||||
ErrClaimNotFound = types.ErrClaimNotFound
|
||||
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
||||
ErrInvalidAccountType = types.ErrInvalidAccountType
|
||||
ErrInvalidClaimType = types.ErrInvalidClaimType
|
||||
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
||||
ErrNoClaimsFound = types.ErrNoClaimsFound
|
||||
ErrRewardPeriodNotFound = types.ErrRewardPeriodNotFound
|
||||
ErrInvalidAccountType = types.ErrInvalidAccountType
|
||||
ErrNoClaimsFound = types.ErrNoClaimsFound
|
||||
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
||||
ErrAccountNotFound = types.ErrAccountNotFound
|
||||
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
||||
ErrZeroClaim = types.ErrZeroClaim
|
||||
GovDenom = types.GovDenom
|
||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||
HardDelegatorRewardFactorKeyPrefix = types.HardDelegatorRewardFactorKeyPrefix
|
||||
ErrClaimExpired = types.ErrClaimExpired
|
||||
ErrInvalidClaimType = types.ErrInvalidClaimType
|
||||
ErrInvalidClaimOwner = types.ErrInvalidClaimOwner
|
||||
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
||||
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||
HardLiquidityClaimKeyPrefix = types.HardLiquidityClaimKeyPrefix
|
||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||
HardSupplyRewardIndexesKeyPrefix = types.HardSupplyRewardIndexesKeyPrefix
|
||||
IncentiveMacc = types.IncentiveMacc
|
||||
KeyClaimEnd = types.KeyClaimEnd
|
||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||
HardDelegatorRewardFactorKeyPrefix = types.HardDelegatorRewardFactorKeyPrefix
|
||||
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
||||
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
||||
KeyHardBorrowRewardPeriods = types.KeyHardBorrowRewardPeriods
|
||||
KeyHardDelegatorRewardPeriods = types.KeyHardDelegatorRewardPeriods
|
||||
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
||||
KeyClaimEnd = types.KeyClaimEnd
|
||||
KeyMultipliers = types.KeyMultipliers
|
||||
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
||||
ModuleCdc = types.ModuleCdc
|
||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||
DefaultActive = types.DefaultActive
|
||||
DefaultRewardPeriods = types.DefaultRewardPeriods
|
||||
DefaultMultiRewardPeriods = types.DefaultMultiRewardPeriods
|
||||
DefaultMultipliers = types.DefaultMultipliers
|
||||
DefaultUSDXClaims = types.DefaultUSDXClaims
|
||||
DefaultHardClaims = types.DefaultHardClaims
|
||||
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
||||
DefaultClaimEnd = types.DefaultClaimEnd
|
||||
GovDenom = types.GovDenom
|
||||
PrincipalDenom = types.PrincipalDenom
|
||||
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
||||
IncentiveMacc = types.IncentiveMacc
|
||||
)
|
||||
|
||||
type (
|
||||
Hooks = keeper.Hooks
|
||||
Keeper = keeper.Keeper
|
||||
AccountKeeper = types.AccountKeeper
|
||||
BaseClaim = types.BaseClaim
|
||||
BaseMultiClaim = types.BaseMultiClaim
|
||||
CDPHooks = types.CDPHooks
|
||||
CdpKeeper = types.CdpKeeper
|
||||
Claim = types.Claim
|
||||
Claims = types.Claims
|
||||
GenesisAccumulationTime = types.GenesisAccumulationTime
|
||||
GenesisAccumulationTimes = types.GenesisAccumulationTimes
|
||||
GenesisState = types.GenesisState
|
||||
HARDHooks = types.HARDHooks
|
||||
HardKeeper = types.HardKeeper
|
||||
HardLiquidityProviderClaim = types.HardLiquidityProviderClaim
|
||||
HardLiquidityProviderClaims = types.HardLiquidityProviderClaims
|
||||
MsgClaimHardReward = types.MsgClaimHardReward
|
||||
MsgClaimUSDXMintingReward = types.MsgClaimUSDXMintingReward
|
||||
MultiRewardIndex = types.MultiRewardIndex
|
||||
MultiRewardIndexes = types.MultiRewardIndexes
|
||||
MultiRewardPeriod = types.MultiRewardPeriod
|
||||
MultiRewardPeriods = types.MultiRewardPeriods
|
||||
Multiplier = types.Multiplier
|
||||
MultiplierName = types.MultiplierName
|
||||
Multipliers = types.Multipliers
|
||||
Params = types.Params
|
||||
QueryHardRewardsParams = types.QueryHardRewardsParams
|
||||
QueryRewardsParams = types.QueryRewardsParams
|
||||
QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams
|
||||
RewardIndex = types.RewardIndex
|
||||
RewardIndexes = types.RewardIndexes
|
||||
RewardPeriod = types.RewardPeriod
|
||||
RewardPeriods = types.RewardPeriods
|
||||
StakingKeeper = types.StakingKeeper
|
||||
SupplyKeeper = types.SupplyKeeper
|
||||
BaseClaim = types.BaseClaim
|
||||
BaseMultiClaim = types.BaseMultiClaim
|
||||
USDXMintingClaim = types.USDXMintingClaim
|
||||
USDXMintingClaims = types.USDXMintingClaims
|
||||
HardLiquidityProviderClaim = types.HardLiquidityProviderClaim
|
||||
HardLiquidityProviderClaims = types.HardLiquidityProviderClaims
|
||||
MultiRewardPeriod = types.MultiRewardPeriod
|
||||
MultiRewardPeriods = types.MultiRewardPeriods
|
||||
RewardIndex = types.RewardIndex
|
||||
RewardIndexes = types.RewardIndexes
|
||||
MultiRewardIndex = types.MultiRewardIndex
|
||||
MultiRewardIndexes = types.MultiRewardIndexes
|
||||
SupplyKeeper = types.SupplyKeeper
|
||||
StakingKeeper = types.StakingKeeper
|
||||
CdpKeeper = types.CdpKeeper
|
||||
HardKeeper = types.HardKeeper
|
||||
AccountKeeper = types.AccountKeeper
|
||||
CDPHooks = types.CDPHooks
|
||||
HARDHooks = types.HARDHooks
|
||||
GenesisState = types.GenesisState
|
||||
GenesisAccumulationTime = types.GenesisAccumulationTime
|
||||
GenesisAccumulationTimes = types.GenesisAccumulationTimes
|
||||
MsgClaimUSDXMintingReward = types.MsgClaimUSDXMintingReward
|
||||
MsgClaimUSDXMintingRewardVVesting = types.MsgClaimUSDXMintingRewardVVesting
|
||||
MsgClaimHardReward = types.MsgClaimHardReward
|
||||
MsgClaimHardRewardVVesting = types.MsgClaimHardRewardVVesting
|
||||
Params = types.Params
|
||||
RewardPeriod = types.RewardPeriod
|
||||
RewardPeriods = types.RewardPeriods
|
||||
Multiplier = types.Multiplier
|
||||
Multipliers = types.Multipliers
|
||||
MultiplierName = types.MultiplierName
|
||||
QueryRewardsParams = types.QueryRewardsParams
|
||||
QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams
|
||||
QueryUSDXMintingRewardsUnsyncedParams = types.QueryUSDXMintingRewardsUnsyncedParams
|
||||
QueryHardRewardsParams = types.QueryHardRewardsParams
|
||||
QueryHardRewardsUnsyncedParams = types.QueryHardRewardsUnsyncedParams
|
||||
QueryRewardFactorsParams = types.QueryRewardFactorsParams
|
||||
RewardFactor = types.RewardFactor
|
||||
RewardFactors = types.RewardFactors
|
||||
Hooks = keeper.Hooks
|
||||
Keeper = keeper.Keeper
|
||||
)
|
||||
|
@ -27,7 +27,9 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
||||
|
||||
incentiveTxCmd.AddCommand(flags.PostCommands(
|
||||
getCmdClaimCdp(cdc),
|
||||
getCmdClaimCdpVVesting(cdc),
|
||||
getCmdClaimHard(cdc),
|
||||
getCmdClaimHardVVesting(cdc),
|
||||
)...)
|
||||
|
||||
return incentiveTxCmd
|
||||
@ -63,6 +65,76 @@ func getCmdClaimCdp(cdc *codec.Codec) *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func getCmdClaimCdpVVesting(cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "claim-cdp-vesting [multiplier] [receiver]",
|
||||
Short: "claim CDP rewards using a given multiplier on behalf of a validator vesting account",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Claim sender's outstanding CDP rewards on behalf of a validator vesting using a given multiplier
|
||||
|
||||
Example:
|
||||
$ %s tx %s claim-cdp-vesting large kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
`, version.ClientName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||
|
||||
sender := cliCtx.GetFromAddress()
|
||||
multiplier := args[0]
|
||||
receiverStr := args[1]
|
||||
receiver, err := sdk.AccAddressFromBech32(receiverStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimUSDXMintingRewardVVesting(sender, receiver, multiplier)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getCmdClaimHardVVesting(cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "claim-hard-vesting [multiplier] [receiver]",
|
||||
Short: "claim Hard module rewards on behalf of a validator vesting account using a given multiplier",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Claim sender's outstanding Hard rewards on behalf of a validator vesting account for deposit/borrow/delegate using given multiplier
|
||||
|
||||
Example:
|
||||
$ %s tx %s claim-hard-vesting large kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
`, version.ClientName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||
|
||||
sender := cliCtx.GetFromAddress()
|
||||
multiplier := args[0]
|
||||
receiverStr := args[1]
|
||||
receiver, err := sdk.AccAddressFromBech32(receiverStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimHardRewardVVesting(sender, receiver, multiplier)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getCmdClaimHard(cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "claim-hard [multiplier]",
|
||||
|
@ -26,3 +26,11 @@ type PostClaimReq struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
}
|
||||
|
||||
// PostClaimReq defines the properties of claim transaction's request body.
|
||||
type PostClaimVVestingReq struct {
|
||||
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
}
|
||||
|
@ -17,7 +17,10 @@ import (
|
||||
|
||||
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc("/incentive/claim-cdp", postClaimCdpHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/incentive/claim-cdp-vesting", postClaimCdpVVestingHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/incentive/claim-hard", postClaimHardHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/incentive/claim-hard-vesting", postClaimHardVVestingHandlerFn(cliCtx)).Methods("POST")
|
||||
|
||||
}
|
||||
|
||||
func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
@ -53,6 +56,39 @@ func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func postClaimCdpVVestingHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var requestBody PostClaimVVestingReq
|
||||
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
|
||||
return
|
||||
}
|
||||
|
||||
requestBody.BaseReq = requestBody.BaseReq.Sanitize()
|
||||
if !requestBody.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
fromAddr, err := sdk.AccAddressFromBech32(requestBody.BaseReq.From)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(fromAddr, requestBody.Sender) {
|
||||
rest.WriteErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("expected: %s, got: %s", fromAddr, requestBody.Sender))
|
||||
return
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimUSDXMintingRewardVVesting(requestBody.Sender, requestBody.Receiver, requestBody.MultiplierName)
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||
}
|
||||
}
|
||||
|
||||
func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var requestBody PostClaimReq
|
||||
@ -85,3 +121,36 @@ func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||
}
|
||||
}
|
||||
|
||||
func postClaimHardVVestingHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var requestBody PostClaimVVestingReq
|
||||
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
|
||||
return
|
||||
}
|
||||
|
||||
requestBody.BaseReq = requestBody.BaseReq.Sanitize()
|
||||
if !requestBody.BaseReq.ValidateBasic(w) {
|
||||
return
|
||||
}
|
||||
|
||||
fromAddr, err := sdk.AccAddressFromBech32(requestBody.BaseReq.From)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Equal(fromAddr, requestBody.Sender) {
|
||||
rest.WriteErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("expected: %s, got: %s", fromAddr, requestBody.Sender))
|
||||
return
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimHardRewardVVesting(requestBody.Sender, requestBody.Receiver, requestBody.MultiplierName)
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,12 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgClaimUSDXMintingReward:
|
||||
return handleMsgClaimUSDXMintingReward(ctx, k, msg)
|
||||
case types.MsgClaimUSDXMintingRewardVVesting:
|
||||
return handleMsgClaimUSDXMintingRewardVVesting(ctx, k, msg)
|
||||
case types.MsgClaimHardReward:
|
||||
return handleMsgClaimHardReward(ctx, k, msg)
|
||||
case types.MsgClaimHardRewardVVesting:
|
||||
return handleMsgClaimHardRewardVVesting(ctx, k, msg)
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
|
||||
}
|
||||
@ -24,7 +28,6 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
}
|
||||
|
||||
func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingReward) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimUSDXMintingReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -34,6 +37,17 @@ func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types
|
||||
}, nil
|
||||
}
|
||||
|
||||
func handleMsgClaimUSDXMintingRewardVVesting(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingRewardVVesting) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimUSDXMintingRewardVVesting(ctx, msg.Sender, msg.Receiver, types.MultiplierName(msg.MultiplierName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sdk.Result{
|
||||
Events: ctx.EventManager().Events(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func handleMsgClaimHardReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardReward) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimHardReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||
@ -44,3 +58,14 @@ func handleMsgClaimHardReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgCla
|
||||
Events: ctx.EventManager().Events(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func handleMsgClaimHardRewardVVesting(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardRewardVVesting) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimHardRewardVVesting(ctx, msg.Sender, msg.Receiver, types.MultiplierName(msg.MultiplierName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sdk.Result{
|
||||
Events: ctx.EventManager().Events(),
|
||||
}, nil
|
||||
}
|
||||
|
@ -74,6 +74,66 @@ func (k Keeper) ClaimUSDXMintingReward(ctx sdk.Context, addr sdk.AccAddress, mul
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClaimUSDXMintingReward sends the reward amount to the input receiver address and zero's out the claim in the store
|
||||
func (k Keeper) ClaimUSDXMintingRewardVVesting(ctx sdk.Context, owner, receiver sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||
claim, found := k.GetUSDXMintingClaim(ctx, owner)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||
}
|
||||
|
||||
acc := k.accountKeeper.GetAccount(ctx, owner)
|
||||
if acc == nil {
|
||||
return sdkerrors.Wrapf(types.ErrAccountNotFound, "address not found: %s", owner)
|
||||
}
|
||||
_, ok := acc.(*validatorvesting.ValidatorVestingAccount)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidAccountType, "owner account must be validator vesting account %s", owner)
|
||||
}
|
||||
|
||||
multiplier, found := k.GetMultiplier(ctx, multiplierName)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidMultiplier, string(multiplierName))
|
||||
}
|
||||
|
||||
claimEnd := k.GetClaimEnd(ctx)
|
||||
|
||||
if ctx.BlockTime().After(claimEnd) {
|
||||
return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
|
||||
}
|
||||
|
||||
claim, err := k.SynchronizeUSDXMintingClaim(ctx, claim)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rewardAmount := claim.Reward.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
|
||||
if rewardAmount.IsZero() {
|
||||
return types.ErrZeroClaim
|
||||
}
|
||||
rewardCoin := sdk.NewCoin(claim.Reward.Denom, rewardAmount)
|
||||
length, err := k.GetPeriodLength(ctx, multiplier)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, receiver, sdk.NewCoins(rewardCoin), length)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k.ZeroUSDXMintingClaim(ctx, claim)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeClaim,
|
||||
sdk.NewAttribute(types.AttributeKeyClaimedBy, claim.GetOwner().String()),
|
||||
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetReward().String()),
|
||||
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetType()),
|
||||
),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClaimHardReward sends the reward amount to the input address and zero's out the claim in the store
|
||||
func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||
_, found := k.GetHardLiquidityProviderClaim(ctx, addr)
|
||||
@ -133,6 +193,74 @@ func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplier
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClaimHardReward sends the reward amount to the input address and zero's out the claim in the store
|
||||
func (k Keeper) ClaimHardRewardVVesting(ctx sdk.Context, owner, receiver sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||
_, found := k.GetHardLiquidityProviderClaim(ctx, owner)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||
}
|
||||
|
||||
acc := k.accountKeeper.GetAccount(ctx, owner)
|
||||
if acc == nil {
|
||||
return sdkerrors.Wrapf(types.ErrAccountNotFound, "address not found: %s", owner)
|
||||
}
|
||||
_, ok := acc.(*validatorvesting.ValidatorVestingAccount)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidAccountType, "owner account must be validator vesting account %s", owner)
|
||||
}
|
||||
|
||||
multiplier, found := k.GetMultiplier(ctx, multiplierName)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrInvalidMultiplier, string(multiplierName))
|
||||
}
|
||||
|
||||
claimEnd := k.GetClaimEnd(ctx)
|
||||
|
||||
if ctx.BlockTime().After(claimEnd) {
|
||||
return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
|
||||
}
|
||||
|
||||
k.SynchronizeHardLiquidityProviderClaim(ctx, owner)
|
||||
|
||||
claim, found := k.GetHardLiquidityProviderClaim(ctx, owner)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||
}
|
||||
|
||||
var rewardCoins sdk.Coins
|
||||
for _, coin := range claim.Reward {
|
||||
rewardAmount := coin.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
|
||||
if rewardAmount.IsZero() {
|
||||
continue
|
||||
}
|
||||
rewardCoins = append(rewardCoins, sdk.NewCoin(coin.Denom, rewardAmount))
|
||||
}
|
||||
if rewardCoins.IsZero() {
|
||||
return types.ErrZeroClaim
|
||||
}
|
||||
length, err := k.GetPeriodLength(ctx, multiplier)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, receiver, rewardCoins, length)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k.ZeroHardLiquidityProviderClaim(ctx, claim)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeClaim,
|
||||
sdk.NewAttribute(types.AttributeKeyClaimedBy, claim.GetOwner().String()),
|
||||
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetReward().String()),
|
||||
sdk.NewAttribute(types.AttributeKeyClaimType, claim.GetType()),
|
||||
),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendTimeLockedCoinsToAccount sends time-locked coins from the input module account to the recipient. If the recipients account is not a vesting account and the input length is greater than zero, the recipient account is converted to a periodic vesting account and the coins are added to the vesting balance as a vesting period with the input length.
|
||||
func (k Keeper) SendTimeLockedCoinsToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, length int64) error {
|
||||
macc := k.supplyKeeper.GetModuleAccount(ctx, senderModule)
|
||||
|
@ -155,6 +155,156 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaimVVesting() {
|
||||
type args struct {
|
||||
ctype string
|
||||
rewardsPerSecond sdk.Coin
|
||||
initialTime time.Time
|
||||
initialCollateral sdk.Coin
|
||||
initialPrincipal sdk.Coin
|
||||
multipliers types.Multipliers
|
||||
multiplier types.MultiplierName
|
||||
timeElapsed int
|
||||
expectedBalance sdk.Coins
|
||||
expectedPeriods vesting.Periods
|
||||
isPeriodicVestingAccount bool
|
||||
}
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
errArgs errArgs
|
||||
}
|
||||
testCases := []test{
|
||||
{
|
||||
"valid 1 day",
|
||||
args{
|
||||
ctype: "bnb-a",
|
||||
rewardsPerSecond: c("ukava", 122354),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
initialCollateral: c("bnb", 1000000000000),
|
||||
initialPrincipal: c("usdx", 10000000000),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedBalance: cs(c("ukava", 11571385600)),
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("ukava", 10571385600))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"invalid zero rewards",
|
||||
args{
|
||||
ctype: "bnb-a",
|
||||
rewardsPerSecond: c("ukava", 0),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
initialCollateral: c("bnb", 1000000000000),
|
||||
initialPrincipal: c("usdx", 10000000000),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedBalance: cs(),
|
||||
expectedPeriods: vesting.Periods{},
|
||||
isPeriodicVestingAccount: false,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: false,
|
||||
contains: "claim amount rounds to zero",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
suite.SetupWithGenState()
|
||||
suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
|
||||
|
||||
// setup incentive state
|
||||
params := types.NewParams(
|
||||
types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
|
||||
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
|
||||
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
|
||||
types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
|
||||
tc.args.multipliers,
|
||||
tc.args.initialTime.Add(time.Hour*24*365*5),
|
||||
)
|
||||
suite.keeper.SetParams(suite.ctx, params)
|
||||
suite.keeper.SetPreviousUSDXMintingAccrualTime(suite.ctx, tc.args.ctype, tc.args.initialTime)
|
||||
suite.keeper.SetUSDXMintingRewardFactor(suite.ctx, tc.args.ctype, sdk.ZeroDec())
|
||||
|
||||
// sets addrs[2] to be a validator vesting account
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
acc := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||
bacc := auth.NewBaseAccount(acc.GetAddress(), acc.GetCoins(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())
|
||||
bva, err2 := vesting.NewBaseVestingAccount(bacc, cs(c("ukava", 400)), suite.ctx.BlockTime().Unix()+16)
|
||||
suite.Require().NoError(err2)
|
||||
periods := vesting.Periods{
|
||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
||||
}
|
||||
vva := validatorvesting.NewValidatorVestingAccountRaw(bva, suite.ctx.BlockTime().Unix(), periods, sdk.ConsAddress{}, nil, 90)
|
||||
ak.SetAccount(suite.ctx, vva)
|
||||
|
||||
// setup account state
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
err := sk.MintCoins(suite.ctx, cdptypes.ModuleName, sdk.NewCoins(tc.args.initialCollateral))
|
||||
suite.Require().NoError(err)
|
||||
err = sk.SendCoinsFromModuleToAccount(suite.ctx, cdptypes.ModuleName, suite.addrs[2], sdk.NewCoins(tc.args.initialCollateral))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// setup kavadist state
|
||||
err = sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// setup cdp state
|
||||
cdpKeeper := suite.app.GetCDPKeeper()
|
||||
err = cdpKeeper.AddCdp(suite.ctx, suite.addrs[2], tc.args.initialCollateral, tc.args.initialPrincipal, tc.args.ctype)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[2])
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(sdk.ZeroDec(), claim.RewardIndexes[0].RewardFactor)
|
||||
|
||||
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * tc.args.timeElapsed))
|
||||
suite.ctx = suite.ctx.WithBlockTime(updatedBlockTime)
|
||||
rewardPeriod, found := suite.keeper.GetUSDXMintingRewardPeriod(suite.ctx, tc.args.ctype)
|
||||
suite.Require().True(found)
|
||||
err = suite.keeper.AccumulateUSDXMintingRewards(suite.ctx, rewardPeriod)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
err = suite.keeper.ClaimUSDXMintingRewardVVesting(suite.ctx, suite.addrs[2], suite.addrs[0], tc.args.multiplier)
|
||||
|
||||
if tc.errArgs.expectPass {
|
||||
suite.Require().NoError(err)
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
acc := ak.GetAccount(suite.ctx, suite.addrs[0])
|
||||
suite.Require().Equal(tc.args.expectedBalance, acc.GetCoins()) // TODO check balance change to decouple from initialized account balance.
|
||||
|
||||
if tc.args.isPeriodicVestingAccount {
|
||||
vacc, ok := acc.(*vesting.PeriodicVestingAccount)
|
||||
suite.Require().True(ok)
|
||||
suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
|
||||
}
|
||||
|
||||
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[2])
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(c("ukava", 0), claim.Reward)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
||||
type args struct {
|
||||
deposit sdk.Coins
|
||||
@ -431,6 +581,296 @@ func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaimVVesting() {
|
||||
type args struct {
|
||||
deposit sdk.Coins
|
||||
borrow sdk.Coins
|
||||
rewardsPerSecond sdk.Coins
|
||||
initialTime time.Time
|
||||
multipliers types.Multipliers
|
||||
multiplier types.MultiplierName
|
||||
timeElapsed int64
|
||||
expectedRewards sdk.Coins
|
||||
expectedPeriods vesting.Periods
|
||||
isPeriodicVestingAccount bool
|
||||
}
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
errArgs errArgs
|
||||
}
|
||||
testCases := []test{
|
||||
{
|
||||
"single reward denom: valid 1 day",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 122354)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedRewards: cs(c("hard", 21142771200)), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"single reward denom: valid 10 days",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 122354)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 864000,
|
||||
expectedRewards: cs(c("hard", 211427712000)), // 105713856000 (deposit reward) + 105713856000 (borrow reward)
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32140800, Amount: cs(c("hard", 211427712000))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"invalid zero rewards",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 0)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedRewards: cs(c("hard", 0)),
|
||||
expectedPeriods: vesting.Periods{},
|
||||
isPeriodicVestingAccount: false,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: false,
|
||||
contains: "claim amount rounds to zero",
|
||||
},
|
||||
},
|
||||
{
|
||||
"multiple reward denoms: valid 1 day",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 122354)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedRewards: cs(c("hard", 21142771200), c("ukava", 21142771200)), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200), c("ukava", 21142771200))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"multiple reward denoms: valid 10 days",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 122354)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 864000,
|
||||
expectedRewards: cs(c("hard", 211427712000), c("ukava", 211427712000)), // 105713856000 (deposit reward) + 105713856000 (borrow reward)
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32140800, Amount: cs(c("hard", 211427712000), c("ukava", 211427712000))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"multiple reward denoms with different rewards per second: valid 1 day",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 222222)),
|
||||
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
multiplier: types.MultiplierName("large"),
|
||||
timeElapsed: 86400,
|
||||
expectedRewards: cs(c("hard", 21142771200), c("ukava", 38399961600)),
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200), c("ukava", 38399961600))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
suite.SetupWithGenState()
|
||||
suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
|
||||
|
||||
// setup kavadist state
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("hard", 1000000000000000000), c("ukava", 1000000000000000000)))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Set up generic reward periods
|
||||
var multiRewardPeriods types.MultiRewardPeriods
|
||||
var rewardPeriods types.RewardPeriods
|
||||
for _, coin := range tc.args.deposit {
|
||||
if len(tc.args.rewardsPerSecond) > 0 {
|
||||
rewardPeriod := types.NewRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond[0])
|
||||
rewardPeriods = append(rewardPeriods, rewardPeriod)
|
||||
}
|
||||
multiRewardPeriod := types.NewMultiRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)
|
||||
multiRewardPeriods = append(multiRewardPeriods, multiRewardPeriod)
|
||||
}
|
||||
|
||||
// Set up generic reward periods
|
||||
params := types.NewParams(
|
||||
rewardPeriods, multiRewardPeriods, multiRewardPeriods, rewardPeriods,
|
||||
types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||
tc.args.initialTime.Add(time.Hour*24*365*5),
|
||||
)
|
||||
suite.keeper.SetParams(suite.ctx, params)
|
||||
|
||||
// Set each denom's previous accrual time and supply reward factor
|
||||
if len(tc.args.rewardsPerSecond) > 0 {
|
||||
for _, coin := range tc.args.deposit {
|
||||
suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||
var rewardIndexes types.RewardIndexes
|
||||
for _, rewardCoin := range tc.args.rewardsPerSecond {
|
||||
rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||
}
|
||||
suite.keeper.SetHardSupplyRewardIndexes(suite.ctx, coin.Denom, rewardIndexes)
|
||||
}
|
||||
}
|
||||
|
||||
// Set each denom's previous accrual time and borrow reward factor
|
||||
if len(tc.args.rewardsPerSecond) > 0 {
|
||||
for _, coin := range tc.args.borrow {
|
||||
suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||
var rewardIndexes types.RewardIndexes
|
||||
for _, rewardCoin := range tc.args.rewardsPerSecond {
|
||||
rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||
}
|
||||
suite.keeper.SetHardBorrowRewardIndexes(suite.ctx, coin.Denom, rewardIndexes)
|
||||
}
|
||||
}
|
||||
|
||||
// sets addrs[3] to be a validator vesting account
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
acc := ak.GetAccount(suite.ctx, suite.addrs[3])
|
||||
bacc := auth.NewBaseAccount(acc.GetAddress(), acc.GetCoins(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())
|
||||
bva, err2 := vesting.NewBaseVestingAccount(bacc, cs(c("ukava", 400)), suite.ctx.BlockTime().Unix()+16)
|
||||
suite.Require().NoError(err2)
|
||||
periods := vesting.Periods{
|
||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
||||
}
|
||||
vva := validatorvesting.NewValidatorVestingAccountRaw(bva, suite.ctx.BlockTime().Unix(), periods, sdk.ConsAddress{}, nil, 90)
|
||||
ak.SetAccount(suite.ctx, vva)
|
||||
|
||||
hardKeeper := suite.app.GetHardKeeper()
|
||||
userAddr := suite.addrs[3]
|
||||
|
||||
// User deposits and borrows
|
||||
err = hardKeeper.Deposit(suite.ctx, userAddr, tc.args.deposit)
|
||||
suite.Require().NoError(err)
|
||||
err = hardKeeper.Borrow(suite.ctx, userAddr, tc.args.borrow)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Check that Hard hooks initialized a HardLiquidityProviderClaim that has 0 rewards
|
||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[3])
|
||||
suite.Require().True(found)
|
||||
for _, coin := range tc.args.deposit {
|
||||
suite.Require().Equal(sdk.ZeroInt(), claim.Reward.AmountOf(coin.Denom))
|
||||
}
|
||||
|
||||
// Set up future runtime context
|
||||
runAtTime := time.Unix(suite.ctx.BlockTime().Unix()+(tc.args.timeElapsed), 0)
|
||||
runCtx := suite.ctx.WithBlockTime(runAtTime)
|
||||
|
||||
// Run Hard begin blocker
|
||||
hard.BeginBlocker(runCtx, suite.hardKeeper)
|
||||
|
||||
// Accumulate supply rewards for each deposit denom
|
||||
for _, coin := range tc.args.deposit {
|
||||
rewardPeriod, found := suite.keeper.GetHardSupplyRewardPeriods(runCtx, coin.Denom)
|
||||
suite.Require().True(found)
|
||||
err = suite.keeper.AccumulateHardSupplyRewards(runCtx, rewardPeriod)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
// Accumulate borrow rewards for each deposit denom
|
||||
for _, coin := range tc.args.borrow {
|
||||
rewardPeriod, found := suite.keeper.GetHardBorrowRewardPeriods(runCtx, coin.Denom)
|
||||
suite.Require().True(found)
|
||||
err = suite.keeper.AccumulateHardBorrowRewards(runCtx, rewardPeriod)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
// Sync hard supply rewards
|
||||
deposit, found := suite.hardKeeper.GetDeposit(suite.ctx, suite.addrs[3])
|
||||
suite.Require().True(found)
|
||||
suite.keeper.SynchronizeHardSupplyReward(suite.ctx, deposit)
|
||||
|
||||
// Sync hard borrow rewards
|
||||
borrow, found := suite.hardKeeper.GetBorrow(suite.ctx, suite.addrs[3])
|
||||
suite.Require().True(found)
|
||||
suite.keeper.SynchronizeHardBorrowReward(suite.ctx, borrow)
|
||||
|
||||
// Fetch pre-claim balances
|
||||
preClaimAcc := ak.GetAccount(runCtx, suite.addrs[2])
|
||||
|
||||
err = suite.keeper.ClaimHardRewardVVesting(runCtx, suite.addrs[3], suite.addrs[2], tc.args.multiplier)
|
||||
if tc.errArgs.expectPass {
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Check that user's balance has increased by expected reward amount
|
||||
postClaimAcc := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||
suite.Require().Equal(preClaimAcc.GetCoins().Add(tc.args.expectedRewards...), postClaimAcc.GetCoins())
|
||||
|
||||
if tc.args.isPeriodicVestingAccount {
|
||||
vacc, ok := postClaimAcc.(*vesting.PeriodicVestingAccount)
|
||||
suite.Require().True(ok)
|
||||
suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
|
||||
}
|
||||
|
||||
// Check that each claim reward coin's amount has been reset to 0
|
||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(runCtx, suite.addrs[3])
|
||||
suite.Require().True(found)
|
||||
for _, claimRewardCoin := range claim.Reward {
|
||||
suite.Require().Equal(c(claimRewardCoin.Denom, 0), claimRewardCoin)
|
||||
}
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
|
||||
type accountArgs struct {
|
||||
periods vesting.Periods
|
||||
|
@ -21,4 +21,6 @@ func RegisterCodec(cdc *codec.Codec) {
|
||||
// Register msgs
|
||||
cdc.RegisterConcrete(MsgClaimUSDXMintingReward{}, "incentive/MsgClaimUSDXMintingReward", nil)
|
||||
cdc.RegisterConcrete(MsgClaimHardReward{}, "incentive/MsgClaimHardReward", nil)
|
||||
cdc.RegisterConcrete(MsgClaimUSDXMintingRewardVVesting{}, "incentive/MsgClaimUSDXRewardVVesting", nil)
|
||||
cdc.RegisterConcrete(MsgClaimHardRewardVVesting{}, "incentive/MsgClaimHardRewardVVesting", nil)
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
// ensure Msg interface compliance at compile time
|
||||
var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
|
||||
var _ sdk.Msg = &MsgClaimHardReward{}
|
||||
var _ sdk.Msg = &MsgClaimHardRewardVVesting{}
|
||||
var _ sdk.Msg = &MsgClaimUSDXMintingRewardVVesting{}
|
||||
|
||||
// MsgClaimUSDXMintingReward message type used to claim USDX minting rewards
|
||||
type MsgClaimUSDXMintingReward struct {
|
||||
@ -50,6 +52,52 @@ func (msg MsgClaimUSDXMintingReward) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
||||
// MsgClaimUSDXMintingRewardVVesting message type used to claim USDX minting rewards for validator vesting accounts
|
||||
type MsgClaimUSDXMintingRewardVVesting struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
}
|
||||
|
||||
// NewMsgClaimUSDXMintingRewardVVesting returns a new MsgClaimUSDXMintingReward.
|
||||
func NewMsgClaimUSDXMintingRewardVVesting(sender, receiver sdk.AccAddress, multiplierName string) MsgClaimUSDXMintingRewardVVesting {
|
||||
return MsgClaimUSDXMintingRewardVVesting{
|
||||
Sender: sender,
|
||||
Receiver: receiver,
|
||||
MultiplierName: multiplierName,
|
||||
}
|
||||
}
|
||||
|
||||
// Route return the message type used for routing the message.
|
||||
func (msg MsgClaimUSDXMintingRewardVVesting) Route() string { return RouterKey }
|
||||
|
||||
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||
func (msg MsgClaimUSDXMintingRewardVVesting) Type() string {
|
||||
return "claim_usdx_minting_reward_vvesting"
|
||||
}
|
||||
|
||||
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||
func (msg MsgClaimUSDXMintingRewardVVesting) ValidateBasic() error {
|
||||
if msg.Sender.Empty() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty")
|
||||
}
|
||||
if msg.Receiver.Empty() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be empty")
|
||||
}
|
||||
return MultiplierName(strings.ToLower(msg.MultiplierName)).IsValid()
|
||||
}
|
||||
|
||||
// GetSignBytes gets the canonical byte representation of the Msg.
|
||||
func (msg MsgClaimUSDXMintingRewardVVesting) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners returns the addresses of signers that must sign.
|
||||
func (msg MsgClaimUSDXMintingRewardVVesting) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
||||
// MsgClaimHardReward message type used to claim Hard liquidity provider rewards
|
||||
type MsgClaimHardReward struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
@ -90,3 +138,49 @@ func (msg MsgClaimHardReward) GetSignBytes() []byte {
|
||||
func (msg MsgClaimHardReward) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
||||
// MsgClaimHardRewardVVesting message type used to claim Hard liquidity provider rewards for validator vesting accounts
|
||||
type MsgClaimHardRewardVVesting struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
}
|
||||
|
||||
// NewMsgClaimHardRewardVVesting returns a new MsgClaimHardReward.
|
||||
func NewMsgClaimHardRewardVVesting(sender, receiver sdk.AccAddress, multiplierName string) MsgClaimHardRewardVVesting {
|
||||
return MsgClaimHardRewardVVesting{
|
||||
Sender: sender,
|
||||
Receiver: receiver,
|
||||
MultiplierName: multiplierName,
|
||||
}
|
||||
}
|
||||
|
||||
// Route return the message type used for routing the message.
|
||||
func (msg MsgClaimHardRewardVVesting) Route() string { return RouterKey }
|
||||
|
||||
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||
func (msg MsgClaimHardRewardVVesting) Type() string {
|
||||
return "claim_hard_reward_vvesting"
|
||||
}
|
||||
|
||||
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||
func (msg MsgClaimHardRewardVVesting) ValidateBasic() error {
|
||||
if msg.Sender.Empty() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty")
|
||||
}
|
||||
if msg.Receiver.Empty() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be empty")
|
||||
}
|
||||
return MultiplierName(strings.ToLower(msg.MultiplierName)).IsValid()
|
||||
}
|
||||
|
||||
// GetSignBytes gets the canonical byte representation of the Msg.
|
||||
func (msg MsgClaimHardRewardVVesting) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners returns the addresses of signers that must sign.
|
||||
func (msg MsgClaimHardRewardVVesting) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user