From b2aae0030139bfff825d58d7c2fe27bc99e83866 Mon Sep 17 00:00:00 2001 From: Derrick Lee Date: Wed, 1 Sep 2021 08:21:31 -0700 Subject: [PATCH] Add circulating supply endpoint for SWP (#1015) * Add circulating supply endpoint for SWP * Fix team SWP amount --- x/validator-vesting/client/cli/query.go | 27 +++++++ x/validator-vesting/client/rest/query.go | 43 +++++++++++ x/validator-vesting/keeper/querier.go | 93 ++++++++++++++++++++++++ x/validator-vesting/types/querier.go | 1 + 4 files changed, 164 insertions(+) diff --git a/x/validator-vesting/client/cli/query.go b/x/validator-vesting/client/cli/query.go index a6f83ca3..7f96b507 100644 --- a/x/validator-vesting/client/cli/query.go +++ b/x/validator-vesting/client/cli/query.go @@ -24,6 +24,7 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command { queryTotalSupply(queryRoute, cdc), queryCirculatingSupplyHARD(queryRoute, cdc), queryCirculatingSupplyUSDX(queryRoute, cdc), + queryCirculatingSupplySWP(queryRoute, cdc), queryTotalSupplyHARD(queryRoute, cdc), queryTotalSupplyUSDX(queryRoute, cdc), )...) @@ -136,6 +137,32 @@ func queryCirculatingSupplyUSDX(queryRoute string, cdc *codec.Codec) *cobra.Comm } } +func queryCirculatingSupplySWP(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "circulating-supply-swp", + Short: "Get SWP circulating supply", + Long: "Get the current circulating supply of SWP tokens", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + // Query + res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryCirculatingSupplySWP), nil) + if err != nil { + return err + } + cliCtx = cliCtx.WithHeight(height) + + // Decode and print results + var out int64 + if err := cdc.UnmarshalJSON(res, &out); err != nil { + return fmt.Errorf("failed to unmarshal supply: %w", err) + } + return cliCtx.PrintOutput(out) + }, + } +} + func queryTotalSupplyHARD(queryRoute string, cdc *codec.Codec) *cobra.Command { return &cobra.Command{ Use: "total-supply-hard", diff --git a/x/validator-vesting/client/rest/query.go b/x/validator-vesting/client/rest/query.go index 09e8bdb5..3e7189d8 100644 --- a/x/validator-vesting/client/rest/query.go +++ b/x/validator-vesting/client/rest/query.go @@ -18,6 +18,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) { r.HandleFunc(fmt.Sprintf("/%s/totalsupply", types.QueryPath), getTotalSupplyHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/circulatingsupplyhard", types.QueryPath), getCirculatingSupplyHARDHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/circulatingsupplyusdx", types.QueryPath), getCirculatingSupplyUSDXHandlerFn(cliCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/%s/circulatingsupplyswp", types.QueryPath), getCirculatingSupplySWPHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/totalsupplyhard", types.QueryPath), getTotalSupplyHARDHandlerFn(cliCtx)).Methods("GET") r.HandleFunc(fmt.Sprintf("/%s/totalsupplyusdx", types.QueryPath), getTotalSupplyUSDXHandlerFn(cliCtx)).Methods("GET") } @@ -189,6 +190,48 @@ func getCirculatingSupplyUSDXHandlerFn(cliCtx context.CLIContext) http.HandlerFu } } +func getCirculatingSupplySWPHandlerFn(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 + } + + params := types.NewBaseQueryParams(page, limit) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err)) + return + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryCirculatingSupplySWP) + res, _, err := cliCtx.QueryWithData(route, bz) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + var circSupply int64 + err = cliCtx.Codec.UnmarshalJSON(res, &circSupply) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + resBytes, err := json.Marshal(circSupply) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + w.Write(resBytes) + } +} + func getTotalSupplyHARDHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { _, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0) diff --git a/x/validator-vesting/keeper/querier.go b/x/validator-vesting/keeper/querier.go index 296b72b9..85462f59 100644 --- a/x/validator-vesting/keeper/querier.go +++ b/x/validator-vesting/keeper/querier.go @@ -25,6 +25,8 @@ func NewQuerier(keeper Keeper) sdk.Querier { return getCirculatingSupplyHARD(ctx, req, keeper) case types.QueryCirculatingSupplyUSDX: return getCirculatingSupplyUSDX(ctx, req, keeper) + case types.QueryCirculatingSupplySWP: + return getCirculatingSupplySWP(ctx, req, keeper) case types.QueryTotalSupplyHARD: return getTotalSupplyHARD(ctx, req, keeper) case types.QueryTotalSupplyUSDX: @@ -279,6 +281,97 @@ func getCirculatingSupplyUSDX(ctx sdk.Context, req abci.RequestQuery, keeper Kee return bz, nil } +func getCirculatingSupplySWP(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, error) { + // Start values + year := 2021 + month := 8 + + var supplyIncreaseDates []time.Time + + // Add month times for 4 years + for i := 0; i < 12*4; i++ { + // Always day 30 unless it's Feb + day := 30 + if month == 2 { + day = 28 + } + + date := time.Date(year, time.Month(month), day, 15 /* hour */, 0, 0, 0, time.UTC) + supplyIncreaseDates = append(supplyIncreaseDates, date) + + // Update year and month + if month == 12 { + month = 1 + year += 1 + } else { + month += 1 + } + } + + // Repeated tokens released + teamSwp := int64(4_687_500) + treasurySwp := int64(5_859_375) + monthlyStakersSwp := int64(520_833) + monthlyLPIncentivesSwp := int64(2_343_750) + + // []{Ecosystem, Team, Treasury, Kava Stakers, LP Incentives} + scheduleAmounts := [][]int64{ + {12_500_000, 0, 15_625_000, monthlyStakersSwp, monthlyLPIncentivesSwp}, // *** Year ONE *** + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 1 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 2 + {0, 0, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 3 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 4 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 5 + {0, 0, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 6 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 7 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 8 + {0, 0, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 9 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 10 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 11 + {0, 18_750_000, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // *** Year TWO *** + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 13 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 14 + {0, teamSwp, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 15 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 16 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 17 + {0, teamSwp, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 18 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 19 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 20 + {0, teamSwp, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 21 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 22 + {0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}, // 23 + {0, teamSwp, treasurySwp, monthlyStakersSwp, monthlyLPIncentivesSwp}, // *** Year THREE *** + } + + // Months 25-47 are the same + for i := 0; i < 23; i++ { + scheduleAmounts = append(scheduleAmounts, []int64{0, 0, 0, monthlyStakersSwp, monthlyLPIncentivesSwp}) + } + + circSupply := sdk.ZeroInt() + blockTime := ctx.BlockTime() + + for i := 0; i < len(scheduleAmounts); i++ { + if blockTime.Before(supplyIncreaseDates[i]) { + break + } + + // Sum up each category of token release + monthTotal := int64(0) + for _, val := range scheduleAmounts[i] { + monthTotal += val + } + + circSupply = circSupply.Add(sdk.NewInt(monthTotal)) + } + + bz, err := keeper.cdc.MarshalJSON(circSupply) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + return bz, nil +} + func getTotalSupplyHARD(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, error) { totalSupply := keeper.supplyKeeper.GetSupply(ctx).GetTotal().AmountOf("hard") supplyInt := sdk.NewDecFromInt(totalSupply).Mul(sdk.MustNewDecFromStr("0.000001")).TruncateInt64() diff --git a/x/validator-vesting/types/querier.go b/x/validator-vesting/types/querier.go index cb43de4c..465435f3 100644 --- a/x/validator-vesting/types/querier.go +++ b/x/validator-vesting/types/querier.go @@ -6,6 +6,7 @@ const ( QueryTotalSupply = "total-supply" QueryCirculatingSupplyHARD = "circulating-supply-hard" QueryCirculatingSupplyUSDX = "circulating-supply-usdx" + QueryCirculatingSupplySWP = "circulating-supply-swp" QueryTotalSupplyHARD = "total-supply-hard" QueryTotalSupplyUSDX = "total-supply-usdx" )