Skip to main content
Version: v0.18

Mint Module


The Mint module is responsible for the flexible creation of tokens. These tokens serve various purposes such as rewarding validators, incentivizing liquidity provision in pools, motivating DApp developers on Pryzm, financing feeders who contribute to the oracle process, rewarding developers for maintaining and enhancing Pryzm, and funding community and treasury fee pools.


The Mint module facilitates the periodic creation of new tokens within a chain. The approach adopted by Pryzm includes:

  • Minting new tokens once per epoch (default is one week), using time-based epochs supported by the epochs module.
  • Allowing for a flexible inflation rate, determined by market demand, targeting a specific bonded-stake ratio.
  • Achieving a balance between market liquidity and staked supply.

The Mint module uses a moving change rate mechanism to determine the suitable market rate for inflation rewards. This mechanism ensures that if the percentage of bonded tokens is either above or below the target percentage, the inflation rate will adjust to either encourage or discourage bonding.

Setting the target percentage of bonded tokens at less than 100% prompts the network to maintain some non-staked tokens, aiding liquidity. The mechanism operates in three parts:

  • If the inflation rate is below the target percentage, the rate will increase until it reaches a maximum value.
  • If the target percentage (default is 67%) is maintained, the inflation rate will remain constant.
  • If the inflation rate is above the target percentage, the rate will decrease until it reaches a minimum value.



This function recalculates the minting parameters and disburses inflation at the end of each epoch, signaled by the epochs module. The function is represented below in pseudocode:

func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) error {
params := k.GetParams(ctx)
if epochIdentifier != params.EpochIdentifier {
return nil
// not distribute rewards if it's not time yet for rewards distribution
if epochNumber < params.MintingRewardsDistributionStartEpoch {
return nil

epochsPerYear := int64(yearSeconds / k.epochsKeeper.GetEpochInfo(ctx, epochIdentifier).Duration.Seconds())
bondedRatio := k.stakingKeeper.BondedRatio(ctx)

// recalculate minter properties
minter, err := k.updateMinter(ctx, params, bondedRatio, epochsPerYear)
if err != nil {

// mint coins
mintedCoin, err := k.mintCoin(ctx, minter, params.MintDenom, epochsPerYear)
if err != nil {

// distribute minted coins
distributedAmounts, err := k.distributeMintedCoin(ctx, *mintedCoin)
if err != nil {
return nil



The inflation rate is calculated using an "inflation calculation function" that is passed to the NewAppModule function. If no function is provided, the default inflation function (NextInflationRate) is used. For custom inflation calculation logic, define and pass a function that matches the InflationCalculationFn signature.

type InflationCalculationFn func(ctx sdk.Context, minter Minter, params Params, bondedRatio sdk.Dec, epochsPerYear int64) sdk.Dec


The target annual inflation rate is recalculated every epoch. It can increase or decrease based on its deviation from the target ratio of 67%. The maximum allowable rate change is 13% per year, yet the annual inflation rate is confined between 7% and 20%.

func (m Minter) NextInflationRate(params Params, bondedRatio sdk.Dec, epochsPerYear int64) sdk.Dec {
// (1 - bondedRatio/GoalBonded) * InflationRateChange
inflationRateChangePerYear := sdk.OneDec().

inflationRateChange := inflationRateChangePerYear.Quo(sdk.NewDec(epochsPerYear))

// adjust the new annual inflation for this next cycle
inflation := m.Inflation.Add(inflationRateChange) // note inflationRateChange may be negative
if inflation.GT(params.InflationMax) {
inflation = params.InflationMax
if inflation.LT(params.InflationMin) {
inflation = params.InflationMin

return inflation


The annual provisions are calculated once per epoch using the current total supply and inflation rate.

func (m Minter) NextAnnualProvisions(totalSupply math.Int) sdk.Dec {
return m.Inflation.MulInt(totalSupply)


This function calculates the provisions for each epoch using the current annual provisions. The mint module's ModuleMinterAccount then mints the provisions and distributes them to specified accounts with the distributeMintedCoin function.

func (m Minter) EpochProvisions(mintDenom string, epochsPerYear int64) sdk.Coin {
provisionAmt := m.AnnualProvisions.QuoInt(sdk.NewInt(epochsPerYear))
return sdk.NewCoin(mintDenom, provisionAmt.TruncateInt())


This function calculates the inflation and annual provisions, and then updates the minter state.

func (k Keeper) updateMinter(ctx sdk.Context, params types.Params, bondedRatio sdk.Dec, epochsPerYear int64) (*types.Minter, error) {
totalStakingSupply := k.stakingKeeper.StakingTokenSupply(ctx)
minter := k.GetMinter(ctx)
minter.Inflation = k.inflationCalculator(ctx, minter, params, bondedRatio, epochsPerYear)
minter.AnnualProvisions = minter.NextAnnualProvisions(totalStakingSupply)
err := k.setMinter(ctx, minter)
if err != nil {
return nil, err
return &minter, nil


This function computes the amount to transfer to each account based on the DistributionProportions parameters. Registered hooks are invoked after each transfer.

func (k Keeper) distributeMintedCoin(ctx sdk.Context, mintedCoin sdk.Coin) (_ *types.DistributionProportions, err error)


The module supports numerous hooks that notify relevant modules about the distributed quantities of minted coins:

type MintHooks interface {
AfterDistributeMintedCoin(ctx sdk.Context, amount sdk.Coin)
OnStakingPortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnPoolIncentivesPortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnOperationsAndDevelopmentPortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnDappPortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnOraclePortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnTreasuryPortionDistributed(ctx sdk.Context, amount sdk.Coin)
OnCommunityPoolPortionDistributed(ctx sdk.Context, amount sdk.Coin)

Modules keen on these notifications should implement the above interface and register the implementation in app.go:




MsgUpdateParams is a governance operation for updating the module's parameters.

message MsgUpdateParams {
string authority = 1;
Params params = 2;

The structure and definitions of the module parameters are detailed in the Parameters section.


MsgDappAccountSpend allows the transfer of tokens from the DApp account in the mint module to another account. It includes fields for the authority, title and description of the message, the recipient account's address, and the amount of tokens to be transferred.

message MsgDappAccountSpend {
string authority = 1;
string title = 2;
string description = 3;
string recipient = 4;
repeated cosmos.base.v1beta1.Coin amount = 5 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = ""



A query to retrieve the current module parameters.

message QueryParamsRequest {}

message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];

The CLI command is also supported:

pryzmd query mint params


A query to fetch the minter's current state.

message QueryMinterRequest {}

message QueryMinterResponse {
Minter minter = 1 [(gogoproto.nullable) = false];

The CLI command is also supported:

pryzmd query mint minter


The EventMint is triggered when a mint epoch has successfully completed. It indicates that total_minted tokens of type MintDenom have been minted and distributed at the end of epoch number epoch_number, with the distributed amounts detailed in distributed_amounts.

message EventMint {
Minter minter = 1;
string bonded_ratio = 2;
string total_minted = 3;
DistributionProportions distributed_amounts = 4;
int64 epoch_number = 5;

message DistributionProportions {
string staking = 1;
string pool_incentives = 2;
string operations_and_development = 3;
string dapp = 4;
string oracle = 5;
string treasury = 6;
string community = 7;



Parameters are stored with this store key:

) -> ProtoBuf(Params)


The Minter data structure stores the current inflation information.

message Minter {
string inflation = 1; // sdk.Dec
// current annual expected provisions
string annual_provisions = 2; // sdk.Dec

The minter is stored with a key:



type Params struct {
MintDenom string
InflationRateChange sdk.Dec
InflationMax sdk.Dec
InflationMin sdk.Dec
GoalBonded sdk.Dec
EpochIdentifier string
MintingRewardsDistributionStartEpoch int64
DistributionProportions DistributionProportions
GenesisEpochProvisions sdk.Dec
OperationsAndDevelopmentAccountAddress string

type DistributionProportions struct {
Staking sdk.Dec
PoolIncentives sdk.Dec
OperationsAndDevelopment sdk.Dec
Dapp sdk.Dec
Oracle sdk.Dec
Treasury sdk.Dec
Community sdk.Dec


Defines the type of coin to mint.

  • type: string
  • default: upryzm


Sets the maximum annual change in the inflation rate.

  • type: sdk.Dec
  • range: [0, 1)
  • default: 0.13


Sets the maximum inflation rate.

  • type: sdk.Dec
  • range: [0, 1)
  • default: 0.20


Sets the minimum inflation rate.

  • type: sdk.Dec
  • range: [0, 1)
  • default: 0.07


Sets the goal for the percentage of bonded upryzms.

  • type: sdk.Dec
  • range: (0, 1)
  • default: 0.67


Sets the mint epoch identifier.

  • type: string
  • range: week, day, or hour
  • default: week


Sets the start epoch for distributing minting rewards.

  • type: int64
  • range: [0, inf)
  • default: 0


Sets the epoch provisions from the first epoch.

  • type: sdk.Dec
  • range: [0, inf)
  • default: 5000000


Identifies the account address that receives the minted operations and development rewards.

  • type: string
  • default: empty


Defines the distribution ratios of the minted denom, determining the recipients of the minted denoms and their proportions.


Sets the proportion of the minted MintDenom allocated as staking rewards.

  • type: sdk.Dec
  • range: [0, inf)
  • default: 0


This denotes the fraction of minted MintDenom allocated as pool incentives.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0


This denotes the fraction of minted MintDenom allocated to the operations and development account address.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0


This denotes the fraction of minted MintDenom allocated to DApp developers.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0


This denotes the fraction of minted MintDenom allocated to oracle feeders.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0


This denotes the fraction of minted MintDenom allocated to treasury.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0.5


This denotes the fraction of minted MintDenom allocated to community pool.

  • Type: sdk.Dec
  • Range: [0, inf)
  • Default value: 0.5


The genesis state for the mint module may contain values for the Parameters of the module and the Minter. The genesis state's full structure is as follows:

message GenesisState {
Params params = 1;
Minter minter = 2;