Skip to main content

Module 0x3::stake_subsidy

use 0x2::bag;
use 0x2::balance;
use 0x2::math;
use 0x2::sui;
use 0x2::tx_context;

Struct StakeSubsidy

struct StakeSubsidy has store
balance: balance::Balance<sui::SUI>
Balance of SUI set aside for stake subsidies that will be drawn down over time.
distribution_counter: u64
Count of the number of times stake subsidies have been distributed.
current_distribution_amount: u64
The amount of stake subsidy to be drawn down per distribution. This amount decays and decreases over time.
stake_subsidy_period_length: u64
Number of distributions to occur before the distribution amount decays.
stake_subsidy_decrease_rate: u16
The rate at which the distribution amount decays at the end of each period. Expressed in basis points.
extra_fields: bag::Bag
Any extra fields that's not defined statically.


const BASIS_POINT_DENOMINATOR: u128 = 10000;

const ESubsidyDecreaseRateTooLarge: u64 = 0;

Function create

public(friend) fun create(balance: balance::Balance<sui::SUI>, initial_distribution_amount: u64, stake_subsidy_period_length: u64, stake_subsidy_decrease_rate: u16, ctx: &mut tx_context::TxContext): stake_subsidy::StakeSubsidy
public(package) fun create(
    balance: Balance<SUI>,
    initial_distribution_amount: u64,
    stake_subsidy_period_length: u64,
    stake_subsidy_decrease_rate: u16,
    ctx: &mut TxContext,
): StakeSubsidy {
    // Rate can't be higher than 100%.
        stake_subsidy_decrease_rate <= BASIS_POINT_DENOMINATOR as u16,

    StakeSubsidy {
        distribution_counter: 0,
        current_distribution_amount: initial_distribution_amount,
        extra_fields: bag::new(ctx),

Function advance_epoch

Advance the epoch counter and draw down the subsidy for the epoch.

public(friend) fun advance_epoch(self: &mut stake_subsidy::StakeSubsidy): balance::Balance<sui::SUI>
public(package) fun advance_epoch(self: &mut StakeSubsidy): Balance<SUI> {
    // Take the minimum of the reward amount and the remaining balance in
    // order to ensure we don't overdraft the remaining stake subsidy
    // balance
    let to_withdraw = math::min(self.current_distribution_amount, self.balance.value());

    // Drawn down the subsidy for this epoch.
    let stake_subsidy = self.balance.split(to_withdraw);

    self.distribution_counter = self.distribution_counter + 1;

    // Decrease the subsidy amount only when the current period ends.
    if (self.distribution_counter % self.stake_subsidy_period_length == 0) {
        let decrease_amount = self.current_distribution_amount as u128
            * (self.stake_subsidy_decrease_rate as u128) / BASIS_POINT_DENOMINATOR;
        self.current_distribution_amount = self.current_distribution_amount - (decrease_amount as u64)


Function current_epoch_subsidy_amount

Returns the amount of stake subsidy to be added at the end of the current epoch.

public fun current_epoch_subsidy_amount(self: &stake_subsidy::StakeSubsidy): u64
public fun current_epoch_subsidy_amount(self: &StakeSubsidy): u64 {
    math::min(self.current_distribution_amount, self.balance.value())