From 8d64598a0398f1805ad76305b919dd07a55f7847 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 23 Jan 2025 09:24:46 +0700 Subject: [PATCH 1/5] a few extra data contract update tests --- .../data_contract_update/mod.rs | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index d92aa92444..2a111aa4db 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -1300,5 +1300,219 @@ mod tests { .unwrap() .expect("expected to commit transaction"); } + + #[test] + fn test_data_contract_update_can_not_remove_token() { + let mut platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_initial_state_structure(); + + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + + let platform_state = platform.state.load(); + let platform_version = platform_state + .current_platform_version() + .expect("expected to get current platform version"); + + let mut data_contract = + get_data_contract_fixture(None, 0, platform_version.protocol_version) + .data_contract_owned(); + + data_contract.set_owner_id(identity.id()); + + { + // Add a token to the contract + let tokens = data_contract.tokens_mut().expect("expected tokens"); + tokens.insert( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + ); + } + + platform + .drive + .apply_contract( + &data_contract, + BlockInfo::default(), + true, + StorageFlags::optional_default_as_cow(), + None, + platform_version, + ) + .expect("expected to apply contract successfully"); + + // Create an updated contract with the token removed + let mut updated_data_contract = data_contract.clone(); + updated_data_contract.set_version(2); + + updated_data_contract.tokens_mut().unwrap().remove(&0); + + let data_contract_update_transition = + DataContractUpdateTransition::new_from_data_contract( + updated_data_contract, + &identity.into_partial_identity_info(), + key.id(), + 2, + 0, + &signer, + platform_version, + None, + ) + .expect("expect to create data contract update transition"); + + let data_contract_update_serialized_transition = data_contract_update_transition + .serialize_to_bytes() + .expect("expected serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![data_contract_update_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + if let [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError(error)), + _, + )] = processing_result.execution_results().as_slice() + { + assert_eq!( + error.action(), + "remove token at position 0", + "expected error message to match 'remove token at position 0'" + ); + assert_eq!( + error.data_contract_id(), + data_contract.id(), + "expected the error to reference the correct data contract ID" + ); + } else { + panic!("Expected a DataContractUpdateActionNotAllowedError"); + } + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + } + + #[test] + fn test_data_contract_update_can_not_modify_token() { + let mut platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_initial_state_structure(); + + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + + let platform_state = platform.state.load(); + let platform_version = platform_state + .current_platform_version() + .expect("expected to get current platform version"); + + let mut data_contract = + get_data_contract_fixture(None, 0, platform_version.protocol_version) + .data_contract_owned(); + + data_contract.set_owner_id(identity.id()); + + { + // Add a token to the contract + let tokens = data_contract.tokens_mut().expect("expected tokens"); + tokens.insert( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + ); + } + + platform + .drive + .apply_contract( + &data_contract, + BlockInfo::default(), + true, + StorageFlags::optional_default_as_cow(), + None, + platform_version, + ) + .expect("expected to apply contract successfully"); + + // Create an updated contract with the token modified + let mut updated_data_contract = data_contract.clone(); + updated_data_contract.set_version(2); + + if let Some(TokenConfiguration::V0(config)) = + updated_data_contract.tokens_mut().unwrap().get_mut(&0) + { + config.minting_allow_choosing_destination = false; //originally true + } + + let data_contract_update_transition = + DataContractUpdateTransition::new_from_data_contract( + updated_data_contract, + &identity.into_partial_identity_info(), + key.id(), + 2, + 0, + &signer, + platform_version, + None, + ) + .expect("expect to create data contract update transition"); + + let data_contract_update_serialized_transition = data_contract_update_transition + .serialize_to_bytes() + .expect("expected serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![data_contract_update_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + if let [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError(error)), + _, + )] = processing_result.execution_results().as_slice() + { + assert_eq!( + error.action(), + "update token at position 0", + "expected error message to match 'update token at position 0'" + ); + assert_eq!( + error.data_contract_id(), + data_contract.id(), + "expected the error to reference the correct data contract ID" + ); + } else { + panic!("Expected a DataContractUpdateActionNotAllowedError"); + } + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + } } } From 19be127faf12b9785d18a8182e68066203c2d8e3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 23 Jan 2025 22:58:18 +0700 Subject: [PATCH 2/5] fix --- .../state_transitions/document/batch_transition/v1/v0_methods.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index c3dbdfa9c3..9b1abccd7d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -54,7 +54,6 @@ use crate::state_transition::batch_transition::document_create_transition::v0::v use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; -#[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; From 39ffaba7a38463f89b2aaafa267abc8cabf959e0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 27 Jan 2025 15:27:18 +0700 Subject: [PATCH 3/5] first part of token distribution --- Cargo.lock | 14 ++ packages/rs-dpp/Cargo.toml | 1 + .../src/data_contract/associated_token/mod.rs | 3 + .../token_configuration/accessors/mod.rs | 49 +---- .../token_configuration/accessors/v0/mod.rs | 25 +-- .../apply_token_configuration_item/v0/mod.rs | 36 +++- .../v0/mod.rs | 89 ++++---- .../v0/mod.rs | 46 +++- .../v0/mod.rs | 95 +++++++-- .../token_configuration/v0/accessors.rs | 55 ++--- .../token_configuration/v0/mod.rs | 73 ++++--- .../token_configuration_item.rs | 57 +++-- .../token_distribution_rules/accessors/mod.rs | 158 ++++++++++++++ .../accessors/v0/mod.rs | 73 +++++++ .../token_distribution_rules/mod.rs | 26 +++ .../token_distribution_rules/v0/accessors.rs | 114 ++++++++++ .../token_distribution_rules/v0/mod.rs | 79 +++++++ .../distribution_function/encode.rs | 179 ++++++++++++++++ .../distribution_function/mod.rs | 196 ++++++++++++++++++ .../token_perpetual_distribution/mod.rs | 25 +++ .../token_perpetual_distribution/v0/mod.rs | 81 ++++++++ .../token_pre_programmed_distribution/mod.rs | 24 +++ .../v0/mod.rs | 28 +++ .../data_contract/change_control_rules/mod.rs | 11 + .../change_control_rules/v0/mod.rs | 21 ++ packages/rs-dpp/src/lib.rs | 6 + .../token_mint_transition/v0/v0_methods.rs | 15 +- .../batched_transition/token_transition.rs | 3 +- .../state_v0/mod.rs | 5 +- .../state_v0/mod.rs | 3 +- .../state_v0/mod.rs | 4 - .../state_v0/mod.rs | 4 - .../state_v0/mod.rs | 5 +- .../state_v0/mod.rs | 3 +- .../state_transitions/batch/mod.rs | 32 ++- .../data_contract_update/mod.rs | 18 +- .../tests/strategy_tests/token_tests.rs | 13 +- .../contract/insert/insert_contract/v1/mod.rs | 3 + .../for_token_balances/v0/mod.rs | 2 - .../v0/transformer.rs | 13 +- 40 files changed, 1411 insertions(+), 276 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/accessors.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/v0/mod.rs diff --git a/Cargo.lock b/Cargo.lock index f55e79caa6..a12c5e4dbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1472,6 +1472,7 @@ dependencies = [ "nohash-hasher", "num_enum 0.7.3", "once_cell", + "ordered-float", "platform-serialization", "platform-serialization-derive", "platform-value", @@ -3405,6 +3406,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", + "rand", + "serde", +] + [[package]] name = "overload" version = "0.1.1" @@ -3860,6 +3872,7 @@ dependencies = [ "libc", "rand_chacha", "rand_core", + "serde", ] [[package]] @@ -3879,6 +3892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", + "serde", ] [[package]] diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index caa157a21c..113f578dac 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -14,6 +14,7 @@ authors = [ [dependencies] anyhow = { version = "1.0.81" } async-trait = { version = "0.1.79" } +ordered-float = { version = "4.6.0", features = ["serde"]} base64 = "0.22.1" bs58 = "0.5" byteorder = { version = "1.4" } diff --git a/packages/rs-dpp/src/data_contract/associated_token/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/mod.rs index d7558c24b1..ac8095f729 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/mod.rs @@ -1,3 +1,6 @@ pub mod token_configuration; pub mod token_configuration_convention; pub mod token_configuration_item; +pub mod token_distribution_rules; +pub mod token_perpetual_distribution; +pub mod token_pre_programmed_distribution; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 0429831203..2f063196a3 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -6,10 +6,10 @@ use crate::data_contract::associated_token::token_configuration::accessors::v0:: }; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention; +use crate::data_contract::associated_token::token_distribution_rules::TokenDistributionRules; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::GroupContractPosition; -use platform_value::Identifier; use std::collections::BTreeSet; /// Implementing TokenConfigurationV0Getters for TokenConfiguration @@ -69,30 +69,15 @@ impl TokenConfigurationV0Getters for TokenConfiguration { } } - /// Returns the new tokens destination identity. - fn new_tokens_destination_identity(&self) -> Option { + fn distribution_rules(&self) -> &TokenDistributionRules { match self { - TokenConfiguration::V0(v0) => v0.new_tokens_destination_identity(), + TokenConfiguration::V0(v0) => v0.distribution_rules(), } } - /// Returns the new tokens destination identity rules. - fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { + fn distribution_rules_mut(&mut self) -> &mut TokenDistributionRules { match self { - TokenConfiguration::V0(v0) => v0.new_tokens_destination_identity_rules(), - } - } - /// Returns whether minting allows choosing a destination. - fn minting_allow_choosing_destination(&self) -> bool { - match self { - TokenConfiguration::V0(v0) => v0.minting_allow_choosing_destination(), - } - } - - /// Returns the rules for minting destination selection. - fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { - match self { - TokenConfiguration::V0(v0) => v0.minting_allow_choosing_destination_rules(), + TokenConfiguration::V0(v0) => v0.distribution_rules_mut(), } } @@ -195,17 +180,9 @@ impl TokenConfigurationV0Setters for TokenConfiguration { } } - /// Sets the new tokens destination identity. - fn set_new_tokens_destination_identity(&mut self, id: Option) { + fn set_distribution_rules(&mut self, rules: TokenDistributionRules) { match self { - TokenConfiguration::V0(v0) => v0.set_new_tokens_destination_identity(id), - } - } - - /// Sets the new tokens destination identity rules. - fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { - match self { - TokenConfiguration::V0(v0) => v0.set_new_tokens_destination_identity_rules(rules), + TokenConfiguration::V0(v0) => v0.set_distribution_rules(rules), } } @@ -262,16 +239,4 @@ impl TokenConfigurationV0Setters for TokenConfiguration { TokenConfiguration::V0(v0) => v0.set_main_control_group_can_be_modified(action_takers), } } - - fn set_minting_allow_choosing_destination(&mut self, value: bool) { - match self { - TokenConfiguration::V0(v0) => v0.set_minting_allow_choosing_destination(value), - } - } - - fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { - match self { - TokenConfiguration::V0(v0) => v0.set_minting_allow_choosing_destination_rules(rules), - } - } } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index b1b4143059..2ab5f7a625 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -1,9 +1,9 @@ use crate::balances::credits::TokenAmount; use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention; +use crate::data_contract::associated_token::token_distribution_rules::TokenDistributionRules; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::GroupContractPosition; -use platform_value::Identifier; use std::collections::BTreeSet; /// Accessor trait for getters of `TokenConfigurationV0` @@ -28,15 +28,11 @@ pub trait TokenConfigurationV0Getters { /// Returns the max supply change rules. fn max_supply_change_rules(&self) -> &ChangeControlRules; - /// Returns the new tokens destination identity. - fn new_tokens_destination_identity(&self) -> Option; + /// Returns the distribution rules. + fn distribution_rules(&self) -> &TokenDistributionRules; - /// Returns the new tokens destination identity rules. - fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules; - /// Returns whether minting allows choosing a destination. - fn minting_allow_choosing_destination(&self) -> bool; - /// Returns the rules for minting destination selection. - fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules; + /// Returns a mutable reference to the distribution rules. + fn distribution_rules_mut(&mut self) -> &mut TokenDistributionRules; /// Returns the manual minting rules. fn manual_minting_rules(&self) -> &ChangeControlRules; @@ -81,11 +77,8 @@ pub trait TokenConfigurationV0Setters { /// Sets the max supply change rules. fn set_max_supply_change_rules(&mut self, rules: ChangeControlRules); - /// Sets the new tokens destination identity. - fn set_new_tokens_destination_identity(&mut self, id: Option); - - /// Sets the new tokens destination identity rules. - fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules); + /// Sets the distribution rules. + fn set_distribution_rules(&mut self, rules: TokenDistributionRules); /// Sets the manual minting rules. fn set_manual_minting_rules(&mut self, rules: ChangeControlRules); @@ -108,8 +101,4 @@ pub trait TokenConfigurationV0Setters { /// Sets the main control group can be modified. fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers); - /// Sets whether minting allows choosing a destination. - fn set_minting_allow_choosing_destination(&mut self, value: bool); - /// Sets the rules for minting destination selection. - fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules); } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/apply_token_configuration_item/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/apply_token_configuration_item/v0/mod.rs index 706faf5f48..e3d1c22f06 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/apply_token_configuration_item/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/apply_token_configuration_item/v0/mod.rs @@ -1,5 +1,9 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use crate::data_contract::associated_token::token_configuration_item::TokenConfigurationChangeItem; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::{ + TokenDistributionRulesV0Getters, TokenDistributionRulesV0Setters, +}; + impl TokenConfigurationV0 { /// Applies a `TokenConfigurationChangeItem` to this token configuration. /// @@ -35,31 +39,51 @@ impl TokenConfigurationV0 { .set_admin_action_takers(admin_group); } TokenConfigurationChangeItem::NewTokensDestinationIdentity(identity) => { - self.new_tokens_destination_identity = identity; + self.distribution_rules + .set_new_tokens_destination_identity(identity); } TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup( control_group, ) => { - self.new_tokens_destination_identity_rules + self.distribution_rules + .new_tokens_destination_identity_rules_mut() .set_authorized_to_make_change_action_takers(control_group); } TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(admin_group) => { - self.new_tokens_destination_identity_rules + self.distribution_rules + .new_tokens_destination_identity_rules_mut() .set_admin_action_takers(admin_group); } TokenConfigurationChangeItem::MintingAllowChoosingDestination(allow) => { - self.minting_allow_choosing_destination = allow; + self.distribution_rules + .set_minting_allow_choosing_destination(allow); } TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup( control_group, ) => { - self.minting_allow_choosing_destination_rules + self.distribution_rules + .minting_allow_choosing_destination_rules_mut() .set_authorized_to_make_change_action_takers(control_group); } TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup( admin_group, ) => { - self.minting_allow_choosing_destination_rules + self.distribution_rules + .minting_allow_choosing_destination_rules_mut() + .set_admin_action_takers(admin_group); + } + TokenConfigurationChangeItem::PerpetualDistribution(perpetual_distribution) => { + self.distribution_rules + .set_perpetual_distribution(perpetual_distribution); + } + TokenConfigurationChangeItem::PerpetualDistributionControlGroup(control_group) => { + self.distribution_rules + .perpetual_distribution_rules_mut() + .set_authorized_to_make_change_action_takers(control_group); + } + TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(admin_group) => { + self.distribution_rules + .perpetual_distribution_rules_mut() .set_admin_action_takers(admin_group); } TokenConfigurationChangeItem::ManualMinting(control_group) => { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/authorized_action_takers_for_configuration_item/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/authorized_action_takers_for_configuration_item/v0/mod.rs index bf8d070994..3549db93b1 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/authorized_action_takers_for_configuration_item/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/authorized_action_takers_for_configuration_item/v0/mod.rs @@ -1,5 +1,6 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use crate::data_contract::associated_token::token_configuration_item::TokenConfigurationChangeItem; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; impl TokenConfigurationV0 { /// Returns the authorized action takers for a specific `TokenConfigurationChangeItem`. @@ -21,10 +22,9 @@ impl TokenConfigurationV0 { .conventions_change_rules .authorized_to_make_change_action_takers() .clone(), - TokenConfigurationChangeItem::ConventionsControlGroup(_) => self - .conventions_change_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::ConventionsControlGroup(_) => { + self.conventions_change_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::ConventionsAdminGroup(_) => { self.conventions_change_rules.admin_action_takers().clone() } @@ -32,77 +32,92 @@ impl TokenConfigurationV0 { .max_supply_change_rules .authorized_to_make_change_action_takers() .clone(), - TokenConfigurationChangeItem::MaxSupplyControlGroup(_) => self - .max_supply_change_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::MaxSupplyControlGroup(_) => { + self.max_supply_change_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::MaxSupplyAdminGroup(_) => { self.max_supply_change_rules.admin_action_takers().clone() } + TokenConfigurationChangeItem::PerpetualDistribution(_) => self + .distribution_rules + .perpetual_distribution_rules() + .authorized_to_make_change_action_takers() + .clone(), + TokenConfigurationChangeItem::PerpetualDistributionControlGroup(_) => self + .distribution_rules + .perpetual_distribution_rules() + .admin_action_takers() + .clone(), + TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(_) => self + .distribution_rules + .perpetual_distribution_rules() + .admin_action_takers() + .clone(), TokenConfigurationChangeItem::NewTokensDestinationIdentity(_) => self - .new_tokens_destination_identity_rules + .distribution_rules + .new_tokens_destination_identity_rules() .authorized_to_make_change_action_takers() .clone(), TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup(_) => self - .new_tokens_destination_identity_rules - .authorized_to_make_change_action_takers() + .distribution_rules + .new_tokens_destination_identity_rules() + .admin_action_takers() .clone(), TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(_) => self - .new_tokens_destination_identity_rules + .distribution_rules + .new_tokens_destination_identity_rules() .admin_action_takers() .clone(), TokenConfigurationChangeItem::MintingAllowChoosingDestination(_) => self - .minting_allow_choosing_destination_rules + .distribution_rules + .minting_allow_choosing_destination_rules() .authorized_to_make_change_action_takers() .clone(), TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup(_) => self - .minting_allow_choosing_destination_rules - .authorized_to_make_change_action_takers() + .distribution_rules + .minting_allow_choosing_destination_rules() + .admin_action_takers() .clone(), TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup(_) => self - .minting_allow_choosing_destination_rules + .distribution_rules + .minting_allow_choosing_destination_rules() .admin_action_takers() .clone(), - TokenConfigurationChangeItem::ManualMinting(_) => self - .manual_minting_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::ManualMinting(_) => { + self.manual_minting_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::ManualMintingAdminGroup(_) => { self.manual_minting_rules.admin_action_takers().clone() } - TokenConfigurationChangeItem::ManualBurning(_) => self - .manual_burning_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::ManualBurning(_) => { + self.manual_burning_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::ManualBurningAdminGroup(_) => { self.manual_burning_rules.admin_action_takers().clone() } - TokenConfigurationChangeItem::Freeze(_) => self - .freeze_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::Freeze(_) => { + self.freeze_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::FreezeAdminGroup(_) => { self.freeze_rules.admin_action_takers().clone() } - TokenConfigurationChangeItem::Unfreeze(_) => self - .unfreeze_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::Unfreeze(_) => { + self.unfreeze_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::UnfreezeAdminGroup(_) => { self.unfreeze_rules.admin_action_takers().clone() } TokenConfigurationChangeItem::DestroyFrozenFunds(_) => self .destroy_frozen_funds_rules - .authorized_to_make_change_action_takers() + .admin_action_takers() .clone(), TokenConfigurationChangeItem::DestroyFrozenFundsAdminGroup(_) => self .destroy_frozen_funds_rules .admin_action_takers() .clone(), - TokenConfigurationChangeItem::EmergencyAction(_) => self - .emergency_action_rules - .authorized_to_make_change_action_takers() - .clone(), + TokenConfigurationChangeItem::EmergencyAction(_) => { + self.emergency_action_rules.admin_action_takers().clone() + } TokenConfigurationChangeItem::EmergencyActionAdminGroup(_) => { self.emergency_action_rules.admin_action_takers().clone() } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/can_apply_token_configuration_item/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/can_apply_token_configuration_item/v0/mod.rs index 158143efa0..d83cdc4b10 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/can_apply_token_configuration_item/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/can_apply_token_configuration_item/v0/mod.rs @@ -1,10 +1,12 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use crate::data_contract::associated_token::token_configuration_item::TokenConfigurationChangeItem; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use crate::data_contract::group::Group; use crate::data_contract::GroupContractPosition; use crate::group::action_taker::{ActionGoal, ActionTaker}; use platform_value::Identifier; use std::collections::BTreeMap; + impl TokenConfigurationV0 { /// Determines whether a `TokenConfigurationChangeItem` can be applied to this token configuration. /// @@ -74,13 +76,41 @@ impl TokenConfigurationV0 { goal, ) } + TokenConfigurationChangeItem::PerpetualDistribution(_) => self + .distribution_rules + .perpetual_distribution_rules() + .can_make_change(contract_owner_id, main_group, groups, action_taker, goal), + TokenConfigurationChangeItem::PerpetualDistributionControlGroup(control_group) => self + .distribution_rules + .perpetual_distribution_rules() + .can_change_authorized_action_takers( + control_group, + contract_owner_id, + main_group, + groups, + action_taker, + goal, + ), + TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(admin_group) => self + .distribution_rules + .perpetual_distribution_rules() + .can_change_admin_action_takers( + admin_group, + contract_owner_id, + main_group, + groups, + action_taker, + goal, + ), TokenConfigurationChangeItem::NewTokensDestinationIdentity(_) => self - .new_tokens_destination_identity_rules + .distribution_rules + .new_tokens_destination_identity_rules() .can_make_change(contract_owner_id, main_group, groups, action_taker, goal), TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup( control_group, ) => self - .new_tokens_destination_identity_rules + .distribution_rules + .new_tokens_destination_identity_rules() .can_change_authorized_action_takers( control_group, contract_owner_id, @@ -90,7 +120,8 @@ impl TokenConfigurationV0 { goal, ), TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(admin_group) => { - self.new_tokens_destination_identity_rules + self.distribution_rules + .new_tokens_destination_identity_rules() .can_change_admin_action_takers( admin_group, contract_owner_id, @@ -101,12 +132,14 @@ impl TokenConfigurationV0 { ) } TokenConfigurationChangeItem::MintingAllowChoosingDestination(_) => self - .minting_allow_choosing_destination_rules + .distribution_rules + .minting_allow_choosing_destination_rules() .can_make_change(contract_owner_id, main_group, groups, action_taker, goal), TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup( control_group, ) => self - .minting_allow_choosing_destination_rules + .distribution_rules + .minting_allow_choosing_destination_rules() .can_change_authorized_action_takers( control_group, contract_owner_id, @@ -118,7 +151,8 @@ impl TokenConfigurationV0 { TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup( admin_group, ) => self - .minting_allow_choosing_destination_rules + .distribution_rules + .minting_allow_choosing_destination_rules() .can_change_admin_action_takers( admin_group, contract_owner_id, diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 9789261865..4a5f368184 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,6 +1,7 @@ use crate::consensus::basic::data_contract::DataContractTokenConfigurationUpdateError; use crate::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use crate::data_contract::group::Group; use crate::data_contract::GroupContractPosition; use crate::group::action_taker::{ActionGoal, ActionTaker}; @@ -83,18 +84,28 @@ impl TokenConfiguration { } // Check changes to new_tokens_destination_identity and rules - if old.new_tokens_destination_identity != new.new_tokens_destination_identity - || old.new_tokens_destination_identity_rules - != new.new_tokens_destination_identity_rules + if old.distribution_rules.new_tokens_destination_identity() + != new.distribution_rules.new_tokens_destination_identity() + || old + .distribution_rules + .new_tokens_destination_identity_rules() + != new + .distribution_rules + .new_tokens_destination_identity_rules() { - if !old.new_tokens_destination_identity_rules.can_change_to( - &new.new_tokens_destination_identity_rules, - contract_owner_id, - self.main_control_group(), - groups, - action_taker, - goal, - ) { + if !old + .distribution_rules + .new_tokens_destination_identity_rules() + .can_change_to( + &new.distribution_rules + .new_tokens_destination_identity_rules(), + contract_owner_id, + self.main_control_group(), + groups, + action_taker, + goal, + ) + { return SimpleConsensusValidationResult::new_with_error( DataContractTokenConfigurationUpdateError::new( "update".to_string(), @@ -109,18 +120,28 @@ impl TokenConfiguration { } // Check changes to minting_allow_choosing_destination and its rules - if old.minting_allow_choosing_destination != new.minting_allow_choosing_destination - || old.minting_allow_choosing_destination_rules - != new.minting_allow_choosing_destination_rules + if old.distribution_rules.minting_allow_choosing_destination() + != new.distribution_rules.minting_allow_choosing_destination() + || old + .distribution_rules + .minting_allow_choosing_destination_rules() + != new + .distribution_rules + .minting_allow_choosing_destination_rules() { - if !old.minting_allow_choosing_destination_rules.can_change_to( - &new.minting_allow_choosing_destination_rules, - contract_owner_id, - self.main_control_group(), - groups, - action_taker, - goal, - ) { + if !old + .distribution_rules + .minting_allow_choosing_destination_rules() + .can_change_to( + &new.distribution_rules + .minting_allow_choosing_destination_rules(), + contract_owner_id, + self.main_control_group(), + groups, + action_taker, + goal, + ) + { return SimpleConsensusValidationResult::new_with_error( DataContractTokenConfigurationUpdateError::new( "update".to_string(), @@ -134,6 +155,36 @@ impl TokenConfiguration { } } + // Check changes to perpetual_distribution and its rules + if old.distribution_rules.perpetual_distribution() + != new.distribution_rules.perpetual_distribution() + || old.distribution_rules.perpetual_distribution_rules() + != new.distribution_rules.perpetual_distribution_rules() + { + if !old + .distribution_rules + .perpetual_distribution_rules() + .can_change_to( + &new.distribution_rules.perpetual_distribution_rules(), + contract_owner_id, + self.main_control_group(), + groups, + action_taker, + goal, + ) + { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "perpetualDistribution or perpetualDistributionRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + // Check changes to manual_minting_rules if old.manual_minting_rules != new.manual_minting_rules { if !old.manual_minting_rules.can_change_to( diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index 3d4642ab8d..7a289badbd 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -5,10 +5,11 @@ use crate::data_contract::associated_token::token_configuration::accessors::v0:: use crate::data_contract::associated_token::token_configuration::v0::{ TokenConfigurationConvention, TokenConfigurationV0, }; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; +use crate::data_contract::associated_token::token_distribution_rules::TokenDistributionRules; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::GroupContractPosition; -use platform_value::Identifier; use std::collections::BTreeSet; /// Implementing `TokenConfigurationV0Getters` for `TokenConfigurationV0` @@ -53,24 +54,12 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { &self.max_supply_change_rules } - /// Returns the new tokens destination identity. - fn new_tokens_destination_identity(&self) -> Option { - self.new_tokens_destination_identity + fn distribution_rules(&self) -> &TokenDistributionRules { + &self.distribution_rules } - /// Returns the new tokens destination identity rules. - fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { - &self.new_tokens_destination_identity_rules - } - - /// Returns whether minting allows choosing a destination. - fn minting_allow_choosing_destination(&self) -> bool { - self.minting_allow_choosing_destination - } - - /// Returns the rules for minting destination selection. - fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { - &self.minting_allow_choosing_destination_rules + fn distribution_rules_mut(&mut self) -> &mut TokenDistributionRules { + &mut self.distribution_rules } /// Returns the manual minting rules. @@ -138,8 +127,15 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { // Apply the helper to all fields containing `ChangeControlRules` add_from_change_control_rules(&self.max_supply_change_rules); add_from_change_control_rules(&self.conventions_change_rules); - add_from_change_control_rules(&self.new_tokens_destination_identity_rules); - add_from_change_control_rules(&self.minting_allow_choosing_destination_rules); + add_from_change_control_rules( + self.distribution_rules + .new_tokens_destination_identity_rules(), + ); + add_from_change_control_rules( + self.distribution_rules + .minting_allow_choosing_destination_rules(), + ); + add_from_change_control_rules(self.distribution_rules.perpetual_distribution_rules()); add_from_change_control_rules(&self.manual_minting_rules); add_from_change_control_rules(&self.manual_burning_rules); add_from_change_control_rules(&self.freeze_rules); @@ -181,16 +177,9 @@ impl TokenConfigurationV0Setters for TokenConfigurationV0 { self.max_supply_change_rules = rules; } - /// Sets the new tokens destination identity. - fn set_new_tokens_destination_identity(&mut self, id: Option) { - self.new_tokens_destination_identity = id; - } - - /// Sets the new tokens destination identity rules. - fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { - self.new_tokens_destination_identity_rules = rules; + fn set_distribution_rules(&mut self, rules: TokenDistributionRules) { + self.distribution_rules = rules; } - /// Sets the manual minting rules. fn set_manual_minting_rules(&mut self, rules: ChangeControlRules) { self.manual_minting_rules = rules; @@ -230,14 +219,4 @@ impl TokenConfigurationV0Setters for TokenConfigurationV0 { fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers) { self.main_control_group_can_be_modified = action_takers; } - - /// Sets whether minting allows choosing a destination. - fn set_minting_allow_choosing_destination(&mut self, value: bool) { - self.minting_allow_choosing_destination = value; - } - - /// Sets the rules for minting destination selection. - fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { - self.minting_allow_choosing_destination_rules = rules; - } } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 6f6bcd9556..eb6c23f6e6 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -3,12 +3,13 @@ mod accessors; use crate::balances::credits::TokenAmount; use crate::data_contract::associated_token::token_configuration_convention::v0::TokenConfigurationConventionV0; use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention; +use crate::data_contract::associated_token::token_distribution_rules::v0::TokenDistributionRulesV0; +use crate::data_contract::associated_token::token_distribution_rules::TokenDistributionRules; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::GroupContractPosition; use bincode::{Decode, Encode}; -use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::fmt; @@ -34,14 +35,8 @@ pub struct TokenConfigurationV0 { /// Even if set no one can ever change this under the base supply #[serde(default = "default_change_control_rules")] pub max_supply_change_rules: ChangeControlRules, - #[serde(default)] - pub new_tokens_destination_identity: Option, - #[serde(default = "default_change_control_rules")] - pub new_tokens_destination_identity_rules: ChangeControlRules, - #[serde(default = "default_minting_allow_choosing_destination")] - pub minting_allow_choosing_destination: bool, - #[serde(default = "default_change_control_rules")] - pub minting_allow_choosing_destination_rules: ChangeControlRules, + /// The distribution rules for the token + pub distribution_rules: TokenDistributionRules, #[serde(default = "default_contract_owner_change_control_rules")] pub manual_minting_rules: ChangeControlRules, #[serde(default = "default_contract_owner_change_control_rules")] @@ -60,11 +55,6 @@ pub struct TokenConfigurationV0 { pub main_control_group_can_be_modified: AuthorizedActionTakers, } -// Default function for `minting_allow_choosing_destination` to return `true` -fn default_minting_allow_choosing_destination() -> bool { - true -} - // Default function for `keeps_history` fn default_keeps_history() -> bool { true // Default to `true` for keeps_history @@ -99,7 +89,7 @@ impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "TokenConfigurationV0 {{\n conventions: {:?},\n conventions_change_rules: {:?},\n base_supply: {},\n max_supply: {:?},\n keeps_history: {},\n start_as_paused: {},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n destroy_frozen_funds_rules: {:?},\n emergency_action_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", + "TokenConfigurationV0 {{\n conventions: {:?},\n conventions_change_rules: {:?},\n base_supply: {},\n max_supply: {:?},\n keeps_history: {},\n start_as_paused: {},\n max_supply_change_rules: {:?},\n distribution_rules: {},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n destroy_frozen_funds_rules: {:?},\n emergency_action_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", self.conventions, self.conventions_change_rules, self.base_supply, @@ -107,10 +97,7 @@ impl fmt::Display for TokenConfigurationV0 { self.keeps_history, self.start_as_paused, self.max_supply_change_rules, - self.new_tokens_destination_identity, - self.new_tokens_destination_identity_rules, - self.minting_allow_choosing_destination, - self.minting_allow_choosing_destination_rules, + self.distribution_rules, self.manual_minting_rules, self.manual_burning_rules, self.freeze_rules, @@ -150,24 +137,36 @@ impl TokenConfigurationV0 { self_changing_admin_action_takers_allowed: false, } .into(), - new_tokens_destination_identity: None, - new_tokens_destination_identity_rules: ChangeControlRulesV0 { - authorized_to_make_change: AuthorizedActionTakers::NoOne, - admin_action_takers: AuthorizedActionTakers::NoOne, - changing_authorized_action_takers_to_no_one_allowed: false, - changing_admin_action_takers_to_no_one_allowed: false, - self_changing_admin_action_takers_allowed: false, - } - .into(), - minting_allow_choosing_destination: true, - minting_allow_choosing_destination_rules: ChangeControlRulesV0 { - authorized_to_make_change: AuthorizedActionTakers::NoOne, - admin_action_takers: AuthorizedActionTakers::NoOne, - changing_authorized_action_takers_to_no_one_allowed: false, - changing_admin_action_takers_to_no_one_allowed: false, - self_changing_admin_action_takers_allowed: false, - } - .into(), + distribution_rules: TokenDistributionRules::V0(TokenDistributionRulesV0 { + perpetual_distribution: None, + perpetual_distribution_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + } + .into(), + pre_programmed_distribution: None, + new_tokens_destination_identity: None, + new_tokens_destination_identity_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + } + .into(), + minting_allow_choosing_destination: true, + minting_allow_choosing_destination_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + } + .into(), + }), manual_minting_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, admin_action_takers: AuthorizedActionTakers::NoOne, diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs index 12c32c83be..e91788708e 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs @@ -1,5 +1,6 @@ use crate::balances::credits::TokenAmount; use crate::data_contract::associated_token::token_configuration_convention::TokenConfigurationConvention; +use crate::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::GroupContractPosition; use crate::ProtocolError; @@ -36,6 +37,9 @@ pub enum TokenConfigurationChangeItem { MaxSupply(Option), MaxSupplyControlGroup(AuthorizedActionTakers), MaxSupplyAdminGroup(AuthorizedActionTakers), + PerpetualDistribution(Option), + PerpetualDistributionControlGroup(AuthorizedActionTakers), + PerpetualDistributionAdminGroup(AuthorizedActionTakers), NewTokensDestinationIdentity(Option), NewTokensDestinationIdentityControlGroup(AuthorizedActionTakers), NewTokensDestinationIdentityAdminGroup(AuthorizedActionTakers), @@ -56,7 +60,6 @@ pub enum TokenConfigurationChangeItem { EmergencyActionAdminGroup(AuthorizedActionTakers), MainControlGroup(Option), } - impl TokenConfigurationChangeItem { pub fn u8_item_index(&self) -> u8 { match self { @@ -67,25 +70,28 @@ impl TokenConfigurationChangeItem { TokenConfigurationChangeItem::MaxSupply(_) => 4, TokenConfigurationChangeItem::MaxSupplyControlGroup(_) => 5, TokenConfigurationChangeItem::MaxSupplyAdminGroup(_) => 6, - TokenConfigurationChangeItem::NewTokensDestinationIdentity(_) => 7, - TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup(_) => 8, - TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(_) => 9, - TokenConfigurationChangeItem::MintingAllowChoosingDestination(_) => 10, - TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup(_) => 11, - TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup(_) => 12, - TokenConfigurationChangeItem::ManualMinting(_) => 13, - TokenConfigurationChangeItem::ManualMintingAdminGroup(_) => 14, - TokenConfigurationChangeItem::ManualBurning(_) => 15, - TokenConfigurationChangeItem::ManualBurningAdminGroup(_) => 16, - TokenConfigurationChangeItem::Freeze(_) => 17, - TokenConfigurationChangeItem::FreezeAdminGroup(_) => 18, - TokenConfigurationChangeItem::Unfreeze(_) => 19, - TokenConfigurationChangeItem::UnfreezeAdminGroup(_) => 20, - TokenConfigurationChangeItem::DestroyFrozenFunds(_) => 21, - TokenConfigurationChangeItem::DestroyFrozenFundsAdminGroup(_) => 22, - TokenConfigurationChangeItem::EmergencyAction(_) => 23, - TokenConfigurationChangeItem::EmergencyActionAdminGroup(_) => 24, - TokenConfigurationChangeItem::MainControlGroup(_) => 25, + TokenConfigurationChangeItem::PerpetualDistribution(_) => 7, + TokenConfigurationChangeItem::PerpetualDistributionControlGroup(_) => 8, + TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(_) => 9, + TokenConfigurationChangeItem::NewTokensDestinationIdentity(_) => 10, + TokenConfigurationChangeItem::NewTokensDestinationIdentityControlGroup(_) => 11, + TokenConfigurationChangeItem::NewTokensDestinationIdentityAdminGroup(_) => 12, + TokenConfigurationChangeItem::MintingAllowChoosingDestination(_) => 13, + TokenConfigurationChangeItem::MintingAllowChoosingDestinationControlGroup(_) => 14, + TokenConfigurationChangeItem::MintingAllowChoosingDestinationAdminGroup(_) => 15, + TokenConfigurationChangeItem::ManualMinting(_) => 16, + TokenConfigurationChangeItem::ManualMintingAdminGroup(_) => 17, + TokenConfigurationChangeItem::ManualBurning(_) => 18, + TokenConfigurationChangeItem::ManualBurningAdminGroup(_) => 19, + TokenConfigurationChangeItem::Freeze(_) => 20, + TokenConfigurationChangeItem::FreezeAdminGroup(_) => 21, + TokenConfigurationChangeItem::Unfreeze(_) => 22, + TokenConfigurationChangeItem::UnfreezeAdminGroup(_) => 23, + TokenConfigurationChangeItem::DestroyFrozenFunds(_) => 24, + TokenConfigurationChangeItem::DestroyFrozenFundsAdminGroup(_) => 25, + TokenConfigurationChangeItem::EmergencyAction(_) => 26, + TokenConfigurationChangeItem::EmergencyActionAdminGroup(_) => 27, + TokenConfigurationChangeItem::MainControlGroup(_) => 28, } } } @@ -115,6 +121,17 @@ impl fmt::Display for TokenConfigurationChangeItem { TokenConfigurationChangeItem::MaxSupplyAdminGroup(admin_group) => { write!(f, "Max Supply Admin Group: {}", admin_group) } + TokenConfigurationChangeItem::PerpetualDistribution(distribution) => match distribution + { + Some(dist) => write!(f, "Perpetual Distribution: {}", dist), + None => write!(f, "Perpetual Distribution: None"), + }, + TokenConfigurationChangeItem::PerpetualDistributionControlGroup(control_group) => { + write!(f, "Perpetual Distribution Control Group: {}", control_group) + } + TokenConfigurationChangeItem::PerpetualDistributionAdminGroup(admin_group) => { + write!(f, "Perpetual Distribution Admin Group: {}", admin_group) + } TokenConfigurationChangeItem::NewTokensDestinationIdentity(identity) => { match identity { Some(id) => write!(f, "New Tokens Destination Identity: {}", id), diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/mod.rs new file mode 100644 index 0000000000..f189476244 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/mod.rs @@ -0,0 +1,158 @@ +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::{ + TokenDistributionRulesV0Getters, TokenDistributionRulesV0Setters, +}; +use crate::data_contract::associated_token::token_distribution_rules::TokenDistributionRules; +use crate::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; +use crate::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; +use crate::data_contract::change_control_rules::ChangeControlRules; +use platform_value::Identifier; + +pub mod v0; +/// Implementing `TokenDistributionRulesV0Getters` for `TokenDistributionRules` +impl TokenDistributionRulesV0Getters for TokenDistributionRules { + /// Returns the perpetual distribution configuration. + fn perpetual_distribution(&self) -> Option<&TokenPerpetualDistribution> { + match self { + TokenDistributionRules::V0(v0) => v0.perpetual_distribution(), + } + } + + /// Returns the perpetual distribution configuration (mutable). + fn perpetual_distribution_mut(&mut self) -> Option<&mut TokenPerpetualDistribution> { + match self { + TokenDistributionRules::V0(v0) => v0.perpetual_distribution_mut(), + } + } + + /// Returns the perpetual distribution change rules. + fn perpetual_distribution_rules(&self) -> &ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.perpetual_distribution_rules(), + } + } + + /// Returns the perpetual distribution change rules (mutable). + fn perpetual_distribution_rules_mut(&mut self) -> &mut ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.perpetual_distribution_rules_mut(), + } + } + + /// Returns the pre-programmed distribution configuration. + fn pre_programmed_distribution(&self) -> Option<&TokenPreProgrammedDistribution> { + match self { + TokenDistributionRules::V0(v0) => v0.pre_programmed_distribution(), + } + } + + /// Returns the pre-programmed distribution configuration (mutable). + fn pre_programmed_distribution_mut(&mut self) -> Option<&mut TokenPreProgrammedDistribution> { + match self { + TokenDistributionRules::V0(v0) => v0.pre_programmed_distribution_mut(), + } + } + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option<&Identifier> { + match self { + TokenDistributionRules::V0(v0) => v0.new_tokens_destination_identity(), + } + } + + /// Returns the rules for changing the new tokens destination identity. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.new_tokens_destination_identity_rules(), + } + } + + /// Returns the rules for changing the new tokens destination identity (mutable). + fn new_tokens_destination_identity_rules_mut(&mut self) -> &mut ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.new_tokens_destination_identity_rules_mut(), + } + } + + /// Returns whether minting allows choosing destination. + fn minting_allow_choosing_destination(&self) -> bool { + match self { + TokenDistributionRules::V0(v0) => v0.minting_allow_choosing_destination(), + } + } + + /// Returns the rules for changing the minting allow choosing destination setting. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.minting_allow_choosing_destination_rules(), + } + } + + /// Returns the rules for changing the minting allow choosing destination setting (mutable). + fn minting_allow_choosing_destination_rules_mut(&mut self) -> &mut ChangeControlRules { + match self { + TokenDistributionRules::V0(v0) => v0.minting_allow_choosing_destination_rules_mut(), + } + } +} + +/// Implementing `TokenDistributionRulesV0Setters` for `TokenDistributionRules` +impl TokenDistributionRulesV0Setters for TokenDistributionRules { + /// Sets the perpetual distribution configuration. + fn set_perpetual_distribution( + &mut self, + perpetual_distribution: Option, + ) { + match self { + TokenDistributionRules::V0(v0) => v0.set_perpetual_distribution(perpetual_distribution), + } + } + + /// Sets the perpetual distribution change rules. + fn set_perpetual_distribution_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenDistributionRules::V0(v0) => v0.set_perpetual_distribution_rules(rules), + } + } + + /// Sets the pre-programmed distribution configuration. + fn set_pre_programmed_distribution( + &mut self, + pre_programmed_distribution: Option, + ) { + match self { + TokenDistributionRules::V0(v0) => { + v0.set_pre_programmed_distribution(pre_programmed_distribution) + } + } + } + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, identity: Option) { + match self { + TokenDistributionRules::V0(v0) => v0.set_new_tokens_destination_identity(identity), + } + } + + /// Sets the rules for changing the new tokens destination identity. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenDistributionRules::V0(v0) => v0.set_new_tokens_destination_identity_rules(rules), + } + } + + /// Sets whether minting allows choosing destination. + fn set_minting_allow_choosing_destination(&mut self, allow: bool) { + match self { + TokenDistributionRules::V0(v0) => v0.set_minting_allow_choosing_destination(allow), + } + } + + /// Sets the rules for changing the minting allow choosing destination setting. + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenDistributionRules::V0(v0) => { + v0.set_minting_allow_choosing_destination_rules(rules) + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/v0/mod.rs new file mode 100644 index 0000000000..5b7c5080ee --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/accessors/v0/mod.rs @@ -0,0 +1,73 @@ +use crate::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; +use crate::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; +use crate::data_contract::change_control_rules::ChangeControlRules; +use platform_value::Identifier; + +/// Accessor trait for getters of `TokenDistributionRulesV0` +pub trait TokenDistributionRulesV0Getters { + /// Returns the perpetual distribution configuration. + fn perpetual_distribution(&self) -> Option<&TokenPerpetualDistribution>; + + /// Returns the perpetual distribution configuration. + fn perpetual_distribution_mut(&mut self) -> Option<&mut TokenPerpetualDistribution>; + + /// Returns the perpetual distribution change rules. + fn perpetual_distribution_rules(&self) -> &ChangeControlRules; + + /// Returns the perpetual distribution change rules. + fn perpetual_distribution_rules_mut(&mut self) -> &mut ChangeControlRules; + + /// Returns the pre-programmed distribution configuration. + fn pre_programmed_distribution(&self) -> Option<&TokenPreProgrammedDistribution>; + + /// Returns the pre-programmed distribution configuration. + fn pre_programmed_distribution_mut(&mut self) -> Option<&mut TokenPreProgrammedDistribution>; + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option<&Identifier>; + + /// Returns the rules for changing the new tokens destination identity. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules; + + /// Returns the rules for changing the new tokens destination identity. + fn new_tokens_destination_identity_rules_mut(&mut self) -> &mut ChangeControlRules; + + /// Returns whether minting allows choosing destination. + fn minting_allow_choosing_destination(&self) -> bool; + + /// Returns the rules for changing the minting allow choosing destination setting. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules; + + /// Returns the rules for changing the minting allow choosing destination setting. + fn minting_allow_choosing_destination_rules_mut(&mut self) -> &mut ChangeControlRules; +} + +/// Accessor trait for setters of `TokenDistributionRulesV0` +pub trait TokenDistributionRulesV0Setters { + /// Sets the perpetual distribution configuration. + fn set_perpetual_distribution( + &mut self, + perpetual_distribution: Option, + ); + + /// Sets the perpetual distribution change rules. + fn set_perpetual_distribution_rules(&mut self, rules: ChangeControlRules); + + /// Sets the pre-programmed distribution configuration. + fn set_pre_programmed_distribution( + &mut self, + pre_programmed_distribution: Option, + ); + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, identity: Option); + + /// Sets the rules for changing the new tokens destination identity. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules); + + /// Sets whether minting allows choosing destination. + fn set_minting_allow_choosing_destination(&mut self, allow: bool); + + /// Sets the rules for changing the minting allow choosing destination setting. + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules); +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/mod.rs new file mode 100644 index 0000000000..df242893a7 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/mod.rs @@ -0,0 +1,26 @@ +use bincode::{Decode, Encode}; +use derive_more::From; +use serde::{Deserialize, Serialize}; + +pub mod accessors; +pub mod v0; + +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] +#[serde(tag = "$format_version")] +pub enum TokenDistributionRules { + #[serde(rename = "0")] + V0(TokenDistributionRulesV0), +} + +use crate::data_contract::associated_token::token_distribution_rules::v0::TokenDistributionRulesV0; +use std::fmt; + +impl fmt::Display for TokenDistributionRules { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TokenDistributionRules::V0(v0) => { + write!(f, "{}", v0) //just pass through + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/accessors.rs new file mode 100644 index 0000000000..397e609525 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/accessors.rs @@ -0,0 +1,114 @@ +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::{ + TokenDistributionRulesV0Getters, TokenDistributionRulesV0Setters, +}; +use crate::data_contract::associated_token::token_distribution_rules::v0::TokenDistributionRulesV0; +use crate::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; +use crate::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; +use crate::data_contract::change_control_rules::ChangeControlRules; +use platform_value::Identifier; +/// Implementing `TokenDistributionRulesV0Getters` for `TokenDistributionRulesV0` +impl TokenDistributionRulesV0Getters for TokenDistributionRulesV0 { + /// Returns the perpetual distribution configuration. + fn perpetual_distribution(&self) -> Option<&TokenPerpetualDistribution> { + self.perpetual_distribution.as_ref() + } + + /// Returns the perpetual distribution configuration (mutable). + fn perpetual_distribution_mut(&mut self) -> Option<&mut TokenPerpetualDistribution> { + self.perpetual_distribution.as_mut() + } + + /// Returns the perpetual distribution change rules. + fn perpetual_distribution_rules(&self) -> &ChangeControlRules { + &self.perpetual_distribution_rules + } + + /// Returns the perpetual distribution change rules (mutable). + fn perpetual_distribution_rules_mut(&mut self) -> &mut ChangeControlRules { + &mut self.perpetual_distribution_rules + } + + /// Returns the pre-programmed distribution configuration. + fn pre_programmed_distribution(&self) -> Option<&TokenPreProgrammedDistribution> { + self.pre_programmed_distribution.as_ref() + } + + /// Returns the pre-programmed distribution configuration (mutable). + fn pre_programmed_distribution_mut(&mut self) -> Option<&mut TokenPreProgrammedDistribution> { + self.pre_programmed_distribution.as_mut() + } + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option<&Identifier> { + self.new_tokens_destination_identity.as_ref() + } + + /// Returns the rules for changing the new tokens destination identity. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { + &self.new_tokens_destination_identity_rules + } + + /// Returns the rules for changing the new tokens destination identity (mutable). + fn new_tokens_destination_identity_rules_mut(&mut self) -> &mut ChangeControlRules { + &mut self.new_tokens_destination_identity_rules + } + + /// Returns whether minting allows choosing destination. + fn minting_allow_choosing_destination(&self) -> bool { + self.minting_allow_choosing_destination + } + + /// Returns the rules for changing the minting allow choosing destination setting. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { + &self.minting_allow_choosing_destination_rules + } + + /// Returns the rules for changing the minting allow choosing destination setting (mutable). + fn minting_allow_choosing_destination_rules_mut(&mut self) -> &mut ChangeControlRules { + &mut self.minting_allow_choosing_destination_rules + } +} + +/// Implementing `TokenDistributionRulesV0Setters` for `TokenDistributionRulesV0` +impl TokenDistributionRulesV0Setters for TokenDistributionRulesV0 { + /// Sets the perpetual distribution configuration. + fn set_perpetual_distribution( + &mut self, + perpetual_distribution: Option, + ) { + self.perpetual_distribution = perpetual_distribution; + } + + /// Sets the perpetual distribution change rules. + fn set_perpetual_distribution_rules(&mut self, rules: ChangeControlRules) { + self.perpetual_distribution_rules = rules; + } + + /// Sets the pre-programmed distribution configuration. + fn set_pre_programmed_distribution( + &mut self, + pre_programmed_distribution: Option, + ) { + self.pre_programmed_distribution = pre_programmed_distribution; + } + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, identity: Option) { + self.new_tokens_destination_identity = identity; + } + + /// Sets the rules for changing the new tokens destination identity. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { + self.new_tokens_destination_identity_rules = rules; + } + + /// Sets whether minting allows choosing destination. + fn set_minting_allow_choosing_destination(&mut self, allow: bool) { + self.minting_allow_choosing_destination = allow; + } + + /// Sets the rules for changing the minting allow choosing destination setting. + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { + self.minting_allow_choosing_destination_rules = rules; + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/mod.rs new file mode 100644 index 0000000000..ddcc549a4b --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_distribution_rules/v0/mod.rs @@ -0,0 +1,79 @@ +mod accessors; + +use crate::data_contract::associated_token::token_perpetual_distribution::TokenPerpetualDistribution; +use crate::data_contract::associated_token::token_pre_programmed_distribution::TokenPreProgrammedDistribution; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; +use crate::data_contract::change_control_rules::ChangeControlRules; +use bincode::Encode; +use platform_serialization::de::Decode; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct TokenDistributionRulesV0 { + #[serde(default)] + pub perpetual_distribution: Option, + #[serde(default = "default_change_control_rules")] + pub perpetual_distribution_rules: ChangeControlRules, + #[serde(default)] + pub pre_programmed_distribution: Option, + #[serde(default)] + pub new_tokens_destination_identity: Option, + #[serde(default = "default_change_control_rules")] + pub new_tokens_destination_identity_rules: ChangeControlRules, + #[serde(default = "default_minting_allow_choosing_destination")] + pub minting_allow_choosing_destination: bool, + #[serde(default = "default_change_control_rules")] + pub minting_allow_choosing_destination_rules: ChangeControlRules, +} + +// Default function for `minting_allow_choosing_destination` to return `true` +fn default_minting_allow_choosing_destination() -> bool { + true +} + +fn default_change_control_rules() -> ChangeControlRules { + ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + }) +} + +impl fmt::Display for TokenDistributionRulesV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "TokenDistributionRulesV0 {{\n \ + perpetual_distribution: {},\n \ + perpetual_distribution_rules: {},\n \ + pre_programmed_distribution: {},\n \ + new_tokens_destination_identity: {},\n \ + new_tokens_destination_identity_rules: {},\n \ + minting_allow_choosing_destination: {},\n \ + minting_allow_choosing_destination_rules: {}\n\ + }}", + match &self.perpetual_distribution { + Some(value) => format!("{}", value), + None => "None".to_string(), + }, + self.perpetual_distribution_rules, + match &self.pre_programmed_distribution { + Some(value) => format!("{}", value), + None => "None".to_string(), + }, + match &self.new_tokens_destination_identity { + Some(value) => format!("{}", value), + None => "None".to_string(), + }, + self.new_tokens_destination_identity_rules, + self.minting_allow_choosing_destination, + self.minting_allow_choosing_destination_rules, + ) + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs new file mode 100644 index 0000000000..80ca17b4fa --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/encode.rs @@ -0,0 +1,179 @@ +use crate::balances::credits::{SignedTokenAmount, TokenAmount}; +use crate::data_contract::associated_token::token_perpetual_distribution::distribution_function::DistributionFunction; +use bincode::{BorrowDecode, Decode, Encode}; +use ordered_float::NotNan; + +// Implement Encode for DistributionFunction +impl Encode for DistributionFunction { + fn encode( + &self, + encoder: &mut E, + ) -> Result<(), bincode::error::EncodeError> { + match self { + DistributionFunction::LinearInteger { a, b } => { + 0u8.encode(encoder)?; // Variant index for LinearInteger + a.encode(encoder)?; + b.encode(encoder)?; + } + DistributionFunction::LinearFloat { a, b } => { + 1u8.encode(encoder)?; // Variant index for LinearFloat + a.into_inner().encode(encoder)?; // Encode the NotNan value as f64 + b.encode(encoder)?; + } + DistributionFunction::PolynomialInteger { a, n, b } => { + 2u8.encode(encoder)?; // Variant index for PolynomialInteger + a.encode(encoder)?; + n.encode(encoder)?; + b.encode(encoder)?; + } + DistributionFunction::PolynomialFloat { a, n, b } => { + 3u8.encode(encoder)?; // Variant index for PolynomialFloat + a.into_inner().encode(encoder)?; + n.into_inner().encode(encoder)?; + b.encode(encoder)?; + } + DistributionFunction::Exponential { a, b, c } => { + 4u8.encode(encoder)?; // Variant index for Exponential + a.into_inner().encode(encoder)?; + b.into_inner().encode(encoder)?; + c.encode(encoder)?; + } + DistributionFunction::Logarithmic { a, b, c } => { + 5u8.encode(encoder)?; // Variant index for Logarithmic + a.into_inner().encode(encoder)?; + b.into_inner().encode(encoder)?; + c.encode(encoder)?; + } + DistributionFunction::Stepwise(steps) => { + 6u8.encode(encoder)?; // Variant index for Stepwise + steps.encode(encoder)?; + } + } + Ok(()) + } +} + +// Implement Decode for DistributionFunction +impl Decode for DistributionFunction { + fn decode( + decoder: &mut D, + ) -> Result { + let variant = u8::decode(decoder)?; + match variant { + 0 => { + let a = i64::decode(decoder)?; + let b = SignedTokenAmount::decode(decoder)?; + Ok(Self::LinearInteger { a, b }) + } + 1 => { + let a = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let b = SignedTokenAmount::decode(decoder)?; + Ok(Self::LinearFloat { a, b }) + } + 2 => { + let a = i64::decode(decoder)?; + let n = i64::decode(decoder)?; + let b = SignedTokenAmount::decode(decoder)?; + Ok(Self::PolynomialInteger { a, n, b }) + } + 3 => { + let a = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let n = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let b = SignedTokenAmount::decode(decoder)?; + Ok(Self::PolynomialFloat { a, n, b }) + } + 4 => { + let a = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let b = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let c = SignedTokenAmount::decode(decoder)?; + Ok(Self::Exponential { a, b, c }) + } + 5 => { + let a = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let b = NotNan::new(f64::decode(decoder)?).map_err(|_| { + bincode::error::DecodeError::OtherString("Invalid float: NaN".into()) + })?; + let c = SignedTokenAmount::decode(decoder)?; + Ok(Self::Logarithmic { a, b, c }) + } + 6 => { + let steps = Vec::<(u64, TokenAmount)>::decode(decoder)?; + Ok(Self::Stepwise(steps)) + } + _ => Err(bincode::error::DecodeError::OtherString( + "Invalid variant".into(), + )), + } + } +} + +impl<'de> BorrowDecode<'de> for DistributionFunction { + fn borrow_decode>( + decoder: &mut D, + ) -> Result { + let variant = u8::borrow_decode(decoder)?; // Decode the variant tag + + match variant { + 0 => { + let a = i64::borrow_decode(decoder)?; + let b = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::LinearInteger { a, b }) + } + 1 => { + let a = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let b = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::LinearFloat { a, b }) + } + 2 => { + let a = i64::borrow_decode(decoder)?; + let n = i64::borrow_decode(decoder)?; + let b = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::PolynomialInteger { a, n, b }) + } + 3 => { + let a = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let n = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let b = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::PolynomialFloat { a, n, b }) + } + 4 => { + let a = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let b = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let c = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::Exponential { a, b, c }) + } + 5 => { + let a = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let b = NotNan::::new(f64::borrow_decode(decoder)?) + .map_err(|e| bincode::error::DecodeError::OtherString(e.to_string()))?; + let c = SignedTokenAmount::borrow_decode(decoder)?; + Ok(DistributionFunction::Logarithmic { a, b, c }) + } + 6 => { + let steps = Vec::<(u64, TokenAmount)>::borrow_decode(decoder)?; + Ok(DistributionFunction::Stepwise(steps)) + } + _ => Err(bincode::error::DecodeError::OtherString( + "Invalid variant tag for DistributionFunction".to_string(), + )), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs new file mode 100644 index 0000000000..1fa7af8bf2 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs @@ -0,0 +1,196 @@ +use crate::balances::credits::{SignedTokenAmount, TokenAmount}; +use ordered_float::NotNan; +use serde::{Deserialize, Serialize}; +use std::fmt; + +mod encode; + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd)] +pub enum DistributionFunction { + /// A linear function emits tokens in increasing or decreasing amounts over time (integer precision). + /// + /// # Formula + /// - `f(x) = a * x + b` + /// - Where `a` is the slope (rate of change) and `b` is the initial value. + /// + /// # Description + /// - `a > 0`: Tokens increase over time. + /// - `a < 0`: Tokens decrease over time. + /// - `b` is the starting emission value. + /// + /// # Use Case + /// - Incentivize early adopters with higher rewards (`a < 0`). + /// - Gradually increase emissions to match ecosystem growth (`a > 0`). + /// + /// # Example + /// - Start with 50 tokens and increase by 10 tokens per epoch: `f(x) = 10x + 50`. + LinearInteger { a: i64, b: SignedTokenAmount }, + + /// A linear function emits tokens in increasing or decreasing amounts over time (floating-point precision). + /// + /// # Formula + /// - `f(x) = a * x + b` + /// - Where `a` is the slope (rate of change) and `b` is the initial value. + /// + /// # Description + /// - `a > 0`: Tokens increase over time. + /// - `a < 0`: Tokens decrease over time. + /// - `b` is the starting emission value. + /// + /// # Use Case + /// - Similar to `LinearInteger`, but supports fractional rates of change. + /// + /// # Example + /// - Start with 50 tokens and increase by 0.5 tokens per epoch: `f(x) = 0.5x + 50`. + LinearFloat { + a: NotNan, + b: SignedTokenAmount, + }, + + /// A polynomial function emits tokens according to a quadratic or cubic curve (integer precision). + /// + /// # Formula + /// - `f(x) = a * x^n + b` + /// - Where `n` is the degree of the polynomial, `a` is the scaling factor, and `b` is the base amount. + /// + /// # Description + /// - Higher-degree polynomials allow for flexible emission curves. + /// - Use for growth or decay patterns that aren't linear. + /// + /// # Use Case + /// - Reward systems with diminishing returns as time progresses. + /// + /// # Example + /// - Emit rewards based on a quadratic curve: `f(x) = 2x^2 + 20`. + PolynomialInteger { + a: i64, + n: i64, + b: SignedTokenAmount, + }, + + /// A polynomial function emits tokens according to a quadratic or cubic curve (floating-point precision). + /// + /// # Formula + /// - `f(x) = a * x^n + b` + /// - Where `n` is the degree of the polynomial, `a` is the scaling factor, and `b` is the base amount. + /// + /// # Description + /// - Similar to `PolynomialInteger`, but supports fractional scaling and degrees. + /// + /// # Example + /// - Emit rewards based on a cubic curve with fractional growth: `f(x) = 0.5x^3 + 20`. + PolynomialFloat { + a: NotNan, + n: NotNan, + b: SignedTokenAmount, + }, + + /// An exponential function emits tokens based on exponential growth or decay. + /// + /// # Formula + /// - `f(x) = a * e^(b * x) + c` + /// - Where `a` is the scaling factor, `b` controls the growth/decay rate, and `c` is an offset. + /// + /// # Description + /// - Exponential growth: `b > 0`, emissions increase rapidly. + /// - Exponential decay: `b < 0`, emissions decrease rapidly. + /// - Useful for early incentivization or ecosystem maturity. + /// + /// # Use Case + /// - Reward mechanisms where early contributors get larger rewards. + /// + /// # Example + /// - Start with 100 tokens and halve emissions every interval, with a minimum of 5 tokens: `f(x) = 100 * e^(-0.693 * x) + 5`. + Exponential { + a: NotNan, + b: NotNan, + c: SignedTokenAmount, + }, + + /// A logarithmic function emits tokens based on logarithmic growth. + /// + /// # Formula + /// - `f(x) = a * log_b(x) + c` + /// - Where `a` is the scaling factor, `b` is the logarithm base, and `c` is an offset. + /// + /// # Description + /// - Growth starts quickly but slows as `x` increases. + /// - Suitable for sustainable emissions over long periods. + /// + /// # Use Case + /// - Gradual emissions tapering to balance supply and demand. + /// + /// # Example + /// - Emit rewards using a log base-2 curve: `f(x) = 20 * log_2(x) + 5`. + Logarithmic { + a: NotNan, + b: NotNan, + c: SignedTokenAmount, + }, + + /// A stepwise function emits tokens in fixed amounts for predefined intervals. + /// + /// # Description + /// - Emissions remain constant within each step. + /// - Steps define specific time intervals or milestones. + /// + /// # Use Case + /// - Adjust rewards at specific milestones. + /// + /// # Example + /// - Emit 100 tokens per block for the first 1000 blocks, then 50 tokens thereafter. + Stepwise(Vec<(u64, TokenAmount)>), +} + +impl fmt::Display for DistributionFunction { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + DistributionFunction::LinearInteger { a, b } => { + write!(f, "LinearInteger: f(x) = {} * x + {}", a, b) + } + DistributionFunction::LinearFloat { a, b } => { + write!(f, "LinearFloat: f(x) = {:.3} * x + {}", a.into_inner(), b) + } + DistributionFunction::PolynomialInteger { a, n, b } => { + write!(f, "PolynomialInteger: f(x) = {} * x^{} + {}", a, n, b) + } + DistributionFunction::PolynomialFloat { a, n, b } => { + write!( + f, + "PolynomialFloat: f(x) = {:.3} * x^{:.3} + {}", + a.into_inner(), + n.into_inner(), + b + ) + } + DistributionFunction::Exponential { a, b, c } => { + write!( + f, + "Exponential: f(x) = {:.3} * e^({:.3} * x) + {}", + a.into_inner(), + b.into_inner(), + c + ) + } + DistributionFunction::Logarithmic { a, b, c } => { + write!( + f, + "Logarithmic: f(x) = {:.3} * log_{:.3}(x) + {}", + a.into_inner(), + b.into_inner(), + c + ) + } + DistributionFunction::Stepwise(steps) => { + write!(f, "Stepwise: ")?; + for (index, (step, amount)) in steps.iter().enumerate() { + if index > 0 { + write!(f, ", ")?; + } + write!(f, "Step {} -> {}", step, amount)?; + } + Ok(()) + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs new file mode 100644 index 0000000000..da47067ff2 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/mod.rs @@ -0,0 +1,25 @@ +use crate::data_contract::associated_token::token_perpetual_distribution::v0::TokenPerpetualDistributionV0; +use bincode::{Decode, Encode}; +use derive_more::From; +use serde::{Deserialize, Serialize}; +use std::fmt; + +pub mod distribution_function; +pub mod v0; + +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, PartialOrd, From)] +#[serde(tag = "$format_version")] +pub enum TokenPerpetualDistribution { + #[serde(rename = "0")] + V0(TokenPerpetualDistributionV0), +} + +impl fmt::Display for TokenPerpetualDistribution { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TokenPerpetualDistribution::V0(v0) => { + write!(f, "{}", v0) //just pass through + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs new file mode 100644 index 0000000000..81d9bfa39e --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/v0/mod.rs @@ -0,0 +1,81 @@ +use crate::balances::credits::TokenAmount; +use crate::data_contract::associated_token::token_perpetual_distribution::distribution_function::DistributionFunction; +use crate::prelude::{BlockHeightInterval, EpochInterval, TimestampMillisInterval}; +use bincode::Encode; +use platform_serialization::de::Decode; +use serde::{Deserialize, Serialize}; +use std::fmt; + +pub type BaseTokenAmount = TokenAmount; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, PartialOrd)] +pub enum RewardDistributionType { + /// A fixed amount of tokens is emitted every n blocks + BlockFixed(BlockHeightInterval, TokenAmount), + /// A fixed amount of tokens is emitted every amount of time given + TimeFixed(TimestampMillisInterval, TokenAmount), + /// A fixed amount of tokens is emitted every amount of epochs + EpochFixed(EpochInterval, TokenAmount), + /// A variable amount of tokens is emitted every amount of time given + TimeVariable( + TimestampMillisInterval, + BaseTokenAmount, + DistributionFunction, + ), + /// A variable amount of tokens is emitted every amount of epochs + EpochVariable(EpochInterval, BaseTokenAmount, DistributionFunction), +} + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, PartialOrd)] +#[serde(rename_all = "camelCase")] +pub struct TokenPerpetualDistributionV0 { + /// The distribution type that the token will use + pub distribution_type: RewardDistributionType, + /// Is the release of the token automatic if the owner id has enough balance? + pub automatic_release: bool, +} + +impl fmt::Display for RewardDistributionType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + RewardDistributionType::BlockFixed(interval, amount) => { + write!(f, "BlockFixed: {} tokens every {} blocks", amount, interval) + } + RewardDistributionType::TimeFixed(interval, amount) => { + write!( + f, + "TimeFixed: {} tokens every {} milliseconds", + amount, interval + ) + } + RewardDistributionType::EpochFixed(interval, amount) => { + write!(f, "EpochFixed: {} tokens every {} epochs", amount, interval) + } + RewardDistributionType::TimeVariable(interval, base_amount, function) => { + write!( + f, + "TimeVariable: Base {} tokens with function {} every {} milliseconds", + base_amount, function, interval + ) + } + RewardDistributionType::EpochVariable(interval, base_amount, function) => { + write!( + f, + "EpochVariable: Base {} tokens with function {} every {} epochs", + base_amount, function, interval + ) + } + } + } +} + +impl fmt::Display for TokenPerpetualDistributionV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "TokenPerpetualDistributionV0 {{\n distribution_type: {},\n automatic_release: {}\n}}", + self.distribution_type, + self.automatic_release + ) + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs new file mode 100644 index 0000000000..8ade8f657a --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/mod.rs @@ -0,0 +1,24 @@ +use crate::data_contract::associated_token::token_pre_programmed_distribution::v0::TokenPreProgrammedDistributionV0; +use bincode::{Decode, Encode}; +use derive_more::From; +use serde::{Deserialize, Serialize}; +use std::fmt; + +pub mod v0; + +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] +#[serde(tag = "$format_version")] +pub enum TokenPreProgrammedDistribution { + #[serde(rename = "0")] + V0(TokenPreProgrammedDistributionV0), +} + +impl fmt::Display for TokenPreProgrammedDistribution { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TokenPreProgrammedDistribution::V0(v0) => { + write!(f, "{}", v0) //just pass through + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/v0/mod.rs new file mode 100644 index 0000000000..b70a4a20ee --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_pre_programmed_distribution/v0/mod.rs @@ -0,0 +1,28 @@ +use crate::balances::credits::TokenAmount; +use crate::prelude::TimestampMillis; +use bincode::Encode; +use platform_serialization::de::Decode; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; +use std::fmt; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct TokenPreProgrammedDistributionV0 { + pub distributions: BTreeMap>, +} + +/// Implementing `Display` for `TokenPreProgrammedDistributionV0` +impl fmt::Display for TokenPreProgrammedDistributionV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "TokenPreProgrammedDistributionV0 {{")?; + for (timestamp, distributions) in &self.distributions { + writeln!(f, " Timestamp: {}", timestamp)?; + for (identity, amount) in distributions { + writeln!(f, " Identity: {}, Amount: {}", identity, amount)?; + } + } + write!(f, "}}") + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs index 105580133b..6bfa4c73f1 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs @@ -11,6 +11,7 @@ use derive_more::From; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; +use std::fmt; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, From)] pub enum ChangeControlRules { @@ -125,3 +126,13 @@ impl ChangeControlRules { } } } + +impl fmt::Display for ChangeControlRules { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ChangeControlRules::V0(v0) => { + write!(f, "{}", v0) //just pass through + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs index f5f4254a2a..d413470023 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs @@ -6,6 +6,7 @@ use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; +use std::fmt; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] pub struct ChangeControlRulesV0 { @@ -158,3 +159,23 @@ impl ChangeControlRulesV0 { true } } + +impl fmt::Display for ChangeControlRulesV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "ChangeControlRulesV0 {{\n \ + authorized_to_make_change: {},\n \ + admin_action_takers: {},\n \ + changing_authorized_action_takers_to_no_one_allowed: {},\n \ + changing_admin_action_takers_to_no_one_allowed: {},\n \ + self_changing_admin_action_takers_allowed: {}\n\ + }}", + self.authorized_to_make_change, + self.admin_action_takers, + self.changing_authorized_action_takers_to_no_one_allowed, + self.changing_admin_action_takers_to_no_one_allowed, + self.self_changing_admin_action_takers_allowed + ) + } +} diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 4225704da9..9c5d4c65c1 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -79,11 +79,17 @@ pub mod prelude { #[cfg(feature = "validation")] pub use crate::validation::ConsensusValidationResult; + pub type EpochInterval = u16; + pub type BlockHeight = u64; + pub type BlockHeightInterval = u64; + pub type CoreBlockHeight = u32; pub type TimestampMillis = u64; + pub type TimestampMillisInterval = u64; + pub type StartAtIncluded = bool; pub type TimestampIncluded = bool; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs index 1973836f53..3b3694a442 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs @@ -1,6 +1,7 @@ use platform_value::Identifier; use crate::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use crate::ProtocolError; use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; @@ -81,13 +82,13 @@ impl TokenMintTransitionV0Methods for TokenMintTransitionV0 { token_configuration: &TokenConfiguration, ) -> Result { match self.issued_to_identity_id() { - None => { - token_configuration - .new_tokens_destination_identity() - .ok_or(ProtocolError::Token( - TokenError::TokenNoMintingRecipient.into(), - )) - } + None => token_configuration + .distribution_rules() + .new_tokens_destination_identity() + .copied() + .ok_or(ProtocolError::Token( + TokenError::TokenNoMintingRecipient.into(), + )), Some(recipient) => Ok(recipient), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 0591eb4079..255c968c36 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -9,6 +9,7 @@ use crate::block::block_info::BlockInfo; use crate::data_contract::accessors::v0::DataContractV0Getters; use crate::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use crate::data_contract::DataContract; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::Document; @@ -344,7 +345,7 @@ impl TokenTransitionV0Methods for TokenTransition { } TokenTransition::Mint(mint) => { let recipient = match mint.issued_to_identity_id() { - None => token_configuration.new_tokens_destination_identity().ok_or(ProtocolError::NotSupported("either the mint destination must be set or the contract must have a destination set for new tokens".to_string()))?, + None => token_configuration.distribution_rules().new_tokens_destination_identity().copied().ok_or(ProtocolError::NotSupported("either the mint destination must be set or the contract must have a destination set for new tokens".to_string()))?, Some(recipient) => recipient, }; TokenEvent::Mint(mint.amount(), recipient, mint.public_note().cloned()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_burn_transition_action/state_v0/mod.rs index ae67c64bdf..cc45b90a41 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_burn_transition_action/state_v0/mod.rs @@ -1,18 +1,15 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::IdentityDoesNotHaveEnoughTokenBalanceError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; -use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_destroy_frozen_funds_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_destroy_frozen_funds_transition_action/state_v0/mod.rs index b37bfab734..a2c4057c8e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_destroy_frozen_funds_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_destroy_frozen_funds_transition_action/state_v0/mod.rs @@ -1,11 +1,10 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{IdentityTokenAccountNotFrozenError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::IdentityTokenAccountNotFrozenError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_emergency_action_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_emergency_action_transition_action/state_v0/mod.rs index 928e9f092b..66e99de1c2 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_emergency_action_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_emergency_action_transition_action/state_v0/mod.rs @@ -1,11 +1,7 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::UnauthorizedTokenActionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::{TokenEmergencyActionTransitionAction, TokenEmergencyActionTransitionActionAccessorsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_freeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_freeze_transition_action/state_v0/mod.rs index 69333fa12d..14701a7171 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_freeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_freeze_transition_action/state_v0/mod.rs @@ -1,11 +1,7 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::UnauthorizedTokenActionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_mint_transition_action/state_v0/mod.rs index 1edce2ea32..d30cb0d377 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_mint_transition_action/state_v0/mod.rs @@ -2,19 +2,16 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::identity::RecipientIdentityDoesNotExistError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{TokenMintPastMaxSupplyError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::TokenMintPastMaxSupplyError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::error::drive::DriveError; use drive::query::TransactionArg; -use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_unfreeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_unfreeze_transition_action/state_v0/mod.rs index d99fab0765..79d39f1490 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_unfreeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token/token_unfreeze_transition_action/state_v0/mod.rs @@ -1,11 +1,10 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{IdentityTokenAccountNotFrozenError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::IdentityTokenAccountNotFrozenError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::group::action_taker::{ActionGoal, ActionTaker}; use dpp::prelude::Identifier; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index bd1cf8d0f9..7b38ca9b32 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -10202,6 +10202,7 @@ mod tests { use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; use dpp::data_contract::associated_token::token_configuration_convention::v0::TokenConfigurationConventionV0; use dpp::data_contract::associated_token::token_configuration_convention::v0::TokenConfigurationLocalizationsV0; + use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Setters; use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use dpp::data_contract::change_control_rules::v0::ChangeControlRulesV0; use dpp::data_contract::change_control_rules::ChangeControlRules; @@ -10686,7 +10687,9 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); }), None, platform_version, @@ -10784,7 +10787,9 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); }), None, platform_version, @@ -10879,7 +10884,9 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); }), None, platform_version, @@ -10967,8 +10974,11 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() .set_new_tokens_destination_identity(Some(identity.id())); }), None, @@ -11067,8 +11077,11 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() .set_new_tokens_destination_identity(Some(identity.id())); }), None, @@ -11164,8 +11177,11 @@ mod tests { &mut platform, identity.id(), Some(|token_configuration: &mut TokenConfiguration| { - token_configuration.set_minting_allow_choosing_destination(false); token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); + token_configuration + .distribution_rules_mut() .set_new_tokens_destination_identity(Some(identity.id())); }), None, @@ -15008,8 +15024,6 @@ mod tests { let (identity, signer, key) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - let identity_2_id = Identifier::random_with_rng(&mut rng); - let (contract, token_id) = create_token_contract_with_owner_identity( &mut platform, identity.id(), @@ -15103,8 +15117,6 @@ mod tests { let (identity, signer, key) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - let identity_2_id = Identifier::random_with_rng(&mut rng); - let (contract, token_id) = create_token_contract_with_owner_identity( &mut platform, identity.id(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index 2a111aa4db..a4abb0b904 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -1177,8 +1177,10 @@ mod tests { mod token_tests { use super::*; use dpp::data_contract::accessors::v1::DataContractV1Setters; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Setters; #[test] fn test_data_contract_update_can_not_add_new_token() { let mut platform = TestPlatformBuilder::new() @@ -1358,7 +1360,7 @@ mod tests { platform_version, None, ) - .expect("expect to create data contract update transition"); + .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition .serialize_to_bytes() @@ -1380,7 +1382,9 @@ mod tests { .expect("expected to process state transition"); if let [StateTransitionExecutionResult::PaidConsensusError( - ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError(error)), + ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError( + error, + )), _, )] = processing_result.execution_results().as_slice() { @@ -1453,7 +1457,9 @@ mod tests { if let Some(TokenConfiguration::V0(config)) = updated_data_contract.tokens_mut().unwrap().get_mut(&0) { - config.minting_allow_choosing_destination = false; //originally true + config + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); //originally true } let data_contract_update_transition = @@ -1467,7 +1473,7 @@ mod tests { platform_version, None, ) - .expect("expect to create data contract update transition"); + .expect("expect to create data contract update transition"); let data_contract_update_serialized_transition = data_contract_update_transition .serialize_to_bytes() @@ -1489,7 +1495,9 @@ mod tests { .expect("expected to process state transition"); if let [StateTransitionExecutionResult::PaidConsensusError( - ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError(error)), + ConsensusError::StateError(StateError::DataContractUpdateActionNotAllowedError( + error, + )), _, )] = processing_result.execution_results().as_slice() { diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index af9dddbee2..5acb898ccc 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -5,7 +5,10 @@ mod tests { use dpp::dash_to_duffs; use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; - use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::{ + TokenConfigurationV0Getters, TokenConfigurationV0Setters, + }; + use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Setters; use dpp::data_contract::DataContract; use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::Identity; @@ -70,7 +73,9 @@ mod tests { let token_configuration = contract .token_configuration_mut(0) .expect("expected to get token configuration"); - token_configuration.set_minting_allow_choosing_destination(true); + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(true); contract.set_owner_id(identity1.id()); let new_id = DataContract::generate_data_contract_id_v0(identity1.id(), 1); contract.set_id(new_id); @@ -218,7 +223,9 @@ mod tests { let token_configuration = contract .token_configuration_mut(0) .expect("expected to get token configuration"); - token_configuration.set_minting_allow_choosing_destination(true); + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(true); contract.set_owner_id(identity1.id()); let new_id = DataContract::generate_data_contract_id_v0(identity1.id(), 1); contract.set_id(new_id); diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index 29c49b6750..826ccfe97a 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -18,6 +18,7 @@ use crate::util::object_size_info::DriveKeyInfo; use crate::util::object_size_info::PathKeyElementInfo::PathKeyElement; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::version::PlatformVersion; use dpp::ProtocolError; @@ -219,7 +220,9 @@ impl Drive { if token_config.base_supply() > 0 { // We have a base supply that needs to be distributed on contract creation let destination_identity_id = token_config + .distribution_rules() .new_tokens_destination_identity() + .copied() .unwrap_or(contract.owner_id()); let token_balance_path = token_balances_path_vec(token_id_bytes); diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs index 6a466b9d94..821d7c74c6 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs @@ -14,8 +14,6 @@ use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; use grovedb::EstimatedSumTrees::{AllBigSumTrees, AllSumTrees, NoSumTrees}; use std::collections::HashMap; -pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u32 = 256; - impl Drive { /// Adds estimation costs for token balances in Drive for version 0. /// diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs index 5fba01b5e0..ee34e6dd99 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs @@ -12,6 +12,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Getters; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use platform_version::version::PlatformVersion; @@ -117,6 +118,7 @@ impl TokenMintTransitionActionV0 { if !base_action .token_configuration()? + .distribution_rules() .minting_allow_choosing_destination() && issued_to_identity_id.is_some() { @@ -148,7 +150,10 @@ impl TokenMintTransitionActionV0 { .tokens() .get(&position) .and_then(|token_configuration| { - token_configuration.new_tokens_destination_identity() + token_configuration + .distribution_rules() + .new_tokens_destination_identity() + .copied() }) }) { Some(identity_balance_holder_id) => identity_balance_holder_id, @@ -290,6 +295,7 @@ impl TokenMintTransitionActionV0 { if !base_action .token_configuration()? + .distribution_rules() .minting_allow_choosing_destination() && issued_to_identity_id.is_some() { @@ -321,7 +327,10 @@ impl TokenMintTransitionActionV0 { .tokens() .get(&base.token_contract_position()) .and_then(|token_configuration| { - token_configuration.new_tokens_destination_identity() + token_configuration + .distribution_rules() + .new_tokens_destination_identity() + .copied() }) }) { Some(identity_balance_holder_id) => identity_balance_holder_id, From 153539537f069774a78001b70fea66942d9f6fd8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 27 Jan 2025 15:48:23 +0700 Subject: [PATCH 4/5] fix --- .../token_configuration/v0/mod.rs | 31 +++++++++++++++++++ .../tests/strategy_tests/token_tests.rs | 4 +-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index eb6c23f6e6..570b2edde3 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -36,6 +36,7 @@ pub struct TokenConfigurationV0 { #[serde(default = "default_change_control_rules")] pub max_supply_change_rules: ChangeControlRules, /// The distribution rules for the token + #[serde(default = "default_token_distribution_rules")] pub distribution_rules: TokenDistributionRules, #[serde(default = "default_contract_owner_change_control_rules")] pub manual_minting_rules: ChangeControlRules, @@ -65,6 +66,36 @@ fn default_starts_as_paused() -> bool { false } +fn default_token_distribution_rules() -> TokenDistributionRules { + TokenDistributionRules::V0(TokenDistributionRulesV0 { + perpetual_distribution: None, + perpetual_distribution_rules: ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + }), + pre_programmed_distribution: None, + new_tokens_destination_identity: None, + new_tokens_destination_identity_rules: ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + }), + minting_allow_choosing_destination: false, + minting_allow_choosing_destination_rules: ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + admin_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_admin_action_takers_to_no_one_allowed: false, + self_changing_admin_action_takers_allowed: false, + }), + }) +} + fn default_change_control_rules() -> ChangeControlRules { ChangeControlRules::V0(ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index 5acb898ccc..d2a2607c92 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -5,9 +5,7 @@ mod tests { use dpp::dash_to_duffs; use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; - use dpp::data_contract::associated_token::token_configuration::accessors::v0::{ - TokenConfigurationV0Getters, TokenConfigurationV0Setters, - }; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contract::associated_token::token_distribution_rules::accessors::v0::TokenDistributionRulesV0Setters; use dpp::data_contract::DataContract; use dpp::identity::accessors::IdentityGettersV0; From b72462e5caa4824dd81268131710ee8f38476c7a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 27 Jan 2025 16:02:57 +0700 Subject: [PATCH 5/5] fix --- .../associated_token/token_configuration/v0/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 570b2edde3..0c8ccb6dc3 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -85,7 +85,7 @@ fn default_token_distribution_rules() -> TokenDistributionRules { changing_admin_action_takers_to_no_one_allowed: false, self_changing_admin_action_takers_allowed: false, }), - minting_allow_choosing_destination: false, + minting_allow_choosing_destination: true, minting_allow_choosing_destination_rules: ChangeControlRules::V0(ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, admin_action_takers: AuthorizedActionTakers::NoOne,