Skip to content

Commit

Permalink
Implement tax caps querier for all whitelisted denoms (#442)
Browse files Browse the repository at this point in the history
* add tax_caps querier
* add client interface & swagger update

Co-authored-by: Paul Kim <[email protected]>
  • Loading branch information
yys and hanjukim authored Feb 9, 2021
1 parent 0d928e4 commit 2ddf402
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 1 deletion.
2 changes: 1 addition & 1 deletion client/lcd/statik/statik.go

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions client/lcd/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2624,6 +2624,22 @@ paths:
example: "100000"
404:
description: Not Found
/treasury/tax_caps:
get:
summary: Get tax caps for the all whitelisted denoms
tags:
- Treasury
produces:
- application/json
responses:
200:
description: OK
schema:
type: array
items:
$ref: "#/definitions/TaxCap"
404:
description: Not Found
/treasury/reward_weight:
get:
summary: Get current reward weight
Expand Down Expand Up @@ -4229,3 +4245,12 @@ definitions:
type: array
items:
$ref: "#/definitions/Msg"
TaxCap:
type: object
properties:
denom:
type: string
example: uluna
tax_cap:
type: string
example: "50"
30 changes: 30 additions & 0 deletions x/treasury/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command {
oracleQueryCmd.AddCommand(flags.GetCommands(
GetCmdQueryTaxRate(cdc),
GetCmdQueryTaxCap(cdc),
GetCmdQueryTaxCaps(cdc),
GetCmdQueryRewardWeight(cdc),
GetCmdQueryParams(cdc),
GetCmdQueryTaxProceeds(cdc),
Expand Down Expand Up @@ -105,6 +106,35 @@ $ terracli query treasury tax-cap ukrw
return cmd
}

// GetCmdQueryTaxCaps implements the query tax-caps command.
func GetCmdQueryTaxCaps(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "tax-caps",
Args: cobra.NoArgs,
Short: "Query the current stability tax caps for all denom assets",
Long: strings.TrimSpace(`
Query the current stability tax caps of the all denom assets.
The stability tax levied on a tx is at most tax cap, regardless of the size of the transaction.
$ terracli query treasury tax-caps
`),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)

res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryTaxCaps), nil)
if err != nil {
return err
}

var taxCaps types.TaxCapsQueryResponse
cdc.MustUnmarshalJSON(res, &taxCaps)
return cliCtx.PrintOutput(taxCaps)
},
}

return cmd
}

// GetCmdQueryRewardWeight implements the query reward-weight command.
func GetCmdQueryRewardWeight(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Expand Down
19 changes: 19 additions & 0 deletions x/treasury/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
func registerQueryRoute(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc("/treasury/tax_rate", queryTaxRateHandlerFunction(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/treasury/tax_cap/{%s}", RestDenom), queryTaxCapHandlerFunction(cliCtx)).Methods("GET")
r.HandleFunc("/treasury/tax_caps", queryTaxCapsHandlerFunction(cliCtx)).Methods("GET")
r.HandleFunc("/treasury/reward_weight", queryRewardWeightHandlerFunction(cliCtx)).Methods("GET")
r.HandleFunc("/treasury/tax_proceeds", queryTaxProceedsHandlerFunction(cliCtx)).Methods("GET")
r.HandleFunc("/treasury/seigniorage_proceeds", querySeigniorageProceedsHandlerFunction(cliCtx)).Methods("GET")
Expand Down Expand Up @@ -63,6 +64,24 @@ func queryTaxCapHandlerFunction(cliCtx context.CLIContext) http.HandlerFunc {
}
}

func queryTaxCapsHandlerFunction(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}

res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryTaxCaps), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}

cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}

func queryRewardWeightHandlerFunction(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
Expand Down
20 changes: 20 additions & 0 deletions x/treasury/internal/keeper/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ func NewQuerier(keeper Keeper) sdk.Querier {
return queryTaxRate(ctx, keeper)
case types.QueryTaxCap:
return queryTaxCap(ctx, req, keeper)
case types.QueryTaxCaps:
return queryTaxCaps(ctx, keeper)
case types.QueryRewardWeight:
return queryRewardWeight(ctx, keeper)
case types.QuerySeigniorageProceeds:
Expand Down Expand Up @@ -107,6 +109,24 @@ func queryTaxCap(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte,
return bz, nil
}

func queryTaxCaps(ctx sdk.Context, keeper Keeper) ([]byte, error) {
var taxCaps types.TaxCapsQueryResponse
keeper.IterateTaxCap(ctx, func(denom string, taxCap sdk.Int) bool {
taxCaps = append(taxCaps, types.TaxCapsResponseItem{
Denom: denom,
TaxCap: taxCap,
})
return false
})

bz, err := codec.MarshalJSONIndent(keeper.cdc, taxCaps)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}

return bz, nil
}

func queryRewardWeight(ctx sdk.Context, keeper Keeper) ([]byte, error) {
taxRate := keeper.GetRewardWeight(ctx)
bz, err := codec.MarshalJSONIndent(keeper.cdc, taxRate)
Expand Down
47 changes: 47 additions & 0 deletions x/treasury/internal/keeper/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ func getQueriedTaxCap(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier s
return response
}

func getQueriedTaxCaps(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier) types.TaxCapsQueryResponse {
query := abci.RequestQuery{
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryTaxCaps}, "/"),
Data: nil,
}

bz, err := querier(ctx, []string{types.QueryTaxCaps}, query)
require.Nil(t, err)
require.NotNil(t, bz)

var response types.TaxCapsQueryResponse
err2 := cdc.UnmarshalJSON(bz, &response)
require.Nil(t, err2)

return response
}

func getQueriedRewardWeight(t *testing.T, ctx sdk.Context, cdc *codec.Codec, querier sdk.Querier, epoch int64) sdk.Dec {
query := abci.RequestQuery{
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryRewardWeight}, "/"),
Expand Down Expand Up @@ -191,6 +208,36 @@ func TestQueryTaxCap(t *testing.T) {
require.Equal(t, queriedTaxCap, params.TaxPolicy.Cap.Amount)
}

func TestQueryTaxCaps(t *testing.T) {
input := CreateTestInput(t)
querier := NewQuerier(input.TreasuryKeeper)

input.TreasuryKeeper.SetTaxCap(input.Ctx, "ukrw", sdk.NewInt(1000000000))
input.TreasuryKeeper.SetTaxCap(input.Ctx, "usdr", sdk.NewInt(1000000))
input.TreasuryKeeper.SetTaxCap(input.Ctx, "uusd", sdk.NewInt(1200000))

// Get a currency super random; should default to policy coin.
queriedTaxCaps := getQueriedTaxCaps(t, input.Ctx, input.Cdc, querier)

require.Equal(t, queriedTaxCaps,
types.TaxCapsQueryResponse{
{
Denom: "ukrw",
TaxCap: sdk.NewInt(1000000000),
},
{
Denom: "usdr",
TaxCap: sdk.NewInt(1000000),
},

{
Denom: "uusd",
TaxCap: sdk.NewInt(1200000),
},
},
)
}

func TestQueryTaxProceeds(t *testing.T) {
input := CreateTestInput(t)
querier := NewQuerier(input.TreasuryKeeper)
Expand Down
10 changes: 10 additions & 0 deletions x/treasury/internal/types/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
const (
QueryTaxRate = "taxRate"
QueryTaxCap = "taxCap"
QueryTaxCaps = "taxCaps"
QueryRewardWeight = "rewardWeight"
QuerySeigniorageProceeds = "seigniorageProceeds"
QueryTaxProceeds = "taxProceeds"
Expand All @@ -30,6 +31,15 @@ func NewQueryTaxCapParams(denom string) QueryTaxCapParams {
}
}

// TaxCapsResponseItem query response item of tax caps querier
type TaxCapsResponseItem struct {
Denom string `json:"denom"`
TaxCap sdk.Int `json:"tax_cap"`
}

// TaxCapsQueryResponse query response body of tax caps querier
type TaxCapsQueryResponse []TaxCapsResponseItem

// IndicatorQueryResonse query response body
type IndicatorQueryResonse struct {
TRLYear sdk.Dec `json:"trl_year"`
Expand Down

0 comments on commit 2ddf402

Please sign in to comment.