0g-chain/x/incentive/client/cli/query.go
Derrick Lee 6ef9bab67d
Add liquid staking reward redistribution via incentive (#1308)
* wip Add claim

* Add distr keeper and claiming

* Add claim test

* Update claim test with failures

* wip Add staking rewards

* -S

Fix savings to earn incentive methods

* Use a single accural time for all earn incentives

* Add additional required liquid methods

* Update genesis to only include 1 accrual time for earn

* Revert "Update genesis to only include 1 accrual time for earn"

This reverts commit cc7e35347298681c0c8a4a0b9bf9b9b296c25531.

* Revert "Use a single accural time for all earn incentives"

This reverts commit aeb49c4622d4e3d99dc6421c8830932b1b546be9.

* Update tests with incentive distribution

* Add earn to incentive rewards query

* add earn cli tx

* Update claim example to use ukava large

* Use underlying ukava to determine proportional reward amount

* Rename liquid methods to reflect derivative value

* Add tests for derivative values

* Return error to panic in BeginBlocker

Co-authored-by: karzak <kjydavis3@gmail.com>
2022-09-28 13:20:01 -07:00

402 lines
12 KiB
Go

package cli
import (
"fmt"
"strings"
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/kava-labs/kava/x/incentive/types"
)
const (
flagOwner = "owner"
flagType = "type"
flagUnsynced = "unsynced"
flagDenom = "denom"
typeDelegator = "delegator"
typeHard = "hard"
typeUSDXMinting = "usdx-minting"
typeSwap = "swap"
typeSavings = "savings"
typeEarn = "earn"
)
var rewardTypes = []string{typeDelegator, typeHard, typeUSDXMinting, typeSwap, typeEarn}
// GetQueryCmd returns the cli query commands for the incentive module
func GetQueryCmd() *cobra.Command {
incentiveQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the incentive module",
}
cmds := []*cobra.Command{
queryParamsCmd(),
queryRewardsCmd(),
queryRewardFactorsCmd(),
}
for _, cmd := range cmds {
flags.AddQueryFlagsToCmd(cmd)
}
incentiveQueryCmd.AddCommand(cmds...)
return incentiveQueryCmd
}
func queryRewardsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "rewards",
Short: "query claimable rewards",
Long: strings.TrimSpace(
fmt.Sprintf(`Query rewards with optional flags for owner and type
Example:
$ %[1]s query %[2]s rewards
$ %[1]s query %[2]s rewards --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
$ %[1]s query %[2]s rewards --type hard
$ %[1]s query %[2]s rewards --type usdx-minting
$ %[1]s query %[2]s rewards --type delegator
$ %[1]s query %[2]s rewards --type swap
$ %[1]s query %[2]s rewards --type savings
$ %[1]s query %[2]s rewards --type earn
$ %[1]s query %[2]s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
$ %[1]s query %[2]s rewards --type hard --unsynced
`,
version.AppName, types.ModuleName)),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
page, _ := cmd.Flags().GetInt(flags.FlagPage)
limit, _ := cmd.Flags().GetInt(flags.FlagLimit)
strOwner, _ := cmd.Flags().GetString(flagOwner)
strType, _ := cmd.Flags().GetString(flagType)
boolUnsynced, _ := cmd.Flags().GetBool(flagUnsynced)
// Prepare params for querier
var owner sdk.AccAddress
if strOwner != "" {
if owner, err = sdk.AccAddressFromBech32(strOwner); err != nil {
return err
}
}
switch strings.ToLower(strType) {
case typeHard:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeHardRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
case typeUSDXMinting:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeUSDXMintingRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
case typeDelegator:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeDelegatorRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
case typeSwap:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeSwapRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
case typeSavings:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeSavingsRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
case typeEarn:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
claims, err := executeEarnRewardsQuery(cliCtx, params)
if err != nil {
return err
}
return cliCtx.PrintObjectLegacy(claims)
default:
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
hardClaims, err := executeHardRewardsQuery(cliCtx, params)
if err != nil {
return err
}
usdxMintingClaims, err := executeUSDXMintingRewardsQuery(cliCtx, params)
if err != nil {
return err
}
delegatorClaims, err := executeDelegatorRewardsQuery(cliCtx, params)
if err != nil {
return err
}
swapClaims, err := executeSwapRewardsQuery(cliCtx, params)
if err != nil {
return err
}
savingsClaims, err := executeSavingsRewardsQuery(cliCtx, params)
if err != nil {
return err
}
earnClaims, err := executeEarnRewardsQuery(cliCtx, params)
if err != nil {
return err
}
if len(hardClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(hardClaims); err != nil {
return err
}
}
if len(usdxMintingClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(usdxMintingClaims); err != nil {
return err
}
}
if len(delegatorClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(delegatorClaims); err != nil {
return err
}
}
if len(swapClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(swapClaims); err != nil {
return err
}
}
if len(savingsClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(savingsClaims); err != nil {
return err
}
}
if len(earnClaims) > 0 {
if err := cliCtx.PrintObjectLegacy(earnClaims); err != nil {
return err
}
}
}
return nil
},
}
cmd.Flags().String(flagOwner, "", "(optional) filter by owner address")
cmd.Flags().String(flagType, "", fmt.Sprintf("(optional) filter by a reward type: %s", strings.Join(rewardTypes, "|")))
cmd.Flags().Bool(flagUnsynced, false, "(optional) get unsynced claims")
cmd.Flags().Int(flags.FlagPage, 1, "pagination page rewards of to to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of rewards to query for")
return cmd
}
func queryParamsCmd() *cobra.Command {
return &cobra.Command{
Use: "params",
Short: "get the incentive module parameters",
Long: "Get the current global incentive module parameters.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
// Query
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetParams)
res, height, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
// Decode and print results
var params types.Params
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &params); err != nil {
return fmt.Errorf("failed to unmarshal params: %w", err)
}
return cliCtx.PrintObjectLegacy(params)
},
}
}
func queryRewardFactorsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "reward-factors",
Short: "get current global reward factors",
Long: `Get current global reward factors for all reward types.`,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
// Execute query
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetRewardFactors)
res, height, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
// Decode and print results
var response types.QueryGetRewardFactorsResponse
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &response); err != nil {
return fmt.Errorf("failed to unmarshal reward factors: %w", err)
}
return cliCtx.PrintObjectLegacy(response)
},
}
cmd.Flags().String(flagDenom, "", "(optional) filter reward factors by denom")
return cmd
}
func executeHardRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.HardLiquidityProviderClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.HardLiquidityProviderClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetHardRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.HardLiquidityProviderClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.HardLiquidityProviderClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.HardLiquidityProviderClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeUSDXMintingRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.USDXMintingClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.USDXMintingClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetUSDXMintingRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.USDXMintingClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.USDXMintingClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.USDXMintingClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeDelegatorRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.DelegatorClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.DelegatorClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetDelegatorRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.DelegatorClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.DelegatorClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.DelegatorClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeSwapRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.SwapClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.SwapClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetSwapRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.SwapClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.SwapClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.SwapClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeSavingsRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.SavingsClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.SavingsClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetSavingsRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.SavingsClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.SavingsClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.SavingsClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}
func executeEarnRewardsQuery(cliCtx client.Context, params types.QueryRewardsParams) (types.EarnClaims, error) {
bz, err := cliCtx.LegacyAmino.MarshalJSON(params)
if err != nil {
return types.EarnClaims{}, err
}
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetEarnRewards)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return types.EarnClaims{}, err
}
cliCtx = cliCtx.WithHeight(height)
var claims types.EarnClaims
if err := cliCtx.LegacyAmino.UnmarshalJSON(res, &claims); err != nil {
return types.EarnClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
}
return claims, nil
}