Skip to main content

Spending Pools

Overview

Spending pools are KIRA’s native token distribution system, providing a way to distribute a pooled amount of one or multiple tokens to a predefined set of accounts at a predefined rate over a specific period. They can operate in two distinct modes for the rate of distribution: a fixed rate mode and a dynamic rate mode, providing flexibility and customization options for different use cases.

Spending pools are an essential tool for incentivizing network actors such as developers or community managers for their contributions. They are permissionless, allowing any KIRA account to create one and associate it with one or more "owners," which can be governance-defined roles or individual KIRA accounts. Accounts that are eligible to claim rewards from the spending pool are called "beneficiaries" and can also be defined as roles or individual KIRA accounts. One of the primary use cases for spending pools is the distribution of Universal Basic Income to KIRA consensus nodes and governance members. Additionally, they are also utilized by the Staking Collective module as a means to redistribute staking rewards.

Distribution Rates

Static Mode

This spending pool mechanism is straightforward - it consists of a distribution rate and a period. Instead of tracking the exact amount owed to each account over time, it simply keeps track of the last time that an account has made a claim within the claiming period. This information is sufficient to calculate an account's current entitlement by multiplying the distribution rate by the time elapsed since the last claim. Spending pools can accommodate the distribution of multiple different tokens. Any token can be deposited and their individual distribution rate can be accurately set, ensuring that the tokens are distributed as intended over the claiming period.

note

If a token is deposited into the pool but its static rate is not defined, it will not be distributed to any beneficiaries (similar to setting its rate to zero).

Dynamic Mode

The dynamic token rate mechanism, enabled by the dynamic-rate field, allows for the proper distribution of tokens over the claiming period, even when the amount of tokens deposited within that period is unpredictable or fluctuating, which would otherwise require continuous rate adjustments. If dynamic-rate is set to false, the spending pool operates in the static rate mode. When it is enabled, the dynamic-rate-period field determines how often the token rates are recalculated, measured in seconds (Unix).

In this mode, rates of distribution are re-adjusted at the end of each dynamic-rate-period to ensure the complete allocation of pooled funds by the conclusion of the subsequent period. Therefore, any fund contributions made to the pool after the rate recalibration will effectively be accounted for in the following period. For beneficiaries, it is essential to make a claim at least once within the current dynamic-rate-period, and ideally at its closure in order to get the full entitlement; beneficiaries who fail to claim their due rewards within a dynamic period effectively forfeit their share (or remaining share) for that period, which is then redistributed in the next period's calculations. It also implies that beneficiaries who register cannot claim during the ongoing period and must wait until the next one to starts to do so, to effectively receive tokens from the pool. The Staking Collectives module is an example of where this mechanism is necessary, as it works in conjunction with the Spending Pool module to redistribute staking rewards which are unpredictable by nature.

Claiming Period

The simplicity of the spending pool mechanism also allows for flexibility in claiming. Unlike traditional wage systems where one typically has to wait until the end of a specific period (usually a month) to receive their earnings, with a spending pool, an account can claim multiple times within the defined claiming period. This allows for a more dynamic and responsive distribution of funds, catering to the needs of the beneficiaries while still ensuring that the tokens are being distributed properly. The claim-start and claim-end parameters define the claiming period during which tokens can be claimed from the pool, providing a precise and transparent system for all parties involved.

note

claim-end can be set to 0 to indicate that there is no predetermined end date for the claiming period, allowing beneficiaries to claim their rewards until the spending pool’s funds are fully distributed.

Claiming Process

To request funds from a spending pool, a beneficiary must be registered. The beneficiary can then send a transaction to request the funds they are entitled to receive. There are several conditions that must be met in order for the funds to be distributed:

  • The current block time must be within the period defined by the claim-start and claim-end properties.
  • The spending pool must have a sufficient balance. If the pool does not have enough funds, pooled token will not be sent in any amount. If the pool has sufficient funds, the exact amount owed will be sent to the beneficiary.
  • If the claiming period or the dynamic claim period has elapsed and the funds have not been claimed by the beneficiary they are forfeited.

If all of these conditions are met, the funds will be distributed to the beneficiary.

Claim Expiry

The claim-expiry parameter sets a critical window within which beneficiaries are required to claim their rewards, preserving the integrity of reward calculations amid potential rate changes over time. Should a beneficiary not engage within this window, rewards succeeding the deadline are excluded from subsequent claim calculation. This mechanism ensures that rewards are accurately and fairly distributed even if pool owners operate rate changes, and it underscores the importance of regular claims to secure entitled benefits. Beneficiaries must therefore remain proactive in claiming within each designated period to uphold the system's equitable distribution of rewards

note

The proposal-distribute-spending-pool command enables the spending pool’s owners to enforce funds distribution. This command is particularly useful before modifying the fixed distribution rate to avoid misdistribution.

Distribution Weights

Individual token distribution rates can be set for specific accounts and/or roles using weights. For example, if a specific account's or a role’s weight is set to 2, it will receive tokens at 2x the base rate (static or dynamic) compared to other accounts. Weights can also be decimal values, such as 0.5, which will reduce the token rate for the associated account or role by half. All distribution rates are set to 1 by default.

It's worth noting that any changes made to the weights of registered beneficiaries will result in the recalculation of global token rates, ensuring that the modified rate for one account does not impact the entitlements of others. This means for instance that if the weight for an account is increased, the global rate is increased accordingly, rather than decreasing entitlements for every other account. This mechanism makes sense from an HR management standpoint, as it allows for proper management of wages among different members of a community or team, ensuring that each person is compensated fairly for their contributions.

Parameters

Spending Pool

NAMETYPEEXAMPLEDESCRIPTION
namestring"Dev salary"Unique identifier for the spending pool.
claim_startuint641610000000Unix timestamp of the start of the claiming period.
claim_enduint641620000000Unix timestamp of the end of the claiming period.
claim_expiryuint642592000Time in seconds after which unclaimed funds are no longer accountable.
rates[]string1ukex,0.8uethRate of distribution in the smallest token denomination per 1 second. This value can be a float number smaller than the actual denomination.
vote_quorumuint6451Pool-specific percentage of owner accounts that must vote YES or NO for any of the pool proposals to be valid.
vote_perioduint64600Period of time in seconds that any of the pool proposals must last before passing or being rejected.
vote_enactmentuint64300Period of time that must pass before any of the pool proposals are enacted.
ownersPermInfoList of accounts/roles with governance control over the pool.
beneficiariesWeightedPermInfoSet of accounts/roles with their respective weights eligible for funds distribution.
balances[]string100000ukex,20uethArray of balances in the pool.
dynamic_rateboolfalseFlag to define if the distribution rate is dynamic.
dynamic_rate_perioduint6486400Time in seconds defining the recalculation period for dynamic rates.
last_dynamic_rate_calc_timeuint641615000000Timestamp of the last dynamic rate calculation.

PermInfo type

NAMETYPEEXAMPLEDESCRIPTION
owner_roles[]uint641,2Array of role identifiers for pool ownership.
owner_accounts[]stringkira1yq8l...,kira1o9dl...Array of account addresses with ownership privileges.

WeightedPermInfo type

NAMETYPEEXAMPLEDESCRIPTION
roles[]WeightedRoleArray of roles with associated weights.
accounts[]WeightedAccountArray of accounts with associated weights.

WeightedRole type

NAMETYPEEXAMPLEDESCRIPTION
roleuint641Identifier for a specific role.
weightfloat1.2Dedicated weight for this role in the funds distribution calculation.

WeightedAccount type

NAMETYPEEXAMPLEDESCRIPTION
accountstringkira1yq8l...Account address.
weightfloat0.5Dedicated weight of the account in the funds distribution calculation.

CLI Syntax & Examples

note

Each CLI command and proposal process in KIRA requires specific permissions. These permissions must be added to the account's whitelist or obtained as sudo permissions for direct changes. Refer to the Roles & Permissions documentation for more details.

note

$SIGNER represents the transaction signer's account name or address. For instructions on setting common flags as environment variables, such as $FLAGS_TX and $FLAGS_QR, see the CLI Guide page.

Transactions

create-spending-poolCreates a new spending pool.
proposal-spending-pool-updateProposes modifications to a pool.
deposit-spending-poolAllows depositing tokens to the pool.
register-spending-pool-beneficiaryRegisters a beneficiary account.
claim-spending-poolBeneficiaries claim tokens.
proposal-spending-pool-withdrawProposes withdrawal from the pool.
proposal-distribute-spending-poolProposes distribution to beneficiaries.

Create Spending Pool

Create a new spending pool using the create-spending-pool command.

Flags

  • $NAME: Name of the spending pool registry.
  • $CLAIMSTART: The exact start time after which tokens can be claimed from the pool, expressed in seconds (Unix time).
  • $CLAIMEND: The exact end time before which tokens can be claimed from the pool, expressed in seconds (Unix time).
  • $RATES: Decimal rate of distribution in the smallest token denomination per second. Format: <rate><denom>,..., e.g: 0.5ukex.
  • $VOTEQUORUM: Pool specific percentage of owner accounts that must vote YES or NO for a proposal to be valid.
  • $VOTEPERIOD: Time in seconds for which a pool proposal must last before being accepted or rejected.
  • $VOTEENACTMENT: Time in seconds before a passed pool proposal is enacted.
  • $OWNERROLES: List of roles controlling the pool via proposals, e.g: 1,2,...
  • $OWNERACCOUNTS: List of account addresses controlling the pool via proposals. Format: kira1yq8l(...),...
  • $BENEFICIARYROLES: List of roles eligible for funds distribution, e.g: 3,4,...
  • $BENEFICIARYROLEWEIGHTS: Respective token distribution rate multiplier for beneficiary roles, e.g:1,1.2,…
  • $BENEFICIARYACCOUNTS: List of account addresses eligible for funds distribution. Format: kira1mig9(...),...
  • $BENEFICIARYACCOUNTWEIGHTS: Token distribution rate multiplier for specific accounts, e.g:0.5,…
  • $DYNAMICRATE: Boolean flag to enable dynamic rate calculation.
  • $DYNAMICRATEPERIOD: Dynamic period in seconds (Unix time).
sekaid tx spending create-spending-pool \
--from=$SIGNER $FLAGS_TX \
--name=$NAME --claim-start=$CLAIMSTART --claim-end=$CLAIMEND --rates=$RATES \
--vote-quorum=$VOTEQUORUM --vote-period=$VOTEPERIOD --vote-enactment=$VOTEENACTMENT \
--owner-roles=$OWNERROLES --owner-accounts=$OWNERACCOUNTS \
--beneficiary-roles=$BENEFICIARYROLES --beneficiary-role-weights=$BENEFICIARYROLEWEIGHTS \
--beneficiary-accounts=$BENEFICIARYACCOUNTS --beneficiary-account-weights=$BENEFICIARYACCOUNTWEIGHTS \
--dynamic-rate=$DYNAMICRATE --dynamic-rate-period=$DYNAMICRATEPERIOD

Deposit to a Spending Pool

Deposit tokens to a spending pool using the deposit-spending-pool command.

Flags

  • $NAME: Name of the spending pool registry.
  • $AMOUNTS: Coin denomination and amount to be deposited. Format: <amount><denom>, e.g., 20000ukex.
sekaid tx spending deposit-spending-pool \
--from=$SIGNER $FLAGS_TX \
--name=$NAME --amount=$AMOUNTS

Register as Beneficiary

Register as a beneficiary using the register-spending-pool-beneficiary command.

Flags

  • $NAME: Name of the spending pool registry.
sekaid tx spending register-spending-pool-beneficiary \
--from=$SIGNER $FLAGS_TX \
--name=$NAME

Claim Funds From Spending Pool

Beneficiaries can claim their entitled funds using the claim-spending-pool command, provided they are registered. Claims cannot be processed if the claim period has expired or if the pool lacks adequate funds.

Flags

  • $NAME: Name of the spending pool registry.
sekaid tx spending claim-spending-pool \
--from=$SIGNER $FLAGS_TX \
--name=$NAME