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: Staking reward generation through inflation #757

Closed
Closed
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3cb1f1b
feat(iota-types): staking params were changed according new requirements
valeriyr Jun 19, 2024
9f2b264
feat: store IOTA's TreasutyCap in SystemObject
valeriyr Jun 19, 2024
d336e71
fix(iota-framework): fixed lock files
valeriyr Jun 20, 2024
792afc1
feat(iota-config): turn off stake subsidy by changing default params
valeriyr Jun 20, 2024
55cd94c
feat(iota-framework): added IOTA burn/mint functions
valeriyr Jun 21, 2024
33297be
feat: Remove parts of stake subsidy fund
PhilippGackstatter Jun 25, 2024
68b87c1
feat: Implement increase/decrease supply based on target reward
PhilippGackstatter Jun 25, 2024
e67f56f
feat: Add validator_target_reward and pass to advance_epoch
PhilippGackstatter Jun 25, 2024
c1f310f
feat: Test supply change
PhilippGackstatter Jun 26, 2024
a5311d3
Merge remote-tracking branch 'origin/develop' into l1sc/issue-153-sta…
PhilippGackstatter Jun 26, 2024
23f5cc2
Merge branch 'develop' into l1sc/issue-153-staking-reward-through-inf…
Dkwcs Jun 26, 2024
b75b183
Merge branch 'develop' into l1sc/issue-153-staking-reward-through-inf…
Dkwcs Jun 26, 2024
4c6461b
fix: Set IOTA supply in Rust to correct value
PhilippGackstatter Jun 26, 2024
b594f40
fix: Add `TreasuryCap` to the system state rust struct
PhilippGackstatter Jun 26, 2024
2cd8c1b
Merge branch 'develop' into l1sc/issue-153-staking-reward-through-inf…
Dkwcs Jun 26, 2024
fbbccd9
fix: Add TreasuryCap to the system state rust struct v1
Dkwcs Jun 26, 2024
eca5fc5
feat: Remove stake subsidy fund on move side
PhilippGackstatter Jun 27, 2024
d31a458
Merge remote-tracking branch 'origin/develop' into l1sc/issue-153-sta…
PhilippGackstatter Jun 27, 2024
bd4e36f
feat: Enable burning remainder supply in distribution schedule
PhilippGackstatter Jun 27, 2024
83ace78
feat: Align Iota System State Rust with Move types
PhilippGackstatter Jun 27, 2024
fca23c9
feat: Remove stake subsidy entry from inspector
PhilippGackstatter Jun 27, 2024
6bf9caf
feat: Mint and burn gas coin supply in genesis PTB
PhilippGackstatter Jun 27, 2024
e8034f8
feat: Update docs of change move modules
PhilippGackstatter Jun 27, 2024
782df31
feat(iota-framework): storage deposits basic implementation
Dkwcs Jun 27, 2024
7cb1fc6
feat(iota-framework): remove storage_fund earnings rewards(storage_fu…
Dkwcs Jun 27, 2024
4349f80
refactor(iota-framework): clear storage_fund_reinvest_rate variable …
Dkwcs Jun 27, 2024
97c9c58
feat: Compute the total validator reward based on target reward
PhilippGackstatter Jun 28, 2024
5913666
feat: Add total iota supply to system state summary
PhilippGackstatter Jun 28, 2024
31cafc9
feat: Remove stake subsidy params form state summary
PhilippGackstatter Jun 28, 2024
5615ebb
feat: Remove more stake subsidy related params
PhilippGackstatter Jun 28, 2024
ae3ebfb
fix: Align `SystemEpochInfoEvent` to Move
PhilippGackstatter Jun 28, 2024
2b7204c
feat: Add todo for potentially emitting supply change
PhilippGackstatter Jun 28, 2024
45b0c43
Merge remote-tracking branch 'origin/develop' into l1sc/issue-153-sta…
PhilippGackstatter Jun 28, 2024
e875682
fix: Rename stake subsidy allocation to funds to burn
PhilippGackstatter Jun 28, 2024
33d47f1
Merge branch 'develop' into l1sc/issue-153-staking-reward-through-inf…
Dkwcs Jun 28, 2024
a9f7834
feat(iota-framework): non_refundable_storage_fee and leftover_staking…
Dkwcs Jun 29, 2024
b636d98
fix: Revert to validator target reward being total
PhilippGackstatter Jul 1, 2024
ceb0b38
fix: Update docs
PhilippGackstatter Jul 1, 2024
5365161
fix: Mint correct amount of nanos in genesis PTB
PhilippGackstatter Jul 1, 2024
22d3c09
fix: advance_epoch params and conservation check
PhilippGackstatter Jul 1, 2024
af21774
fix: Skip the authority conservation checks for now
PhilippGackstatter Jul 1, 2024
46d16ca
feat: Rework genesis supply minting and burning
PhilippGackstatter Jul 2, 2024
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
59 changes: 34 additions & 25 deletions crates/iota-config/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,6 @@ pub struct GenesisChainParameters {
pub chain_start_timestamp_ms: u64,
pub epoch_duration_ms: u64,

// Stake Subsidy parameters
pub stake_subsidy_start_epoch: u64,
pub stake_subsidy_initial_distribution_amount: u64,
pub stake_subsidy_period_length: u64,
pub stake_subsidy_decrease_rate: u16,

// Validator committee parameters
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could it be an easier option instead of removing the stake_subsidy related stuff, just to configure it not to generate rewards?

Choose a reason for hiding this comment

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

I don't think we intend to reuse the stake subsidy fund at any point in the future. So I think removing it is the best option, otherwise it becomes technical debt immediately. Or am I missing your point?

Copy link
Contributor Author

@valeriyr valeriyr Jul 1, 2024

Choose a reason for hiding this comment

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

I think you are right, we do not need it.

Removing this entity affects a lot of code and seems like it can be disabled, so I thought that it was better to remove it later as a separate task when we have inflation tests ready.

We also need to clean GenesisCeremonyParameters from the subsidy stuff.

Choose a reason for hiding this comment

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

Yeah, by now I already removed a lot of subsidy related stuff, but not all. If the current state works without removing more, we can remove the rest later - I already mentioned this in the PR description as a later task for which we should create issues.

pub max_validator_count: u64,
pub min_validator_joining_stake: u64,
Expand Down Expand Up @@ -434,30 +428,27 @@ impl GenesisCeremonyParameters {
}

fn default_initial_stake_subsidy_distribution_amount() -> u64 {
// 1M Iota
1_000_000 * iota_types::gas_coin::MICROS_PER_IOTA
// 0 IOTA in micros
0
}

fn default_stake_subsidy_period_length() -> u64 {
// TODO: can this param be set to u64::MAX?

// 10 distributions or epochs
10
}

fn default_stake_subsidy_decrease_rate() -> u16 {
// 10% in basis points
1000
// 0% in basis points. for example, should be equal to 1000 to represent 10%.
0
}

pub fn to_genesis_chain_parameters(&self) -> GenesisChainParameters {
GenesisChainParameters {
protocol_version: self.protocol_version.as_u64(),
stake_subsidy_start_epoch: self.stake_subsidy_start_epoch,
chain_start_timestamp_ms: self.chain_start_timestamp_ms,
epoch_duration_ms: self.epoch_duration_ms,
stake_subsidy_initial_distribution_amount: self
.stake_subsidy_initial_distribution_amount,
stake_subsidy_period_length: self.stake_subsidy_period_length,
stake_subsidy_decrease_rate: self.stake_subsidy_decrease_rate,
max_validator_count: iota_types::governance::MAX_VALIDATOR_COUNT,
min_validator_joining_stake: iota_types::governance::MIN_VALIDATOR_JOINING_STAKE_MICROS,
validator_low_stake_threshold:
Expand All @@ -476,16 +467,18 @@ impl Default for GenesisCeremonyParameters {
}
}

// TODO: TOTAL_SUPPLY_MICROS should not be used for allocation and validation
// directly.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct TokenDistributionSchedule {
pub stake_subsidy_fund_micros: u64,
pub funds_to_burn: u64,
pub allocations: Vec<TokenAllocation>,
}

impl TokenDistributionSchedule {
pub fn validate(&self) {
let mut total_micros = self.stake_subsidy_fund_micros;
let mut total_micros = self.funds_to_burn;

for allocation in &self.allocations {
total_micros += allocation.amount_micros;
Expand Down Expand Up @@ -532,6 +525,11 @@ impl TokenDistributionSchedule {
}
}

/// Creates a new distribution schedule that allocates a default amount to
/// every given validator address.
///
/// The remainder of the total supply, if any, will be burned during the
/// genesis.
pub fn new_for_validators_with_default_allocation<I: IntoIterator<Item = IotaAddress>>(
validators: I,
) -> Self {
Expand All @@ -551,7 +549,7 @@ impl TokenDistributionSchedule {
.collect();

let schedule = Self {
stake_subsidy_fund_micros: supply,
funds_to_burn: supply,
allocations,
};

Expand All @@ -575,7 +573,7 @@ impl TokenDistributionSchedule {
assert_eq!(
TOTAL_SUPPLY_MICROS,
allocations.iter().map(|a| a.amount_micros).sum::<u64>(),
"Token Distribution Schedule must add up to 10B Iota",
"Token Distribution Schedule must add up to the total IOTA supply of {TOTAL_SUPPLY_MICROS} nanos",
);
let stake_subsidy_fund_allocation = allocations.pop().unwrap();
assert_eq!(
Expand All @@ -591,7 +589,7 @@ impl TokenDistributionSchedule {
);

let schedule = Self {
stake_subsidy_fund_micros: stake_subsidy_fund_allocation.amount_micros,
funds_to_burn: stake_subsidy_fund_allocation.amount_micros,
allocations,
};

Expand All @@ -608,7 +606,7 @@ impl TokenDistributionSchedule {

writer.serialize(TokenAllocation {
recipient_address: IotaAddress::default(),
amount_micros: self.stake_subsidy_fund_micros,
amount_micros: self.funds_to_burn,
staked_with_validator: None,
})?;

Expand All @@ -629,15 +627,17 @@ pub struct TokenAllocation {

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct TokenDistributionScheduleBuilder {
pool: u64,
remaining_supply: u64,
funds_to_burn: u64,
allocations: Vec<TokenAllocation>,
}

impl TokenDistributionScheduleBuilder {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
pool: TOTAL_SUPPLY_MICROS,
remaining_supply: TOTAL_SUPPLY_MICROS,
funds_to_burn: 0,
allocations: vec![],
}
}
Expand All @@ -658,13 +658,22 @@ impl TokenDistributionScheduleBuilder {
}

pub fn add_allocation(&mut self, allocation: TokenAllocation) {
self.pool = self.pool.checked_sub(allocation.amount_micros).unwrap();
self.remaining_supply = self
.remaining_supply
.checked_sub(allocation.amount_micros)
.unwrap();
self.allocations.push(allocation);
}

/// Designates the remaining supply to be burned during the genesis.
pub fn burn_remainder(&mut self) {
self.funds_to_burn += self.remaining_supply;
self.remaining_supply = 0;
}

pub fn build(&self) -> TokenDistributionSchedule {
let schedule = TokenDistributionSchedule {
stake_subsidy_fund_micros: self.pool,
funds_to_burn: self.remaining_supply,
allocations: self.allocations.clone(),
};

Expand Down
14 changes: 6 additions & 8 deletions crates/iota-framework/docs/iota-framework/iota.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ It has 9 decimals, and the smallest unit (10^-9) is called "nano".


<pre><code><b>use</b> <a href="../move-stdlib/option.md#0x1_option">0x1::option</a>;
<b>use</b> <a href="../iota-framework/balance.md#0x2_balance">0x2::balance</a>;
<b>use</b> <a href="../iota-framework/coin.md#0x2_coin">0x2::coin</a>;
<b>use</b> <a href="../iota-framework/transfer.md#0x2_transfer">0x2::transfer</a>;
<b>use</b> <a href="../iota-framework/tx_context.md#0x2_tx_context">0x2::tx_context</a>;
Expand Down Expand Up @@ -99,11 +98,11 @@ The total supply of IOTA denominated in Nano (4.6 Billion * 10^9)

## Function `new`

Register the <code><a href="../iota-framework/iota.md#0x2_iota_IOTA">IOTA</a></code> Coin to acquire its <code>Supply</code>.
Register the <code><a href="../iota-framework/iota.md#0x2_iota_IOTA">IOTA</a></code> Coin to acquire its <code>TreasuryCap</code>.
This should be called only once during genesis creation.


<pre><code><b>fun</b> <a href="../iota-framework/iota.md#0x2_iota_new">new</a>(ctx: &<b>mut</b> <a href="../iota-framework/tx_context.md#0x2_tx_context_TxContext">tx_context::TxContext</a>): <a href="../iota-framework/balance.md#0x2_balance_Balance">balance::Balance</a>&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">iota::IOTA</a>&gt;
<pre><code><b>fun</b> <a href="../iota-framework/iota.md#0x2_iota_new">new</a>(ctx: &<b>mut</b> <a href="../iota-framework/tx_context.md#0x2_tx_context_TxContext">tx_context::TxContext</a>): <a href="../iota-framework/coin.md#0x2_coin_TreasuryCap">coin::TreasuryCap</a>&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">iota::IOTA</a>&gt;
</code></pre>


Expand All @@ -112,7 +111,7 @@ This should be called only once during genesis creation.
<summary>Implementation</summary>


<pre><code><b>fun</b> <a href="../iota-framework/iota.md#0x2_iota_new">new</a>(ctx: &<b>mut</b> TxContext): Balance&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">IOTA</a>&gt; {
<pre><code><b>fun</b> <a href="../iota-framework/iota.md#0x2_iota_new">new</a>(ctx: &<b>mut</b> TxContext): TreasuryCap&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">IOTA</a>&gt; {
<b>assert</b>!(ctx.sender() == @0x0, <a href="../iota-framework/iota.md#0x2_iota_ENotSystemAddress">ENotSystemAddress</a>);
<b>assert</b>!(ctx.epoch() == 0, <a href="../iota-framework/iota.md#0x2_iota_EAlreadyMinted">EAlreadyMinted</a>);

Expand All @@ -125,11 +124,10 @@ This should be called only once during genesis creation.
<a href="../move-stdlib/option.md#0x1_option_some">option::some</a>(<a href="../iota-framework/url.md#0x2_url_new_unsafe_from_bytes">url::new_unsafe_from_bytes</a>(b"https://<a href="../iota-framework/iota.md#0x2_iota">iota</a>.org/logo.png")),
ctx
);

<a href="../iota-framework/transfer.md#0x2_transfer_public_freeze_object">transfer::public_freeze_object</a>(metadata);
<b>let</b> <b>mut</b> supply = treasury.treasury_into_supply();
<b>let</b> total_iota = supply.increase_supply(<a href="../iota-framework/iota.md#0x2_iota_TOTAL_SUPPLY_NANO">TOTAL_SUPPLY_NANO</a>);
supply.destroy_supply();
total_iota

treasury
}
</code></pre>

Expand Down
46 changes: 6 additions & 40 deletions crates/iota-framework/docs/iota-system/genesis.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ title: Module `0x3::genesis`
<b>use</b> <a href="../iota-framework/tx_context.md#0x2_tx_context">0x2::tx_context</a>;
<b>use</b> <a href="iota_system.md#0x3_iota_system">0x3::iota_system</a>;
<b>use</b> <a href="iota_system_state_inner.md#0x3_iota_system_state_inner">0x3::iota_system_state_inner</a>;
<b>use</b> <a href="stake_subsidy.md#0x3_stake_subsidy">0x3::stake_subsidy</a>;
<b>use</b> <a href="validator.md#0x3_validator">0x3::validator</a>;
<b>use</b> <a href="validator_set.md#0x3_validator_set">0x3::validator_set</a>;
</code></pre>
Expand Down Expand Up @@ -174,30 +173,6 @@ title: Module `0x3::genesis`
</dt>
<dd>

</dd>
<dt>
<code>stake_subsidy_start_epoch: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>stake_subsidy_initial_distribution_amount: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>stake_subsidy_period_length: u64</code>
</dt>
<dd>

</dd>
<dt>
<code>stake_subsidy_decrease_rate: u16</code>
</dt>
<dd>

</dd>
<dt>
<code>max_validator_count: u64</code>
Expand Down Expand Up @@ -251,7 +226,7 @@ title: Module `0x3::genesis`

<dl>
<dt>
<code>stake_subsidy_fund_micros: u64</code>
<code>funds_to_burn: u64</code>
</dt>
<dd>

Expand Down Expand Up @@ -340,7 +315,7 @@ It will create a singleton IotaSystemState object, which contains
all the information we need in the system.


<pre><code><b>fun</b> <a href="genesis.md#0x3_genesis_create">create</a>(iota_system_state_id: <a href="../iota-framework/object.md#0x2_object_UID">object::UID</a>, iota_supply: <a href="../iota-framework/balance.md#0x2_balance_Balance">balance::Balance</a>&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">iota::IOTA</a>&gt;, genesis_chain_parameters: <a href="genesis.md#0x3_genesis_GenesisChainParameters">genesis::GenesisChainParameters</a>, genesis_validators: <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;<a href="genesis.md#0x3_genesis_GenesisValidatorMetadata">genesis::GenesisValidatorMetadata</a>&gt;, token_distribution_schedule: <a href="genesis.md#0x3_genesis_TokenDistributionSchedule">genesis::TokenDistributionSchedule</a>, ctx: &<b>mut</b> <a href="../iota-framework/tx_context.md#0x2_tx_context_TxContext">tx_context::TxContext</a>)
<pre><code><b>fun</b> <a href="genesis.md#0x3_genesis_create">create</a>(iota_system_state_id: <a href="../iota-framework/object.md#0x2_object_UID">object::UID</a>, iota_treasury_cap: <a href="../iota-framework/coin.md#0x2_coin_TreasuryCap">coin::TreasuryCap</a>&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">iota::IOTA</a>&gt;, iota_supply: <a href="../iota-framework/balance.md#0x2_balance_Balance">balance::Balance</a>&lt;<a href="../iota-framework/iota.md#0x2_iota_IOTA">iota::IOTA</a>&gt;, genesis_chain_parameters: <a href="genesis.md#0x3_genesis_GenesisChainParameters">genesis::GenesisChainParameters</a>, genesis_validators: <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;<a href="genesis.md#0x3_genesis_GenesisValidatorMetadata">genesis::GenesisValidatorMetadata</a>&gt;, token_distribution_schedule: <a href="genesis.md#0x3_genesis_TokenDistributionSchedule">genesis::TokenDistributionSchedule</a>, ctx: &<b>mut</b> <a href="../iota-framework/tx_context.md#0x2_tx_context_TxContext">tx_context::TxContext</a>)
</code></pre>


Expand All @@ -351,7 +326,8 @@ all the information we need in the system.

<pre><code><b>fun</b> <a href="genesis.md#0x3_genesis_create">create</a>(
iota_system_state_id: UID,
<b>mut</b> iota_supply: Balance&lt;IOTA&gt;,
iota_treasury_cap: TreasuryCap&lt;IOTA&gt;,
iota_supply: Balance&lt;IOTA&gt;,
genesis_chain_parameters: <a href="genesis.md#0x3_genesis_GenesisChainParameters">GenesisChainParameters</a>,
genesis_validators: <a href="../move-stdlib/vector.md#0x1_vector">vector</a>&lt;<a href="genesis.md#0x3_genesis_GenesisValidatorMetadata">GenesisValidatorMetadata</a>&gt;,
token_distribution_schedule: <a href="genesis.md#0x3_genesis_TokenDistributionSchedule">TokenDistributionSchedule</a>,
Expand All @@ -361,11 +337,10 @@ all the information we need in the system.
<b>assert</b>!(ctx.epoch() == 0, <a href="genesis.md#0x3_genesis_ENotCalledAtGenesis">ENotCalledAtGenesis</a>);

<b>let</b> <a href="genesis.md#0x3_genesis_TokenDistributionSchedule">TokenDistributionSchedule</a> {
stake_subsidy_fund_micros,
funds_to_burn: _,
allocations,
} = token_distribution_schedule;

<b>let</b> subsidy_fund = iota_supply.split(stake_subsidy_fund_micros);
<b>let</b> <a href="storage_fund.md#0x3_storage_fund">storage_fund</a> = <a href="../iota-framework/balance.md#0x2_balance_zero">balance::zero</a>();

// Create all the `Validator` structs
Expand Down Expand Up @@ -434,7 +409,6 @@ all the information we need in the system.

<b>let</b> system_parameters = <a href="iota_system_state_inner.md#0x3_iota_system_state_inner_create_system_parameters">iota_system_state_inner::create_system_parameters</a>(
genesis_chain_parameters.epoch_duration_ms,
genesis_chain_parameters.stake_subsidy_start_epoch,

// Validator committee parameters
genesis_chain_parameters.max_validator_count,
Expand All @@ -446,22 +420,14 @@ all the information we need in the system.
ctx,
);

<b>let</b> <a href="stake_subsidy.md#0x3_stake_subsidy">stake_subsidy</a> = <a href="stake_subsidy.md#0x3_stake_subsidy_create">stake_subsidy::create</a>(
subsidy_fund,
genesis_chain_parameters.stake_subsidy_initial_distribution_amount,
genesis_chain_parameters.stake_subsidy_period_length,
genesis_chain_parameters.stake_subsidy_decrease_rate,
ctx,
);

<a href="iota_system.md#0x3_iota_system_create">iota_system::create</a>(
iota_system_state_id,
iota_treasury_cap,
validators,
<a href="storage_fund.md#0x3_storage_fund">storage_fund</a>,
genesis_chain_parameters.protocol_version,
genesis_chain_parameters.chain_start_timestamp_ms,
system_parameters,
<a href="stake_subsidy.md#0x3_stake_subsidy">stake_subsidy</a>,
ctx,
);
}
Expand Down
Loading
Loading