Reward Distributor
While just using a stake pool can be sufficient to keep track of total stake duration and lock the NFT in the user's wallet, a reward distributor can be optionally added to distribute rewards to staked NFTs.
Reward distributor, our provided implementation, is modeled similar to Stake pool, having both a
reward_distributor
and a reward_entry
. The reward entry is unique for each mint and keeps track of how many rewards have been given out to that NFT to ensure that it gets its fair share.#[account]
pub struct RewardDistributor {
pub bump: u8,
pub stake_pool: Pubkey,
pub kind: u8,
pub authority: Pubkey,
pub reward_mint: Pubkey,
pub reward_amount: u64,
pub reward_duration_seconds: u64,
pub rewards_issued: u64,
pub max_supply: Option<u64>,
}
#[account]
pub struct RewardEntry {
pub bump: u8,
pub mint: Pubkey,
pub reward_distributor: Pubkey,
pub reward_seconds_received: u64,
pub reward_amount_received: u64,
pub multiplier: u64,
}
A
reward_distributor
can be of 2 different kinds, Mint
or Treasury/Transfer
Mint
- If choosing reward distributor of kind Mint, the mint authority of the reward_mint will be transfered to the reward distributor upon initialization.
- This means that it can mint unlimited tokens to stakers up until an optional
max_supply
- The authority (creator) of this reward distributor can always reclaim the
mint_authority
by closing thereward_distributor
using theclose
instruction.
Treasury/Transfer
- With this kind, an initial supply of tokens of the given reward_mint will be transferred to the
reward_distributor
upon intialization. - The reward distributor will be able to distribute rewards from its treasury / supply until it runs out or hits an optional
max_supply
. - If the reward distributor is running out of tokens, anyone can simply transfer more tokens to it directly via a wallet using the transfer instruction. The tokens are held in the
associated_token_account
of thereward_distributor
for thereward_mint
.
In both kinds of reward distributors, if the
max_supply
is hit, or the treasury runs out, the remaining rewards will be given out and the reward_seconds_received
will be partially updated.Because reward distributor is modeled separately from the stake_pool, a user can optionally claim their rewards at any time for the amount of time they have staked. Typically, this is done automatically when calling
unstake
in the client.Reward distributor is a basic implementation that achieves a fixed linear payout structure, but modeling this as a separate program allows for any complex reward distribution logic to be implemented in a similar manner. Other implementations of other reward distributors are welcomed and encouraged. Examples that could be built:
- Tiered reward system that distributes rewards based on specified stake tiers
- Arbitrary non-linear reward functions
- NFT mutator that modifies metadata based on stake duration
- Probabilistic distributor that may or may not give a reward depending on the outcome of a random iteration. This could apply to a quest or mission with a given probability of success
Reward Distributor Multipliers
Multipliers is a feature that can tap a given token (via its reward_entry) to receive more rewards than the others. Only the authority of the pool can change the multiplier by calling the
update_reward_entry
instruction.- Modeling this separately allows the user/authority to either initialize their own reward_entries and update their multipliers later on or run arbitrary events/bonuses for specific NFTs at any time.
- In addition, the authority may initialize all the entries up front and set the correct/desired multipliers for their NFTs such that it will correctly allocate when the user first stakes.
Last modified 1yr ago