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..15afdec723b 100644 --- a/crates/iota-framework/docs/iota-system/genesis.md +++ b/crates/iota-framework/docs/iota-system/genesis.md @@ -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>, 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)
 
@@ -351,6 +351,7 @@ all the information we need in the system.
fun create(
     iota_system_state_id: UID,
+    iota_treasury_cap: TreasuryCap<IOTA>,
     mut iota_supply: Balance<IOTA>,
     genesis_chain_parameters: GenesisChainParameters,
     genesis_validators: vector<GenesisValidatorMetadata>,
@@ -456,6 +457,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,
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..b669b58398c 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};
@@ -79,6 +80,7 @@ module iota_system::genesis {
     /// all the information we need in the system.
     fun create(
         iota_system_state_id: UID,
+        iota_treasury_cap: TreasuryCap,
         mut iota_supply: Balance,
         genesis_chain_parameters: GenesisChainParameters,
         genesis_validators: vector,
@@ -184,6 +186,7 @@ module iota_system::genesis {
 
         iota_system::create(
             iota_system_state_id,
+            iota_treasury_cap,
             validators,
             storage_fund,
             genesis_chain_parameters.protocol_version,
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..36613b7de5a 100644
--- a/crates/iota-genesis-builder/src/lib.rs
+++ b/crates/iota-genesis-builder/src/lib.rs
@@ -46,7 +46,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 +1060,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 +1069,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 +1080,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 +1089,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 +1098,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 +1106,38 @@ 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:
+        // IOTA supply that already distributed to the users needs to be burned here
+        // or inside the `genesis::new` function.
+        // 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, total_iota];
         let mut call_arg_arguments = vec![
             CallArg::Pure(bcs::to_bytes(&genesis_chain_parameters).unwrap()),
             CallArg::Pure(bcs::to_bytes(&genesis_validators).unwrap()),