From 426c4840068d802768fc0a378dfc3b7098d2c62c Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Wed, 19 Jun 2024 16:18:36 +0300 Subject: [PATCH] feat: store IOTA's TreasutyCap in SystemObject --- .../docs/iota-framework/iota.md | 43 ++++++++++++++++--- .../docs/iota-system/genesis.md | 25 ++++------- .../docs/iota-system/iota_system.md | 4 +- .../iota-system/iota_system_state_inner.md | 18 +++++++- .../packages/iota-framework/sources/iota.move | 23 +++++++--- .../packages/iota-system/sources/genesis.move | 22 ++++------ .../iota-system/sources/iota_system.move | 4 +- .../sources/iota_system_state_inner.move | 10 ++++- .../tests/governance_test_utils.move | 1 + crates/iota-genesis-builder/src/lib.rs | 40 +++++++++++------ 10 files changed, 130 insertions(+), 60 deletions(-) diff --git a/crates/iota-framework/docs/iota-framework/iota.md b/crates/iota-framework/docs/iota-framework/iota.md index 7c76bcebee9..0ce9f549757 100644 --- a/crates/iota-framework/docs/iota-framework/iota.md +++ b/crates/iota-framework/docs/iota-framework/iota.md @@ -9,6 +9,7 @@ It has 9 decimals, and the smallest unit (10^-9) is called "micros". - [Struct `IOTA`](#0x2_iota_IOTA) - [Constants](#@Constants_0) - [Function `new`](#0x2_iota_new) +- [Function `increase_supply`](#0x2_iota_increase_supply) - [Function `transfer`](#0x2_iota_transfer) @@ -109,11 +110,11 @@ The total supply of Iota denominated in Micros (10 Billion * 10^9) ## Function `new` -Register the IOTA Coin to acquire its Supply. +Register the IOTA Coin to acquire its TreasuryCap. This should be called only once during genesis creation. -
fun new(ctx: &mut tx_context::TxContext): balance::Balance<iota::IOTA>
+
fun new(ctx: &mut tx_context::TxContext): coin::TreasuryCap<iota::IOTA>
 
@@ -122,7 +123,7 @@ This should be called only once during genesis creation. Implementation -
fun new(ctx: &mut TxContext): Balance<IOTA> {
+
fun new(ctx: &mut TxContext): TreasuryCap<IOTA> {
     assert!(ctx.sender() == @0x0, ENotSystemAddress);
     assert!(ctx.epoch() == 0, EAlreadyMinted);
 
@@ -136,11 +137,39 @@ This should be called only once during genesis creation.
         option::none(),
         ctx
     );
+
     transfer::public_freeze_object(metadata);
-    let mut supply = treasury.treasury_into_supply();
-    let total_iota = supply.increase_supply(TOTAL_SUPPLY_MICROS);
-    supply.destroy_supply();
-    total_iota
+
+    treasury
+}
+
+ + + + + + + +## Function `increase_supply` + +Increase the IOTA supply. +This should be called only once during genesis creation. + + +
fun increase_supply(cap: &mut coin::TreasuryCap<iota::IOTA>, ctx: &tx_context::TxContext): balance::Balance<iota::IOTA>
+
+ + + +
+Implementation + + +
fun increase_supply(cap: &mut TreasuryCap<IOTA>, ctx: &TxContext): Balance<IOTA> {
+    assert!(ctx.sender() == @0x0, ENotSystemAddress);
+    assert!(ctx.epoch() == 0, EAlreadyMinted);
+
+    cap.supply_mut().increase_supply(TOTAL_SUPPLY_MICROS)
 }
 
diff --git a/crates/iota-framework/docs/iota-system/genesis.md b/crates/iota-framework/docs/iota-system/genesis.md index 6596d57ac48..2e6a8dc30cb 100644 --- a/crates/iota-framework/docs/iota-system/genesis.md +++ b/crates/iota-framework/docs/iota-system/genesis.md @@ -290,7 +290,7 @@ title: Module `0x3::genesis`
-amount_micros: u64 +amount_micros: balance::Balance<iota::IOTA>
@@ -340,7 +340,7 @@ It will create a singleton IotaSystemState object, which contains all the information we need in the system. -
fun create(iota_system_state_id: object::UID, iota_supply: balance::Balance<iota::IOTA>, genesis_chain_parameters: genesis::GenesisChainParameters, genesis_validators: vector<genesis::GenesisValidatorMetadata>, token_distribution_schedule: genesis::TokenDistributionSchedule, ctx: &mut tx_context::TxContext)
+
fun create(iota_system_state_id: object::UID, iota_treasury_cap: coin::TreasuryCap<iota::IOTA>, genesis_chain_parameters: genesis::GenesisChainParameters, genesis_validators: vector<genesis::GenesisValidatorMetadata>, token_distribution_schedule: genesis::TokenDistributionSchedule, ctx: &mut tx_context::TxContext)
 
@@ -351,7 +351,7 @@ all the information we need in the system.
fun create(
     iota_system_state_id: UID,
-    mut iota_supply: Balance<IOTA>,
+    iota_treasury_cap: TreasuryCap<IOTA>,
     genesis_chain_parameters: GenesisChainParameters,
     genesis_validators: vector<GenesisValidatorMetadata>,
     token_distribution_schedule: TokenDistributionSchedule,
@@ -361,11 +361,11 @@ all the information we need in the system.
     assert!(ctx.epoch() == 0, ENotCalledAtGenesis);
 
     let TokenDistributionSchedule {
-        stake_subsidy_fund_micros,
+        stake_subsidy_fund_micros: _,
         allocations,
     } = token_distribution_schedule;
 
-    let subsidy_fund = iota_supply.split(stake_subsidy_fund_micros);
+    let subsidy_fund = balance::zero();
     let storage_fund = balance::zero();
 
     // Create all the `Validator` structs
@@ -423,7 +423,6 @@ all the information we need in the system.
 
     // Allocate tokens and staking operations
     allocate_tokens(
-        iota_supply,
         allocations,
         &mut validators,
         ctx
@@ -456,6 +455,7 @@ all the information we need in the system.
 
     iota_system::create(
         iota_system_state_id,
+        iota_treasury_cap,
         validators,
         storage_fund,
         genesis_chain_parameters.protocol_version,
@@ -477,7 +477,7 @@ all the information we need in the system.
 
 
 
-
fun allocate_tokens(iota_supply: balance::Balance<iota::IOTA>, allocations: vector<genesis::TokenAllocation>, validators: &mut vector<validator::Validator>, ctx: &mut tx_context::TxContext)
+
fun allocate_tokens(allocations: vector<genesis::TokenAllocation>, validators: &mut vector<validator::Validator>, ctx: &mut tx_context::TxContext)
 
@@ -487,7 +487,6 @@ all the information we need in the system.
fun allocate_tokens(
-    mut iota_supply: Balance<IOTA>,
     mut allocations: vector<TokenAllocation>,
     validators: &mut vector<Validator>,
     ctx: &mut TxContext,
@@ -500,28 +499,22 @@ all the information we need in the system.
             staked_with_validator,
         } = allocations.pop_back();
 
-        let allocation_balance = iota_supply.split(amount_micros);
-
         if (staked_with_validator.is_some()) {
             let validator_address = staked_with_validator.destroy_some();
             let validator = validator_set::get_validator_mut(validators, validator_address);
             validator.request_add_stake_at_genesis(
-                allocation_balance,
+                amount_micros,
                 recipient_address,
                 ctx
             );
         } else {
             iota::transfer(
-                allocation_balance.into_coin(ctx),
+                amount_micros.into_coin(ctx),
                 recipient_address,
             );
         };
     };
     allocations.destroy_empty();
-
-    // Provided allocations must fully allocate the iota_supply and there
-    // should be none left at this point.
-    iota_supply.destroy_zero();
 }
 
diff --git a/crates/iota-framework/docs/iota-system/iota_system.md b/crates/iota-framework/docs/iota-system/iota_system.md index cf6ab5c3c8a..0d030e5f8a8 100644 --- a/crates/iota-framework/docs/iota-system/iota_system.md +++ b/crates/iota-framework/docs/iota-system/iota_system.md @@ -167,7 +167,7 @@ Create a new IotaSystemState object and make it shared. This function will be called only once in genesis. -
public(friend) fun create(id: object::UID, validators: vector<validator::Validator>, storage_fund: balance::Balance<iota::IOTA>, protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: iota_system_state_inner::SystemParameters, stake_subsidy: stake_subsidy::StakeSubsidy, ctx: &mut tx_context::TxContext)
+
public(friend) fun create(id: object::UID, iota_treasury_cap: coin::TreasuryCap<iota::IOTA>, validators: vector<validator::Validator>, storage_fund: balance::Balance<iota::IOTA>, protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: iota_system_state_inner::SystemParameters, stake_subsidy: stake_subsidy::StakeSubsidy, ctx: &mut tx_context::TxContext)
 
@@ -178,6 +178,7 @@ This function will be called only once in genesis.
public(package) fun create(
     id: UID,
+    iota_treasury_cap: TreasuryCap<IOTA>,
     validators: vector<Validator>,
     storage_fund: Balance<IOTA>,
     protocol_version: u64,
@@ -187,6 +188,7 @@ This function will be called only once in genesis.
     ctx: &mut TxContext,
 ) {
     let system_state = iota_system_state_inner::create(
+        iota_treasury_cap,
         validators,
         storage_fund,
         protocol_version,
diff --git a/crates/iota-framework/docs/iota-system/iota_system_state_inner.md b/crates/iota-framework/docs/iota-system/iota_system_state_inner.md
index 457f001f402..d9229cd6374 100644
--- a/crates/iota-framework/docs/iota-system/iota_system_state_inner.md
+++ b/crates/iota-framework/docs/iota-system/iota_system_state_inner.md
@@ -281,6 +281,12 @@ The top-level object containing all information of the Iota system.
  we know what version it is by inspecting IotaSystemStateInner as well.
 
+iota_treasury_cap: coin::TreasuryCap<iota::IOTA> +
+
+ The IOTA's TreasuryCap. +
+
validators: validator_set::ValidatorSet
@@ -413,6 +419,12 @@ Uses SystemParametersV2 as the parameters. we know what version it is by inspecting IotaSystemStateInner as well.
+iota_treasury_cap: coin::TreasuryCap<iota::IOTA> +
+
+ The IOTA's TreasuryCap. +
+
validators: validator_set::ValidatorSet
@@ -741,7 +753,7 @@ Create a new IotaSystemState object and make it shared. This function will be called only once in genesis. -
public(friend) fun create(validators: vector<validator::Validator>, initial_storage_fund: balance::Balance<iota::IOTA>, protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: iota_system_state_inner::SystemParameters, stake_subsidy: stake_subsidy::StakeSubsidy, ctx: &mut tx_context::TxContext): iota_system_state_inner::IotaSystemStateInner
+
public(friend) fun create(iota_treasury_cap: coin::TreasuryCap<iota::IOTA>, validators: vector<validator::Validator>, initial_storage_fund: balance::Balance<iota::IOTA>, protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: iota_system_state_inner::SystemParameters, stake_subsidy: stake_subsidy::StakeSubsidy, ctx: &mut tx_context::TxContext): iota_system_state_inner::IotaSystemStateInner
 
@@ -751,6 +763,7 @@ This function will be called only once in genesis.
public(package) fun create(
+    iota_treasury_cap: TreasuryCap<IOTA>,
     validators: vector<Validator>,
     initial_storage_fund: Balance<IOTA>,
     protocol_version: u64,
@@ -766,6 +779,7 @@ This function will be called only once in genesis.
         epoch: 0,
         protocol_version,
         system_state_version: genesis_system_state_version(),
+        iota_treasury_cap,
         validators,
         storage_fund: storage_fund::new(initial_storage_fund),
         parameters,
@@ -852,6 +866,7 @@ This function will be called only once in genesis.
         epoch,
         protocol_version,
         system_state_version: _,
+        iota_treasury_cap,
         validators,
         storage_fund,
         parameters,
@@ -880,6 +895,7 @@ This function will be called only once in genesis.
         epoch,
         protocol_version,
         system_state_version: 2,
+        iota_treasury_cap,
         validators,
         storage_fund,
         parameters: SystemParametersV2 {
diff --git a/crates/iota-framework/packages/iota-framework/sources/iota.move b/crates/iota-framework/packages/iota-framework/sources/iota.move
index e2ceb1fe3fc..96ff58c7c2a 100644
--- a/crates/iota-framework/packages/iota-framework/sources/iota.move
+++ b/crates/iota-framework/packages/iota-framework/sources/iota.move
@@ -6,7 +6,7 @@
 /// It has 9 decimals, and the smallest unit (10^-9) is called "micros".
 module iota::iota {
     use iota::balance::Balance;
-    use iota::coin;
+    use iota::coin::{Self, TreasuryCap};
 
     const EAlreadyMinted: u64 = 0;
     /// Sender is not @0x0 the system address.
@@ -28,9 +28,9 @@ module iota::iota {
     public struct IOTA has drop {}
 
     #[allow(unused_function)]
-    /// Register the `IOTA` Coin to acquire its `Supply`.
+    /// Register the `IOTA` Coin to acquire its `TreasuryCap`.
     /// This should be called only once during genesis creation.
-    fun new(ctx: &mut TxContext): Balance {
+    fun new(ctx: &mut TxContext): TreasuryCap {
         assert!(ctx.sender() == @0x0, ENotSystemAddress);
         assert!(ctx.epoch() == 0, EAlreadyMinted);
 
@@ -44,11 +44,20 @@ module iota::iota {
             option::none(),
             ctx
         );
+
         transfer::public_freeze_object(metadata);
-        let mut supply = treasury.treasury_into_supply();
-        let total_iota = supply.increase_supply(TOTAL_SUPPLY_MICROS);
-        supply.destroy_supply();
-        total_iota
+
+        treasury
+    }
+
+    #[allow(unused_function)]
+    /// Increase the IOTA supply.
+    /// This should be called only once during genesis creation.
+    fun increase_supply(cap: &mut TreasuryCap, ctx: &TxContext): Balance {
+        assert!(ctx.sender() == @0x0, ENotSystemAddress);
+        assert!(ctx.epoch() == 0, EAlreadyMinted);
+
+        cap.supply_mut().increase_supply(TOTAL_SUPPLY_MICROS)
     }
 
     public entry fun transfer(c: coin::Coin, recipient: address) {
diff --git a/crates/iota-framework/packages/iota-system/sources/genesis.move b/crates/iota-framework/packages/iota-system/sources/genesis.move
index 68133f283a7..f462c433bef 100644
--- a/crates/iota-framework/packages/iota-system/sources/genesis.move
+++ b/crates/iota-framework/packages/iota-system/sources/genesis.move
@@ -5,6 +5,7 @@
 module iota_system::genesis {
 
     use iota::balance::{Self, Balance};
+    use iota::coin::TreasuryCap;
     use iota::iota::{Self, IOTA};
     use iota_system::iota_system;
     use iota_system::validator::{Self, Validator};
@@ -61,7 +62,7 @@ module iota_system::genesis {
 
     public struct TokenAllocation {
         recipient_address: address,
-        amount_micros: u64,
+        amount_micros: Balance,
 
         /// Indicates if this allocation should be staked at genesis and with which validator
         staked_with_validator: Option
, @@ -79,7 +80,7 @@ module iota_system::genesis { /// all the information we need in the system. fun create( iota_system_state_id: UID, - mut iota_supply: Balance, + iota_treasury_cap: TreasuryCap, genesis_chain_parameters: GenesisChainParameters, genesis_validators: vector, token_distribution_schedule: TokenDistributionSchedule, @@ -89,11 +90,11 @@ module iota_system::genesis { assert!(ctx.epoch() == 0, ENotCalledAtGenesis); let TokenDistributionSchedule { - stake_subsidy_fund_micros, + stake_subsidy_fund_micros: _, allocations, } = token_distribution_schedule; - let subsidy_fund = iota_supply.split(stake_subsidy_fund_micros); + let subsidy_fund = balance::zero(); let storage_fund = balance::zero(); // Create all the `Validator` structs @@ -151,7 +152,6 @@ module iota_system::genesis { // Allocate tokens and staking operations allocate_tokens( - iota_supply, allocations, &mut validators, ctx @@ -184,6 +184,7 @@ module iota_system::genesis { iota_system::create( iota_system_state_id, + iota_treasury_cap, validators, storage_fund, genesis_chain_parameters.protocol_version, @@ -195,7 +196,6 @@ module iota_system::genesis { } fun allocate_tokens( - mut iota_supply: Balance, mut allocations: vector, validators: &mut vector, ctx: &mut TxContext, @@ -208,28 +208,22 @@ module iota_system::genesis { staked_with_validator, } = allocations.pop_back(); - let allocation_balance = iota_supply.split(amount_micros); - if (staked_with_validator.is_some()) { let validator_address = staked_with_validator.destroy_some(); let validator = validator_set::get_validator_mut(validators, validator_address); validator.request_add_stake_at_genesis( - allocation_balance, + amount_micros, recipient_address, ctx ); } else { iota::transfer( - allocation_balance.into_coin(ctx), + amount_micros.into_coin(ctx), recipient_address, ); }; }; allocations.destroy_empty(); - - // Provided allocations must fully allocate the iota_supply and there - // should be none left at this point. - iota_supply.destroy_zero(); } fun activate_validators(validators: &mut vector) { diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index 9906271b539..4f01e7cf08f 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -42,7 +42,7 @@ module iota_system::iota_system { use iota::balance::Balance; - use iota::coin::Coin; + use iota::coin::{Coin, TreasuryCap}; use iota_system::staking_pool::StakedIota; use iota::iota::IOTA; use iota::table::Table; @@ -78,6 +78,7 @@ module iota_system::iota_system { /// This function will be called only once in genesis. public(package) fun create( id: UID, + iota_treasury_cap: TreasuryCap, validators: vector, storage_fund: Balance, protocol_version: u64, @@ -87,6 +88,7 @@ module iota_system::iota_system { ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( + iota_treasury_cap, validators, storage_fund, protocol_version, diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index f4270501b06..ceaf0a25532 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -4,7 +4,7 @@ module iota_system::iota_system_state_inner { use iota::balance::{Self, Balance}; - use iota::coin::Coin; + use iota::coin::{Coin, TreasuryCap}; use iota_system::staking_pool::{stake_activation_epoch, StakedIota}; use iota::iota::IOTA; use iota_system::validator::{Self, Validator}; @@ -110,6 +110,8 @@ module iota_system::iota_system_state_inner { /// This is always the same as IotaSystemState.version. Keeping a copy here so that /// we know what version it is by inspecting IotaSystemStateInner as well. system_state_version: u64, + /// The IOTA's TreasuryCap. + iota_treasury_cap: TreasuryCap, /// Contains all information about the validators. validators: ValidatorSet, /// The storage fund. @@ -158,6 +160,8 @@ module iota_system::iota_system_state_inner { /// This is always the same as IotaSystemState.version. Keeping a copy here so that /// we know what version it is by inspecting IotaSystemStateInner as well. system_state_version: u64, + /// The IOTA's TreasuryCap. + iota_treasury_cap: TreasuryCap, /// Contains all information about the validators. validators: ValidatorSet, /// The storage fund. @@ -232,6 +236,7 @@ module iota_system::iota_system_state_inner { /// Create a new IotaSystemState object and make it shared. /// This function will be called only once in genesis. public(package) fun create( + iota_treasury_cap: TreasuryCap, validators: vector, initial_storage_fund: Balance, protocol_version: u64, @@ -247,6 +252,7 @@ module iota_system::iota_system_state_inner { epoch: 0, protocol_version, system_state_version: genesis_system_state_version(), + iota_treasury_cap, validators, storage_fund: storage_fund::new(initial_storage_fund), parameters, @@ -293,6 +299,7 @@ module iota_system::iota_system_state_inner { epoch, protocol_version, system_state_version: _, + iota_treasury_cap, validators, storage_fund, parameters, @@ -321,6 +328,7 @@ module iota_system::iota_system_state_inner { epoch, protocol_version, system_state_version: 2, + iota_treasury_cap, validators, storage_fund, parameters: SystemParametersV2 { diff --git a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move index 327418973ac..004f7eaec8d 100644 --- a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move +++ b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move @@ -83,6 +83,7 @@ module iota_system::governance_test_utils { iota_system::create( object::new(ctx), // it doesn't matter what ID iota system state has in tests + coin::create_treasury_cap_for_testing(ctx), validators, balance::create_for_testing(storage_fund_amount * MICROS_PER_IOTA), // storage_fund 1, // protocol version diff --git a/crates/iota-genesis-builder/src/lib.rs b/crates/iota-genesis-builder/src/lib.rs index adec4c5f7c2..ef5dfc814fa 100644 --- a/crates/iota-genesis-builder/src/lib.rs +++ b/crates/iota-genesis-builder/src/lib.rs @@ -20,6 +20,7 @@ use iota_execution::{self, Executor}; use iota_framework::{BuiltInFramework, SystemPackage}; use iota_protocol_config::{Chain, ProtocolConfig, ProtocolVersion}; use iota_types::{ + balance::{BALANCE_DESTROY_REBATES_FUNCTION_NAME, BALANCE_MODULE_NAME}, base_types::{ ExecutionDigests, IotaAddress, ObjectID, SequenceNumber, TransactionDigest, TxContext, }, @@ -33,7 +34,7 @@ use iota_types::{ effects::{TransactionEffects, TransactionEffectsAPI, TransactionEvents}, epoch_data::EpochData, gas::IotaGasStatus, - gas_coin::GasCoin, + gas_coin::{GasCoin, GAS}, governance::StakedIota, in_memory_storage::InMemoryStorage, inner_temporary_store::InnerTemporaryStore, @@ -46,7 +47,7 @@ use iota_types::{ transaction::{ CallArg, CheckedInputObjects, Command, InputObjectKind, ObjectReadResult, Transaction, }, - IOTA_FRAMEWORK_ADDRESS, IOTA_SYSTEM_ADDRESS, + IOTA_FRAMEWORK_PACKAGE_ID, IOTA_SYSTEM_ADDRESS, }; use move_binary_format::CompiledModule; use move_core_types::ident_str; @@ -1060,7 +1061,7 @@ pub fn generate_genesis_system_object( let mut builder = ProgrammableTransactionBuilder::new(); // Step 1: Create the IotaSystemState UID let iota_system_state_uid = builder.programmable_move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + IOTA_FRAMEWORK_PACKAGE_ID, ident_str!("object").to_owned(), ident_str!("iota_system_state").to_owned(), vec![], @@ -1069,7 +1070,7 @@ pub fn generate_genesis_system_object( // Step 2: Create and share the Clock. builder.move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + IOTA_FRAMEWORK_PACKAGE_ID, ident_str!("clock").to_owned(), ident_str!("create").to_owned(), vec![], @@ -1080,7 +1081,7 @@ pub fn generate_genesis_system_object( // (which only happens in tests). if protocol_config.create_authenticator_state_in_genesis() { builder.move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + IOTA_FRAMEWORK_PACKAGE_ID, ident_str!("authenticator_state").to_owned(), ident_str!("create").to_owned(), vec![], @@ -1089,7 +1090,7 @@ pub fn generate_genesis_system_object( } if protocol_config.random_beacon() { builder.move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + IOTA_FRAMEWORK_PACKAGE_ID, ident_str!("random").to_owned(), ident_str!("create").to_owned(), vec![], @@ -1098,7 +1099,7 @@ pub fn generate_genesis_system_object( } if protocol_config.enable_coin_deny_list() { builder.move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + IOTA_FRAMEWORK_PACKAGE_ID, DENY_LIST_MODULE.to_owned(), DENY_LIST_CREATE_FUNC.to_owned(), vec![], @@ -1106,19 +1107,34 @@ pub fn generate_genesis_system_object( )?; } - // Step 4: Mint the supply of IOTA. - let iota_supply = builder.programmable_move_call( - IOTA_FRAMEWORK_ADDRESS.into(), + // Step 4: Create the IOTA Coin. + let iota_treasury_cap = builder.programmable_move_call( + IOTA_FRAMEWORK_PACKAGE_ID, ident_str!("iota").to_owned(), ident_str!("new").to_owned(), vec![], vec![], ); + let total_iota = builder.programmable_move_call( + IOTA_FRAMEWORK_PACKAGE_ID, + ident_str!("iota").to_owned(), + ident_str!("increase_supply").to_owned(), + vec![], + vec![iota_treasury_cap], + ); + // TODO: rename the `destroy_storage_rebates` function or create a specific one. + builder.programmable_move_call( + IOTA_FRAMEWORK_PACKAGE_ID, + BALANCE_MODULE_NAME.to_owned(), + BALANCE_DESTROY_REBATES_FUNCTION_NAME.to_owned(), + vec![GAS::type_tag()], + vec![total_iota], + ); // Step 5: Run genesis. // The first argument is the system state uid we got from step 1 and the second - // one is the IOTA supply we got from step 3. - let mut arguments = vec![iota_system_state_uid, iota_supply]; + // one is the IOTA `TreasuryCap` we got from step 4. + let mut arguments = vec![iota_system_state_uid, iota_treasury_cap]; let mut call_arg_arguments = vec![ CallArg::Pure(bcs::to_bytes(&genesis_chain_parameters).unwrap()), CallArg::Pure(bcs::to_bytes(&genesis_validators).unwrap()),