Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add global_inflation_per_claim param to tokenomics module #951

Open
wants to merge 3 commits into
base: todo_beta/refactor/supplier_staking_fee
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 97 additions & 39 deletions api/poktroll/tokenomics/params.pulsar.go

Large diffs are not rendered by default.

142 changes: 109 additions & 33 deletions api/poktroll/tokenomics/tx.pulsar.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ genesis:
# This is the address that will receive the dao/foundation rewards during claim settlement (global mint TLM).
# TODO_MAINNET(@olshansk): Consolidate the usage of DAO/PNF throughout the configs & codebase.
dao_reward_address: "pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw"
global_inflation_per_claim: 0.1
shared:
params:
num_blocks_per_session: 10
Expand Down
8 changes: 8 additions & 0 deletions makefiles/params.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ params_update_tokenomics_all: ## Update the tokenomics module params
params_update_tokenomics_mint_allocation_percentages: ## Update the tokenomics module mint_allocation_percentages param
poktrolld tx authz exec ./tools/scripts/params/tokenomics_mint_allocation_percentages.json $(PARAM_FLAGS)

.PHONY: params_update_tokenomics_dao_reward_address
params_update_tokenomics_dao_reward_address: ## Update the tokenomics module dao_reward_address param
poktrolld tx authz exec ./tools/scripts/params/tokenomics_dao_reward_address.json $(PARAM_FLAGS)

.PHONY: params_update_tokenomics_global_inflation_per_claim
params_update_tokenomics_global_inflation_per_claim: ## Update the tokenomics module global_inflation_per_claim param
poktrolld tx authz exec ./tools/scripts/params/tokenomics_global_inflation_per_claim.json $(PARAM_FLAGS)

### Service Module Params ###
.PHONY: params_get_service
params_get_service: ## Get the service module params
Expand Down
3 changes: 3 additions & 0 deletions proto/poktroll/tokenomics/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ message Params {
// minted tokens are at the end of claim settlement.
string dao_reward_address = 6 [(cosmos_proto.scalar) = "cosmos.AddressString", (gogoproto.jsontag) = "dao_reward_address", (gogoproto.moretags) = "yaml:\"dao_reward_address\""]; // Bech32 cosmos address

// global_inflation_per_claim is the percentage of a claim's claimable uPOKT amount which will be minted on settlement.
double global_inflation_per_claim = 7 [(gogoproto.jsontag) = "global_inflation_per_claim", (gogoproto.moretags) = "yaml:\"global_inflation_per_claim\""];

// IMPORTANT: Make sure to update all related files if you're modifying or adding a new parameter.
// Try the following grep to find all related places: `grep -r compute_units_to_tokens_multiplier`
// TODO_IMPROVE: Look into an opportunity to use an enum to avoid using strings throughout the codebase.
Expand Down
1 change: 1 addition & 0 deletions proto/poktroll/tokenomics/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ message MsgUpdateParam {
oneof as_type {
MintAllocationPercentages as_mint_allocation_percentages = 3 [(gogoproto.jsontag) = "as_mint_allocation_percentages", (gogoproto.moretags) = "yaml:\"as_mint_allocation_percentages\""];
string as_string = 4 [(gogoproto.jsontag) = "as_string"];
double as_float = 5 [(gogoproto.jsontag) = "as_float"];
}
}

Expand Down
2 changes: 2 additions & 0 deletions testutil/integration/suites/param_configs.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,12 @@ var (
ValidParams: tokenomicstypes.Params{
MintAllocationPercentages: tokenomicstypes.DefaultMintAllocationPercentages,
DaoRewardAddress: sample.AccAddress(),
GlobalInflationPerClaim: 0.666,
},
ParamTypes: map[ParamType]any{
ParamTypeMintAllocationPercentages: tokenomicstypes.MsgUpdateParam_AsMintAllocationPercentages{},
ParamTypeString: tokenomicstypes.MsgUpdateParam_AsString{},
ParamTypeFloat64: tokenomicstypes.MsgUpdateParam_AsFloat{},
},
DefaultParams: tokenomicstypes.DefaultParams(),
NewParamClientFn: tokenomicstypes.NewQueryClient,
Expand Down
4 changes: 3 additions & 1 deletion tools/scripts/params/tokenomics_all.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"supplier": 0.7,
"source_owner": 0.15,
"application": 0.0
}
},
"dao_reward_address": "pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw",
"global_inflation_per_claim": 0.1
}
}
]
Expand Down
12 changes: 12 additions & 0 deletions tools/scripts/params/tokenomics_dao_reward_address.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"body": {
"messages": [
{
"@type": "/poktroll.tokenomics.MsgUpdateParam",
"authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t",
"name": "mint_allocation_percentages",
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
"as_string": "pokt1eeeksh2tvkh7wzmfrljnhw4wrhs55lcuvmekkw"
}
]
}
}
12 changes: 12 additions & 0 deletions tools/scripts/params/tokenomics_global_inflation_per_claim.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"body": {
"messages": [
{
"@type": "/poktroll.tokenomics.MsgUpdateParam",
"authority": "pokt10d07y265gmmuvt4z0w9aw880jnsr700j8yv32t",
"name": "mint_allocation_percentages",
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved
"as_float": 0.1
}
]
}
}
4 changes: 4 additions & 0 deletions x/tokenomics/keeper/msg_server_update_param.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package keeper

//
import (
"context"
"fmt"
Expand Down Expand Up @@ -38,6 +39,9 @@ func (k msgServer) UpdateParam(
case tokenomicstypes.ParamDaoRewardAddress:
logger = logger.With("param_value", msg.GetAsString())
params.DaoRewardAddress = msg.GetAsString()
case tokenomicstypes.ParamGlobalInflationPerClaim:
logger = logger.With("param_value", msg.GetAsFloat())
params.GlobalInflationPerClaim = msg.GetAsFloat()
default:
return nil, status.Error(
codes.InvalidArgument,
Expand Down
78 changes: 64 additions & 14 deletions x/tokenomics/keeper/msg_server_update_param_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,42 @@ import (
tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types"
)

func TestMsgUpdateParam_UpdateMintAllocationDaoOnly(t *testing.T) {
t.Skip("since the mint allocation percentages must sum to 1, it is not possible to modify only one of them")
}
func TestMsgUpdateParam_UpdateMintAllocationPercentagesOnly(t *testing.T) {
expectedMintAllocationPercentages := tokenomicstypes.MintAllocationPercentages{
Dao: 0.1,
Proposer: 0.2,
Supplier: 0.3,
SourceOwner: 0.4,
Application: 0.0,
}

func TestMsgUpdateParam_UpdateMintAllocationProposerOnly(t *testing.T) {
t.Skip("since the mint allocation percentages must sum to 1, it is not possible to modify only one of them")
}
// Set the parameters to their default values
k, msgSrv, ctx := setupMsgServer(t)
defaultParams := tokenomicstypes.DefaultParams()
require.NoError(t, k.SetParams(ctx, defaultParams))

func TestMsgUpdateParam_UpdateMintAllocationSupplierOnly(t *testing.T) {
t.Skip("since the mint allocation percentages must sum to 1, it is not possible to modify only one of them")
}
// Ensure the default values are different from the new values we want to set
require.NotEqual(t, expectedMintAllocationPercentages, defaultParams.MintAllocationPercentages)

func TestMsgUpdateParam_UpdateMintAllocationSourceOwnerOnly(t *testing.T) {
t.Skip("since the mint allocation percentages must sum to 1, it is not possible to modify only one of them")
}
// Update the mint allocation percentages.
updateParamMsg := &tokenomicstypes.MsgUpdateParam{
Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Name: tokenomicstypes.ParamMintAllocationPercentages,
AsType: &tokenomicstypes.MsgUpdateParam_AsMintAllocationPercentages{AsMintAllocationPercentages: &expectedMintAllocationPercentages},
}
res, err := msgSrv.UpdateParam(ctx, updateParamMsg)
require.NoError(t, err)

// Assert that the response contains the expected mint allocation percentages.
require.NotEqual(t, defaultParams.MintAllocationPercentages, res.Params.MintAllocationPercentages)
require.Equal(t, expectedMintAllocationPercentages, res.Params.MintAllocationPercentages)

func TestMsgUpdateParam_UpdateMintAllocationApplicationOnly(t *testing.T) {
t.Skip("since the mint allocation percentages must sum to 1, it is not possible to modify only one of them")
// Assert that the on-chain mint allocation percentages is updated.
params := k.GetParams(ctx)
require.Equal(t, expectedMintAllocationPercentages, params.MintAllocationPercentages)

// Ensure the other parameters are unchanged
testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, string(tokenomicstypes.KeyMintAllocationPercentages))
}

func TestMsgUpdateParam_UpdateDaoRewardAddressOnly(t *testing.T) {
Expand Down Expand Up @@ -63,3 +81,35 @@ func TestMsgUpdateParam_UpdateDaoRewardAddressOnly(t *testing.T) {
// Ensure the other parameters are unchanged
testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, string(tokenomicstypes.KeyDaoRewardAddress))
}

func TestMsgUpdateParam_UpdateGlobalInflationPerClaimOnly(t *testing.T) {
expectedGlobalInflationPerClaim := 0.666

// Set the parameters to their default values
k, msgSrv, ctx := setupMsgServer(t)
defaultParams := tokenomicstypes.DefaultParams()
require.NoError(t, k.SetParams(ctx, defaultParams))

// Ensure the default values are different from the new values we want to set
require.NotEqual(t, expectedGlobalInflationPerClaim, defaultParams.GlobalInflationPerClaim)

// Update the dao reward address.
updateParamMsg := &tokenomicstypes.MsgUpdateParam{
Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Name: tokenomicstypes.ParamGlobalInflationPerClaim,
AsType: &tokenomicstypes.MsgUpdateParam_AsFloat{AsFloat: expectedGlobalInflationPerClaim},
}
res, err := msgSrv.UpdateParam(ctx, updateParamMsg)
require.NoError(t, err)

// Assert that the response contains the expected dao reward address.
require.NotEqual(t, defaultParams.GlobalInflationPerClaim, res.Params.GlobalInflationPerClaim)
require.Equal(t, expectedGlobalInflationPerClaim, res.Params.GlobalInflationPerClaim)

// Assert that the on-chain dao reward address is updated.
params := k.GetParams(ctx)
require.Equal(t, expectedGlobalInflationPerClaim, params.GlobalInflationPerClaim)

// Ensure the other parameters are unchanged
testkeeper.AssertDefaultParamsEqualExceptFields(t, &defaultParams, res.Params, string(tokenomicstypes.KeyGlobalInflationPerClaim))
}
26 changes: 26 additions & 0 deletions x/tokenomics/keeper/msg_update_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,32 @@ func TestMsgUpdateParams(t *testing.T) {
shouldError: true,
expectedErrMsg: "empty address string is not allowed",
},
{
desc: "invalid: negative global inflation per claim",

req: &tokenomicstypes.MsgUpdateParams{
Authority: tokenomicsKeeper.GetAuthority(),
Params: tokenomicstypes.Params{
GlobalInflationPerClaim: -0.1,
bryanchriswhite marked this conversation as resolved.
Show resolved Hide resolved

// DaoRewardAddress MUST NOT be empty string
// when MintAllocationDao is greater than 0.
DaoRewardAddress: sample.AccAddress(),

// MintAllocationXXX params MUST sum to 1.
MintAllocationPercentages: tokenomicstypes.MintAllocationPercentages{
Dao: 0,
Proposer: 0.1,
Supplier: 0.1,
SourceOwner: 0.1,
Application: 0.7,
},
},
},

shouldError: true,
expectedErrMsg: "GlobalInflationPerClaim must be greater than or equal to 0:",
},
{
desc: "valid: successful param update",

Expand Down
36 changes: 36 additions & 0 deletions x/tokenomics/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,39 @@ func TestParams_ValidateDaoRewardAddress(t *testing.T) {
})
}
}

func TestParams_ValidateGlobalInflationPerClaim(t *testing.T) {
tests := []struct {
desc string
globalInflationPerClaim any
expectedErr error
}{
{
desc: "invalid type",
globalInflationPerClaim: float32(0.111),
expectedErr: tokenomicstypes.ErrTokenomicsParamInvalid.Wrap("invalid parameter type: float32"),
},
{
desc: "less than zero",
globalInflationPerClaim: float64(-0.1),
expectedErr: tokenomicstypes.ErrTokenomicsParamInvalid.Wrapf(
"GlobalInflationPerClaim must be greater than or equal to 0: %f", float64(-0.1),
),
},
{
desc: "valid GlobalInflationPerClaim",
globalInflationPerClaim: tokenomicstypes.DefaultGlobalInflationPerClaim,
},
}

for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
err := tokenomicstypes.ValidateGlobalInflationPerClaim(test.globalInflationPerClaim)
if test.expectedErr != nil {
require.ErrorContains(t, err, test.expectedErr.Error())
} else {
require.NoError(t, err)
}
})
}
}
19 changes: 9 additions & 10 deletions x/tokenomics/types/message_update_param.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ func NewMsgUpdateParam(authority string, name string, asTypeAny any) (*MsgUpdate
asTypeIface = &MsgUpdateParam_AsMintAllocationPercentages{AsMintAllocationPercentages: &asType}
case string:
asTypeIface = &MsgUpdateParam_AsString{AsString: asType}
case float64:
asTypeIface = &MsgUpdateParam_AsFloat{AsFloat: asType}
default:
return nil, fmt.Errorf("unexpected param value type: %T", asTypeAny)
}
Expand Down Expand Up @@ -44,28 +46,25 @@ func (msg *MsgUpdateParam) ValidateBasic() error {
// Parameter name must be supported by this module.
switch msg.Name {
case ParamMintAllocationPercentages:
if err := msg.paramTypeIsMintAllocationPercentages(); err != nil {
if err := genericParamTypeIs[*MsgUpdateParam_AsMintAllocationPercentages](msg); err != nil {
return err
}
return ValidateMintAllocationPercentages(*msg.GetAsMintAllocationPercentages())
case ParamDaoRewardAddress:
if err := msg.paramTypeIsString(); err != nil {
if err := genericParamTypeIs[*MsgUpdateParam_AsString](msg); err != nil {
return err
}
return ValidateDaoRewardAddress(msg.GetAsString())
case ParamGlobalInflationPerClaim:
if err := genericParamTypeIs[*MsgUpdateParam_AsFloat](msg); err != nil {
return err
}
return ValidateGlobalInflationPerClaim(msg.GetAsFloat())
default:
return ErrTokenomicsParamNameInvalid.Wrapf("unsupported param %q", msg.Name)
}
}

func (msg *MsgUpdateParam) paramTypeIsMintAllocationPercentages() error {
return genericParamTypeIs[*MsgUpdateParam_AsMintAllocationPercentages](msg)
}

func (msg *MsgUpdateParam) paramTypeIsString() error {
return genericParamTypeIs[*MsgUpdateParam_AsString](msg)
}

// genericTypeIsCoin checks if the parameter type is T, returning an error if not.
func genericParamTypeIs[T any](msg *MsgUpdateParam) error {
if _, ok := msg.AsType.(T); !ok {
Expand Down
11 changes: 11 additions & 0 deletions x/tokenomics/types/message_update_param_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ func TestMsgUpdateParam_ValidateBasic(t *testing.T) {
},
expectedErr: ErrTokenomicsParamInvalid,
},
{
name: "invalid: global inflation per claim less than 0",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just now noticing the constraint in this comment:
image

Add a case equal to 0.

msg: MsgUpdateParam{
Authority: sample.AccAddress(),
Name: ParamGlobalInflationPerClaim,
AsType: &MsgUpdateParam_AsFloat{
AsFloat: -0.1,
},
},
expectedErr: ErrTokenomicsParamInvalid,
},
{
name: "valid: correct address, param name, and type",
msg: MsgUpdateParam{
Expand Down
Loading
Loading