mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
Incentive PR 4: claim Hard rewards via the Incentive module (#780)
* claim hard reward keeper methods * test hard claim payout * claim hard rewards via cli * query hard claims via cli * rest txs and queries * add handler test * add claim type event field
This commit is contained in:
parent
72a6df17fd
commit
3a08fc582b
@ -23,7 +23,8 @@ const (
|
||||
ModuleName = types.ModuleName
|
||||
QuerierRoute = types.QuerierRoute
|
||||
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
||||
QueryGetClaims = types.QueryGetClaims
|
||||
QueryGetCdpClaims = types.QueryGetCdpClaims
|
||||
QueryGetHardClaims = types.QueryGetHardClaims
|
||||
QueryGetParams = types.QueryGetParams
|
||||
QueryGetRewardPeriods = types.QueryGetRewardPeriods
|
||||
RestClaimCollateralType = types.RestClaimCollateralType
|
||||
@ -35,24 +36,27 @@ const (
|
||||
|
||||
var (
|
||||
// function aliases
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewParams = types.NewParams
|
||||
NewPeriod = types.NewPeriod
|
||||
NewQueryClaimsParams = types.NewQueryClaimsParams
|
||||
NewRewardIndex = types.NewRewardIndex
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterCodec = types.RegisterCodec
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||
NewMsgClaimHardLiquidityProviderReward = types.NewMsgClaimHardLiquidityProviderReward
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewParams = types.NewParams
|
||||
NewPeriod = types.NewPeriod
|
||||
NewQueryCdpClaimsParams = types.NewQueryCdpClaimsParams
|
||||
NewQueryHardClaimsParams = types.NewQueryHardClaimsParams
|
||||
NewRewardIndex = types.NewRewardIndex
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterCodec = types.RegisterCodec
|
||||
|
||||
// variable aliases
|
||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||
@ -99,7 +103,8 @@ type (
|
||||
Multipliers = types.Multipliers
|
||||
Params = types.Params
|
||||
PostClaimReq = types.PostClaimReq
|
||||
QueryClaimsParams = types.QueryClaimsParams
|
||||
QueryCdpClaimsParams = types.QueryCdpClaimsParams
|
||||
QueryHardClaimsParams = types.QueryHardClaimsParams
|
||||
RewardIndex = types.RewardIndex
|
||||
RewardIndexes = types.RewardIndexes
|
||||
RewardPeriod = types.RewardPeriod
|
||||
|
@ -25,7 +25,8 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
|
||||
incentiveQueryCmd.AddCommand(flags.GetCommands(
|
||||
queryParamsCmd(queryRoute, cdc),
|
||||
queryClaimsCmd(queryRoute, cdc),
|
||||
queryCdpClaimsCmd(queryRoute, cdc),
|
||||
queryHardClaimsCmd(queryRoute, cdc),
|
||||
)...)
|
||||
|
||||
return incentiveQueryCmd
|
||||
@ -35,16 +36,16 @@ const (
|
||||
flagOwner = "owner"
|
||||
)
|
||||
|
||||
func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
func queryCdpClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "claims ",
|
||||
Use: "cdp-claims",
|
||||
Short: "query USDX minting claims",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query USDX minting claims with optional flag for finding claims for a specifc owner
|
||||
|
||||
Example:
|
||||
$ %s query %s claims
|
||||
$ %s query %s claims --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
$ %s query %s cdp-claims
|
||||
$ %s query %s cdp-claims --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
`,
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName)),
|
||||
Args: cobra.NoArgs,
|
||||
@ -60,14 +61,67 @@ func queryClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params := types.NewQueryClaimsParams(page, limit, owner)
|
||||
params := types.NewQueryCdpClaimsParams(page, limit, owner)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Query
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetClaims)
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdpClaims)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
var claims types.USDXMintingClaims
|
||||
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal claims: %w", err)
|
||||
}
|
||||
return cliCtx.PrintOutput(claims)
|
||||
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagOwner, "", "(optional) filter by claim owner address")
|
||||
cmd.Flags().Int(flags.FlagPage, 1, "pagination page of CDPs to to query for")
|
||||
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of CDPs to query for")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func queryHardClaimsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "hard-claims",
|
||||
Short: "query Hard liquidity provider claims",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query Hard liquidity provider claims with optional flag for finding claims for a specifc owner
|
||||
|
||||
Example:
|
||||
$ %s query %s hard-claims
|
||||
$ %s query %s hard-claims --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
`,
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName)),
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
strOwner := viper.GetString(flagOwner)
|
||||
page := viper.GetInt(flags.FlagPage)
|
||||
limit := viper.GetInt(flags.FlagLimit)
|
||||
|
||||
// Prepare params for querier
|
||||
owner, err := sdk.AccAddressFromBech32(strOwner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params := types.NewQueryHardClaimsParams(page, limit, owner)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Query
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetHardClaims)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -26,22 +26,23 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
incentiveTxCmd.AddCommand(flags.PostCommands(
|
||||
getCmdClaim(cdc),
|
||||
getCmdClaimCdp(cdc),
|
||||
getCmdClaimHard(cdc),
|
||||
)...)
|
||||
|
||||
return incentiveTxCmd
|
||||
|
||||
}
|
||||
|
||||
func getCmdClaim(cdc *codec.Codec) *cobra.Command {
|
||||
func getCmdClaimCdp(cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "claim [owner] [multiplier]",
|
||||
Short: "claim rewards for cdp owner and collateral-type",
|
||||
Use: "claim-cdp [owner] [multiplier]",
|
||||
Short: "claim CDP rewards for cdp owner and collateral-type",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Claim any outstanding rewards owned by owner for the input collateral-type and multiplier,
|
||||
fmt.Sprintf(`Claim any outstanding CDP rewards owned by owner for the input collateral-type and multiplier,
|
||||
|
||||
Example:
|
||||
$ %s tx %s claim kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw large
|
||||
$ %s tx %s claim-cdp kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw large
|
||||
`, version.ClientName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
@ -63,3 +64,34 @@ func getCmdClaim(cdc *codec.Codec) *cobra.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getCmdClaimHard(cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "claim-hard [owner] [multiplier]",
|
||||
Short: "claim Hard rewards for deposit/borrow and delegating",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Claim owner's outstanding Hard rewards using given multiplier multiplier,
|
||||
|
||||
Example:
|
||||
$ %s tx %s claim-hard kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw large
|
||||
`, version.ClientName, types.ModuleName),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
cliCtx := context.NewCLIContextWithInputAndFrom(inBuf, args[0]).WithCodec(cdc)
|
||||
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||
owner, err := sdk.AccAddressFromBech32(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgClaimHardLiquidityProviderReward(owner, args[1])
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,12 @@ import (
|
||||
)
|
||||
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc(fmt.Sprintf("/%s/claims", types.ModuleName), queryClaimsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/%s/cdp-claims", types.ModuleName), queryCdpClaimsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/%s/hard-claims", types.ModuleName), queryHardClaimsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET")
|
||||
}
|
||||
|
||||
func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
func queryCdpClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
@ -41,14 +42,54 @@ func queryClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
queryParams := types.NewQueryClaimsParams(page, limit, owner)
|
||||
queryParams := types.NewQueryCdpClaimsParams(page, limit, owner)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(queryParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetClaims), bz)
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetCdpClaims), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
||||
func queryHardClaimsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var owner sdk.AccAddress
|
||||
if x := r.URL.Query().Get(types.RestClaimOwner); len(x) != 0 {
|
||||
ownerStr := strings.ToLower(strings.TrimSpace(x))
|
||||
owner, err = sdk.AccAddressFromBech32(ownerStr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from claim owner %s", ownerStr))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
queryParams := types.NewQueryHardClaimsParams(page, limit, owner)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(queryParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardClaims), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
@ -16,10 +16,11 @@ import (
|
||||
)
|
||||
|
||||
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc("/incentive/claim", postClaimHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/incentive/claim-cdp", postClaimCdpHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/incentive/claim-hard", postClaimHardHandlerFn(cliCtx)).Methods("POST")
|
||||
}
|
||||
|
||||
func postClaimHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var requestBody types.PostClaimReq
|
||||
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
|
||||
@ -51,3 +52,36 @@ func postClaimHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
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 types.PostClaimReq
|
||||
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.NewMsgClaimHardLiquidityProviderReward(requestBody.Sender, 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,6 +15,8 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgClaimUSDXMintingReward:
|
||||
return handleMsgClaimUSDXMintingReward(ctx, k, msg)
|
||||
case types.MsgClaimHardLiquidityProviderReward:
|
||||
return handleMsgClaimHardLiquidityProviderReward(ctx, k, msg)
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
|
||||
}
|
||||
@ -23,7 +25,18 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
||||
|
||||
func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingReward) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||
err := k.ClaimUSDXMintingReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sdk.Result{
|
||||
Events: ctx.EventManager().Events(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func handleMsgClaimHardLiquidityProviderReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardLiquidityProviderReward) (*sdk.Result, error) {
|
||||
|
||||
err := k.ClaimHardReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -63,7 +63,34 @@ func (suite *HandlerTestSuite) SetupTest() {
|
||||
suite.ctx = ctx
|
||||
}
|
||||
|
||||
func (suite *HandlerTestSuite) addClaim() {
|
||||
func (suite *HandlerTestSuite) TestMsgUSDXMintingClaimReward() {
|
||||
suite.addUSDXMintingClaim()
|
||||
msg := incentive.NewMsgClaimUSDXMintingReward(suite.addrs[0], "small")
|
||||
res, err := suite.handler(suite.ctx, msg)
|
||||
suite.NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
}
|
||||
|
||||
func (suite *HandlerTestSuite) TestMsgHardLiquidityProviderClaimReward() {
|
||||
suite.addHardLiquidityProviderClaim()
|
||||
msg := incentive.NewMsgClaimHardLiquidityProviderReward(suite.addrs[0], "small")
|
||||
res, err := suite.handler(suite.ctx, msg)
|
||||
suite.NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
}
|
||||
|
||||
func (suite *HandlerTestSuite) addHardLiquidityProviderClaim() {
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
||||
suite.Require().NoError(err)
|
||||
rewardPeriod := types.RewardIndexes{types.NewRewardIndex("bnb-s", sdk.ZeroDec())}
|
||||
c1 := incentive.NewHardLiquidityProviderClaim(suite.addrs[0], c("ukava", 1000000), rewardPeriod, rewardPeriod, rewardPeriod)
|
||||
suite.NotPanics(func() {
|
||||
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, c1)
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *HandlerTestSuite) addUSDXMintingClaim() {
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
||||
suite.Require().NoError(err)
|
||||
@ -73,13 +100,6 @@ func (suite *HandlerTestSuite) addClaim() {
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *HandlerTestSuite) TestMsgClaimReward() {
|
||||
suite.addClaim()
|
||||
msg := incentive.NewMsgClaimUSDXMintingReward(suite.addrs[0], "small")
|
||||
res, err := suite.handler(suite.ctx, msg)
|
||||
suite.NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
}
|
||||
func TestHandlerTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(HandlerTestSuite))
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import (
|
||||
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||
)
|
||||
|
||||
// ClaimReward sends the reward amount to the input address and zero's out the claim in the store
|
||||
func (k Keeper) ClaimReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||
// ClaimUSDXMintingReward sends the reward amount to the input address and zero's out the claim in the store
|
||||
func (k Keeper) ClaimUSDXMintingReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||
claim, found := k.GetUSDXMintingClaim(ctx, addr)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", addr)
|
||||
@ -30,7 +30,7 @@ func (k Keeper) ClaimReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName
|
||||
return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
|
||||
}
|
||||
|
||||
claim, err := k.SynchronizeClaim(ctx, claim)
|
||||
claim, err := k.SynchronizeUSDXMintingClaim(ctx, claim)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,13 +47,64 @@ func (k Keeper) ClaimReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName
|
||||
return err
|
||||
}
|
||||
|
||||
k.ZeroClaim(ctx, claim)
|
||||
k.ZeroUSDXMintingClaim(ctx, claim)
|
||||
|
||||
ctx.EventManager().EmitEvent(
|
||||
sdk.NewEvent(
|
||||
types.EventTypeClaim,
|
||||
sdk.NewAttribute(types.AttributeKeyClaimedBy, addr.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.Reward.String()),
|
||||
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)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", addr)
|
||||
}
|
||||
|
||||
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, addr)
|
||||
|
||||
claim, found := k.GetHardLiquidityProviderClaim(ctx, addr)
|
||||
if !found {
|
||||
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", addr)
|
||||
}
|
||||
|
||||
rewardAmount := claim.Reward.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
|
||||
if rewardAmount.IsZero() {
|
||||
return types.ErrZeroClaim
|
||||
}
|
||||
rewardCoin := sdk.NewCoin(claim.Reward.Denom, rewardAmount)
|
||||
length := ctx.BlockTime().AddDate(0, int(multiplier.MonthsLockup), 0).Unix() - ctx.BlockTime().Unix()
|
||||
|
||||
err := k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, sdk.NewCoins(rewardCoin), 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
|
||||
|
@ -14,12 +14,13 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/kava-labs/kava/app"
|
||||
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
||||
"github.com/kava-labs/kava/x/hard"
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
"github.com/kava-labs/kava/x/kavadist"
|
||||
validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||
)
|
||||
|
||||
func (suite *KeeperTestSuite) TestPayoutClaim() {
|
||||
func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
|
||||
type args struct {
|
||||
ctype string
|
||||
rewardsPerSecond sdk.Coin
|
||||
@ -129,7 +130,7 @@ func (suite *KeeperTestSuite) TestPayoutClaim() {
|
||||
err = suite.keeper.AccumulateUSDXMintingRewards(suite.ctx, rewardPeriod)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
err = suite.keeper.ClaimReward(suite.ctx, suite.addrs[0], tc.args.multiplier)
|
||||
err = suite.keeper.ClaimUSDXMintingReward(suite.ctx, suite.addrs[0], tc.args.multiplier)
|
||||
|
||||
if tc.errArgs.expectPass {
|
||||
suite.Require().NoError(err)
|
||||
@ -155,6 +156,173 @@ func (suite *KeeperTestSuite) TestPayoutClaim() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
||||
type args struct {
|
||||
deposit sdk.Coins
|
||||
borrow sdk.Coins
|
||||
rewardsPerSecond sdk.Coin
|
||||
initialTime time.Time
|
||||
multipliers types.Multipliers
|
||||
multiplier types.MultiplierName
|
||||
timeElapsed int64
|
||||
expectedReward sdk.Coin
|
||||
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{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: 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,
|
||||
expectedReward: c("hard", 21142771200), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
|
||||
expectedPeriods: vesting.Periods{vesting.Period{Length: 31536000, Amount: cs(c("hard", 21142771200))}},
|
||||
isPeriodicVestingAccount: true,
|
||||
},
|
||||
errArgs{
|
||||
expectPass: true,
|
||||
contains: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"invalid zero rewards",
|
||||
args{
|
||||
deposit: cs(c("bnb", 10000000000)),
|
||||
borrow: cs(c("bnb", 5000000000)),
|
||||
rewardsPerSecond: 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,
|
||||
expectedReward: sdk.Coin{},
|
||||
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 kavadist state
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("hard", 1000000000000)))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Set up generic reward periods
|
||||
var rewardPeriods types.RewardPeriods
|
||||
for _, coin := range tc.args.deposit {
|
||||
rewardPeriod := types.NewRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)
|
||||
rewardPeriods = append(rewardPeriods, rewardPeriod)
|
||||
}
|
||||
|
||||
// Set up incentive state
|
||||
params := types.NewParams(
|
||||
rewardPeriods, rewardPeriods, rewardPeriods, rewardPeriods,
|
||||
tc.args.multipliers,
|
||||
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
|
||||
for _, coin := range tc.args.deposit {
|
||||
suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||
suite.keeper.SetHardSupplyRewardFactor(suite.ctx, coin.Denom, sdk.ZeroDec())
|
||||
}
|
||||
for _, coin := range tc.args.borrow {
|
||||
suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||
suite.keeper.SetHardBorrowRewardFactor(suite.ctx, coin.Denom, sdk.ZeroDec())
|
||||
}
|
||||
|
||||
hardKeeper := suite.app.GetHardKeeper()
|
||||
userAddr := suite.addrs[3]
|
||||
|
||||
// User deposits
|
||||
err = hardKeeper.Deposit(suite.ctx, userAddr, tc.args.deposit)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// User borrows
|
||||
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)
|
||||
suite.Require().Equal(sdk.ZeroInt(), claim.Reward.Amount)
|
||||
|
||||
// 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.GetHardSupplyRewardPeriod(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.GetHardBorrowRewardPeriod(runCtx, coin.Denom)
|
||||
suite.Require().True(found)
|
||||
err = suite.keeper.AccumulateHardBorrowRewards(runCtx, rewardPeriod)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
// Fetch pre-claim balances
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
preClaimAcc := ak.GetAccount(runCtx, suite.addrs[3])
|
||||
|
||||
err = suite.keeper.ClaimHardReward(runCtx, suite.addrs[3], 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[3])
|
||||
suite.Require().Equal(preClaimAcc.GetCoins().Add(tc.args.expectedReward), 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 the claim's reward amount has been reset to 0
|
||||
claim, found := suite.keeper.GetHardLiquidityProviderClaim(runCtx, suite.addrs[3])
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(c("hard", 0), claim.Reward)
|
||||
} 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
|
||||
|
@ -17,8 +17,10 @@ func NewQuerier(k Keeper) sdk.Querier {
|
||||
switch path[0] {
|
||||
case types.QueryGetParams:
|
||||
return queryGetParams(ctx, req, k)
|
||||
case types.QueryGetClaims:
|
||||
return queryGetClaims(ctx, req, k)
|
||||
case types.QueryGetCdpClaims:
|
||||
return queryGetCdpClaims(ctx, req, k)
|
||||
case types.QueryGetHardClaims:
|
||||
return queryGetHardClaims(ctx, req, k)
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint", types.ModuleName)
|
||||
}
|
||||
@ -38,8 +40,8 @@ func queryGetParams(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var requestParams types.QueryClaimsParams
|
||||
func queryGetCdpClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var requestParams types.QueryCdpClaimsParams
|
||||
err := k.cdc.UnmarshalJSON(req.Data, &requestParams)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
@ -67,3 +69,33 @@ func queryGetClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetHardClaims(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var requestParams types.QueryHardClaimsParams
|
||||
err := k.cdc.UnmarshalJSON(req.Data, &requestParams)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
var claims types.HardLiquidityProviderClaims
|
||||
if len(requestParams.Owner) > 0 {
|
||||
claim, _ := k.GetHardLiquidityProviderClaim(ctx, requestParams.Owner)
|
||||
claims = append(claims, claim)
|
||||
} else {
|
||||
claims = k.GetAllHardLiquidityProviderClaims(ctx)
|
||||
}
|
||||
|
||||
var paginatedClaims types.HardLiquidityProviderClaims
|
||||
|
||||
start, end := client.Paginate(len(claims), requestParams.Page, requestParams.Limit, 100)
|
||||
if start < 0 || end < 0 {
|
||||
paginatedClaims = types.HardLiquidityProviderClaims{}
|
||||
} else {
|
||||
paginatedClaims = claims[start:end]
|
||||
}
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, paginatedClaims)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
@ -518,16 +518,16 @@ func (k Keeper) InitializeHardDelegatorReward(ctx sdk.Context, delegator sdk.Acc
|
||||
k.SetHardLiquidityProviderClaim(ctx, claim)
|
||||
}
|
||||
|
||||
// ZeroClaim zeroes out the claim object's rewards and returns the updated claim object
|
||||
func (k Keeper) ZeroClaim(ctx sdk.Context, claim types.USDXMintingClaim) types.USDXMintingClaim {
|
||||
// ZeroUSDXMintingClaim zeroes out the claim object's rewards and returns the updated claim object
|
||||
func (k Keeper) ZeroUSDXMintingClaim(ctx sdk.Context, claim types.USDXMintingClaim) types.USDXMintingClaim {
|
||||
claim.Reward = sdk.NewCoin(claim.Reward.Denom, sdk.ZeroInt())
|
||||
k.SetUSDXMintingClaim(ctx, claim)
|
||||
return claim
|
||||
}
|
||||
|
||||
// SynchronizeClaim updates the claim object by adding any rewards that have accumulated.
|
||||
// SynchronizeUSDXMintingClaim updates the claim object by adding any rewards that have accumulated.
|
||||
// Returns the updated claim object
|
||||
func (k Keeper) SynchronizeClaim(ctx sdk.Context, claim types.USDXMintingClaim) (types.USDXMintingClaim, error) {
|
||||
func (k Keeper) SynchronizeUSDXMintingClaim(ctx sdk.Context, claim types.USDXMintingClaim) (types.USDXMintingClaim, error) {
|
||||
for _, ri := range claim.RewardIndexes {
|
||||
cdp, found := k.cdpKeeper.GetCdpByOwnerAndCollateralType(ctx, claim.Owner, ri.CollateralType)
|
||||
if !found {
|
||||
@ -546,6 +546,31 @@ func (k Keeper) synchronizeRewardAndReturnClaim(ctx sdk.Context, cdp cdptypes.CD
|
||||
return claim
|
||||
}
|
||||
|
||||
// SynchronizeHardLiquidityProviderClaim adds any accumulated rewards
|
||||
func (k Keeper) SynchronizeHardLiquidityProviderClaim(ctx sdk.Context, owner sdk.AccAddress) {
|
||||
// Synchronize any hard liquidity supply-side rewards
|
||||
deposit, foundDeposit := k.hardKeeper.GetDeposit(ctx, owner)
|
||||
if foundDeposit {
|
||||
k.SynchronizeHardSupplyReward(ctx, deposit)
|
||||
}
|
||||
|
||||
// Synchronize any hard liquidity borrow-side rewards
|
||||
borrow, foundBorrow := k.hardKeeper.GetBorrow(ctx, owner)
|
||||
if foundBorrow {
|
||||
k.SynchronizeHardBorrowReward(ctx, borrow)
|
||||
}
|
||||
|
||||
// Synchronize any hard delegator rewards
|
||||
k.SynchronizeHardDelegatorRewards(ctx, owner)
|
||||
}
|
||||
|
||||
// ZeroHardLiquidityProviderClaim zeroes out the claim object's rewards and returns the updated claim object
|
||||
func (k Keeper) ZeroHardLiquidityProviderClaim(ctx sdk.Context, claim types.HardLiquidityProviderClaim) types.HardLiquidityProviderClaim {
|
||||
claim.Reward = sdk.NewCoin(claim.Reward.Denom, sdk.ZeroInt())
|
||||
k.SetHardLiquidityProviderClaim(ctx, claim)
|
||||
return claim
|
||||
}
|
||||
|
||||
// CalculateTimeElapsed calculates the number of reward-eligible seconds that have passed since the previous
|
||||
// time rewards were accrued, taking into account the end time of the reward period
|
||||
func CalculateTimeElapsed(rewardPeriod types.RewardPeriod, blockTime time.Time, previousAccrualTime time.Time) sdk.Int {
|
||||
|
@ -20,4 +20,5 @@ func RegisterCodec(cdc *codec.Codec) {
|
||||
|
||||
// Register msgs
|
||||
cdc.RegisterConcrete(MsgClaimUSDXMintingReward{}, "incentive/MsgClaimUSDXMintingReward", nil)
|
||||
cdc.RegisterConcrete(MsgClaimHardLiquidityProviderReward{}, "incentive/MsgClaimHardLiquidityProviderReward", nil)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ const (
|
||||
AttributeValueCategory = ModuleName
|
||||
AttributeKeyClaimedBy = "claimed_by"
|
||||
AttributeKeyClaimAmount = "claim_amount"
|
||||
AttributeKeyClaimType = "claim_type"
|
||||
AttributeKeyRewardPeriod = "reward_period"
|
||||
AttributeKeyClaimPeriod = "claim_period"
|
||||
)
|
||||
|
@ -33,6 +33,8 @@ type CdpKeeper interface {
|
||||
|
||||
// HardKeeper defines the expected hard keeper for interacting with Hard protocol
|
||||
type HardKeeper interface {
|
||||
GetDeposit(ctx sdk.Context, depositor sdk.AccAddress) (hardtypes.Deposit, bool)
|
||||
GetBorrow(ctx sdk.Context, borrower sdk.AccAddress) (hardtypes.Borrow, bool)
|
||||
GetSupplyInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool)
|
||||
GetBorrowInterestFactor(ctx sdk.Context, denom string) (sdk.Dec, bool)
|
||||
GetBorrowedCoins(ctx sdk.Context) (coins sdk.Coins, found bool)
|
||||
|
@ -9,8 +9,9 @@ import (
|
||||
|
||||
// ensure Msg interface compliance at compile time
|
||||
var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
|
||||
var _ sdk.Msg = &MsgClaimHardLiquidityProviderReward{}
|
||||
|
||||
// MsgClaimUSDXMintingReward message type used to claim rewards
|
||||
// MsgClaimUSDXMintingReward message type used to claim USDX minting rewards
|
||||
type MsgClaimUSDXMintingReward struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
@ -28,7 +29,7 @@ func NewMsgClaimUSDXMintingReward(sender sdk.AccAddress, multiplierName string)
|
||||
func (msg MsgClaimUSDXMintingReward) Route() string { return RouterKey }
|
||||
|
||||
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||
func (msg MsgClaimUSDXMintingReward) Type() string { return "claim_reward" }
|
||||
func (msg MsgClaimUSDXMintingReward) Type() string { return "claim_usdx_minting_reward" }
|
||||
|
||||
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||
func (msg MsgClaimUSDXMintingReward) ValidateBasic() error {
|
||||
@ -48,3 +49,44 @@ func (msg MsgClaimUSDXMintingReward) GetSignBytes() []byte {
|
||||
func (msg MsgClaimUSDXMintingReward) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
||||
// MsgClaimHardLiquidityProviderReward message type used to claim Hard liquidity provider rewards
|
||||
type MsgClaimHardLiquidityProviderReward struct {
|
||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||
}
|
||||
|
||||
// NewMsgClaimHardLiquidityProviderReward returns a new MsgClaimHardLiquidityProviderReward.
|
||||
func NewMsgClaimHardLiquidityProviderReward(sender sdk.AccAddress, multiplierName string) MsgClaimHardLiquidityProviderReward {
|
||||
return MsgClaimHardLiquidityProviderReward{
|
||||
Sender: sender,
|
||||
MultiplierName: multiplierName,
|
||||
}
|
||||
}
|
||||
|
||||
// Route return the message type used for routing the message.
|
||||
func (msg MsgClaimHardLiquidityProviderReward) Route() string { return RouterKey }
|
||||
|
||||
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||
func (msg MsgClaimHardLiquidityProviderReward) Type() string {
|
||||
return "claim_hard_liquidity_provider_reward"
|
||||
}
|
||||
|
||||
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||
func (msg MsgClaimHardLiquidityProviderReward) ValidateBasic() error {
|
||||
if msg.Sender.Empty() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty")
|
||||
}
|
||||
return MultiplierName(strings.ToLower(msg.MultiplierName)).IsValid()
|
||||
}
|
||||
|
||||
// GetSignBytes gets the canonical byte representation of the Msg.
|
||||
func (msg MsgClaimHardLiquidityProviderReward) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners returns the addresses of signers that must sign.
|
||||
func (msg MsgClaimHardLiquidityProviderReward) GetSigners() []sdk.AccAddress {
|
||||
return []sdk.AccAddress{msg.Sender}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ import (
|
||||
|
||||
// Querier routes for the incentive module
|
||||
const (
|
||||
QueryGetClaims = "claims"
|
||||
QueryGetCdpClaims = "cdp-claims"
|
||||
QueryGetHardClaims = "hard-claims"
|
||||
RestClaimOwner = "owner"
|
||||
RestClaimCollateralType = "collateral_type"
|
||||
QueryGetParams = "parameters"
|
||||
@ -15,16 +16,32 @@ const (
|
||||
QueryGetClaimPeriods = "claim-periods"
|
||||
)
|
||||
|
||||
// QueryClaimsParams params for query /incentive/claims
|
||||
type QueryClaimsParams struct {
|
||||
// QueryCdpClaimsParams params for query /incentive/claims
|
||||
type QueryCdpClaimsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryClaimsParams returns QueryClaimsParams
|
||||
func NewQueryClaimsParams(page, limit int, owner sdk.AccAddress) QueryClaimsParams {
|
||||
return QueryClaimsParams{
|
||||
// NewQueryCdpClaimsParams returns QueryCdpClaimsParams
|
||||
func NewQueryCdpClaimsParams(page, limit int, owner sdk.AccAddress) QueryCdpClaimsParams {
|
||||
return QueryCdpClaimsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryHardClaimsParams params for query /incentive/claims
|
||||
type QueryHardClaimsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryHardClaimsParams returns QueryHardClaimsParams
|
||||
func NewQueryHardClaimsParams(page, limit int, owner sdk.AccAddress) QueryHardClaimsParams {
|
||||
return QueryHardClaimsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
|
Loading…
Reference in New Issue
Block a user