From af2666ba0263e354dff1f136bd3614c4f40fef12 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 19 Mar 2025 14:20:18 +0700 Subject: [PATCH 1/4] fix: mint to self if allowed and no destination id set --- .../v0/transformer.rs | 48 +------------------ 1 file changed, 2 insertions(+), 46 deletions(-) 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 ee34e6dd99e..695a7928c06 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 @@ -157,29 +157,7 @@ impl TokenMintTransitionActionV0 { }) }) { Some(identity_balance_holder_id) => identity_balance_holder_id, - None => { - let bump_action = - BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( - &base_action, - owner_id, - 0, - ); - let batched_action = - BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); - - return Ok(( - ConsensusValidationResult::new_with_data_and_errors( - batched_action.into(), - vec![BasicError::DestinationIdentityForTokenMintingNotSetError( - DestinationIdentityForTokenMintingNotSetError::new( - base_action.token_id(), - ), - ) - .into()], - ), - fee_result, - )); - } + None => owner_id, }; Ok(( @@ -334,29 +312,7 @@ impl TokenMintTransitionActionV0 { }) }) { Some(identity_balance_holder_id) => identity_balance_holder_id, - None => { - let bump_action = - BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( - &base_action, - owner_id, - 0, - ); - let batched_action = - BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); - - return Ok(( - ConsensusValidationResult::new_with_data_and_errors( - batched_action.into(), - vec![BasicError::DestinationIdentityForTokenMintingNotSetError( - DestinationIdentityForTokenMintingNotSetError::new( - base_action.token_id(), - ), - ) - .into()], - ), - fee_result, - )); - } + None => owner_id, }; Ok(( From 68265731d09c156adecb4dabed1cc4b377f453a9 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 19 Mar 2025 15:22:59 +0700 Subject: [PATCH 2/4] fix: remove useless error --- .../src/errors/consensus/basic/basic_error.rs | 5 +- ...dentity_for_token_minting_not_set_error.rs | 33 ---- .../src/errors/consensus/basic/token/mod.rs | 2 - packages/rs-dpp/src/errors/consensus/codes.rs | 11 +- .../batch/tests/token/mod.rs | 168 ------------------ .../v0/transformer.rs | 6 +- .../src/errors/consensus/consensus_error.rs | 5 +- 7 files changed, 12 insertions(+), 218 deletions(-) delete mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index 33eedfb1a47..ce48a7aaa29 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -77,7 +77,7 @@ use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use crate::consensus::basic::overflow_error::OverflowError; use crate::consensus::basic::token::{ ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, - DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenAmountError, + InvalidActionIdError, InvalidTokenAmountError, InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError, InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError, }; @@ -478,9 +478,6 @@ pub enum BasicError { #[error(transparent)] InvalidActionIdError(InvalidActionIdError), - #[error(transparent)] - DestinationIdentityForTokenMintingNotSetError(DestinationIdentityForTokenMintingNotSetError), - #[error(transparent)] ChoosingTokenMintRecipientNotAllowedError(ChoosingTokenMintRecipientNotAllowedError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs deleted file mode 100644 index 7136a46e66f..00000000000 --- a/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::consensus::basic::BasicError; -use crate::consensus::ConsensusError; -use crate::ProtocolError; -use bincode::{Decode, Encode}; -use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; -use platform_value::Identifier; -use thiserror::Error; - -#[derive( - Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, -)] -#[error("Destination identity for minting not set for token {}", token_id)] -#[platform_serialize(unversioned)] -pub struct DestinationIdentityForTokenMintingNotSetError { - token_id: Identifier, -} - -impl DestinationIdentityForTokenMintingNotSetError { - pub fn new(token_id: Identifier) -> Self { - Self { token_id } - } - pub fn token_id(&self) -> Identifier { - self.token_id - } -} - -impl From for ConsensusError { - fn from(err: DestinationIdentityForTokenMintingNotSetError) -> Self { - Self::BasicError(BasicError::DestinationIdentityForTokenMintingNotSetError( - err, - )) - } -} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs index 79ad589ee41..7343f0b590e 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs @@ -1,6 +1,5 @@ mod choosing_token_mint_recipient_not_allowed_error; mod contract_has_no_tokens_error; -mod destination_identity_for_token_minting_not_set_error; mod invalid_action_id_error; mod invalid_token_amount_error; mod invalid_token_config_update_no_change_error; @@ -12,7 +11,6 @@ mod token_transfer_to_ourselves_error; pub use choosing_token_mint_recipient_not_allowed_error::*; pub use contract_has_no_tokens_error::*; -pub use destination_identity_for_token_minting_not_set_error::*; pub use invalid_action_id_error::*; pub use invalid_token_amount_error::*; pub use invalid_token_config_update_no_change_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index e768aee5803..1d688e7caf4 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -143,12 +143,11 @@ impl ErrorWithCode for BasicError { Self::InvalidTokenPositionError(_) => 10451, Self::InvalidActionIdError(_) => 10452, Self::ContractHasNoTokensError(_) => 10453, - Self::DestinationIdentityForTokenMintingNotSetError(_) => 10454, - Self::ChoosingTokenMintRecipientNotAllowedError(_) => 10455, - Self::TokenTransferToOurselfError(_) => 10456, - Self::InvalidTokenConfigUpdateNoChangeError(_) => 10457, - Self::InvalidTokenAmountError(_) => 10458, - Self::InvalidTokenNoteTooBigError(_) => 10459, + Self::ChoosingTokenMintRecipientNotAllowedError(_) => 10454, + Self::TokenTransferToOurselfError(_) => 10455, + Self::InvalidTokenConfigUpdateNoChangeError(_) => 10456, + Self::InvalidTokenAmountError(_) => 10457, + Self::InvalidTokenNoteTooBigError(_) => 10458, // Identity Errors: 10500-10599 Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs index e921df6894e..6ba0315c6b6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs @@ -402,88 +402,6 @@ mod token_tests { .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } - - #[test] - fn test_token_mint_by_owner_no_destination_causes_error() { - let platform_version = PlatformVersion::latest(); - let mut platform = TestPlatformBuilder::new() - .with_latest_protocol_version() - .build_with_mock_rpc() - .set_genesis_state(); - - let mut rng = StdRng::seed_from_u64(49853); - - let platform_state = platform.state.load(); - - let (identity, signer, key) = - setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - - let (contract, token_id) = create_token_contract_with_owner_identity( - &mut platform, - identity.id(), - None::, - None, - None, - platform_version, - ); - - let documents_batch_create_transition = BatchTransition::new_token_mint_transition( - token_id, - identity.id(), - contract.id(), - 0, - 1337, - None, - None, - None, - &key, - 2, - 0, - &signer, - platform_version, - None, - None, - None, - ) - .expect("expect to create documents batch transition"); - - let documents_batch_create_serialized_transition = - documents_batch_create_transition - .serialize_to_bytes() - .expect("expected documents batch serialized state transition"); - - let transaction = platform.drive.grove.start_transaction(); - - let processing_result = platform - .platform - .process_raw_state_transitions( - &vec![documents_batch_create_serialized_transition.clone()], - &platform_state, - &BlockInfo::default(), - &transaction, - platform_version, - false, - None, - ) - .expect("expected to process state transition"); - - assert_matches!( - processing_result.execution_results().as_slice(), - [StateTransitionExecutionResult::PaidConsensusError( - ConsensusError::BasicError( - BasicError::DestinationIdentityForTokenMintingNotSetError(_) - ), - _ - )] - ); - - platform - .drive - .grove - .commit_transaction(transaction) - .unwrap() - .expect("expected to commit transaction"); - } } mod token_mint_tests_no_recipient_minting { @@ -685,92 +603,6 @@ mod token_tests { .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } - - #[test] - fn test_token_mint_by_owned_id_no_destination_causes_error() { - let platform_version = PlatformVersion::latest(); - let mut platform = TestPlatformBuilder::new() - .with_latest_protocol_version() - .build_with_mock_rpc() - .set_genesis_state(); - - let mut rng = StdRng::seed_from_u64(49853); - - let platform_state = platform.state.load(); - - let (identity, signer, key) = - setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - - let (contract, token_id) = create_token_contract_with_owner_identity( - &mut platform, - identity.id(), - Some(|token_configuration: &mut TokenConfiguration| { - token_configuration - .distribution_rules_mut() - .set_minting_allow_choosing_destination(false); - }), - None, - None, - platform_version, - ); - - let documents_batch_create_transition = BatchTransition::new_token_mint_transition( - token_id, - identity.id(), - contract.id(), - 0, - 1337, - None, - None, - None, - &key, - 2, - 0, - &signer, - platform_version, - None, - None, - None, - ) - .expect("expect to create documents batch transition"); - - let documents_batch_create_serialized_transition = - documents_batch_create_transition - .serialize_to_bytes() - .expect("expected documents batch serialized state transition"); - - let transaction = platform.drive.grove.start_transaction(); - - let processing_result = platform - .platform - .process_raw_state_transitions( - &vec![documents_batch_create_serialized_transition.clone()], - &platform_state, - &BlockInfo::default(), - &transaction, - platform_version, - false, - None, - ) - .expect("expected to process state transition"); - - assert_matches!( - processing_result.execution_results().as_slice(), - [StateTransitionExecutionResult::PaidConsensusError( - ConsensusError::BasicError( - BasicError::DestinationIdentityForTokenMintingNotSetError(_) - ), - _ - )] - ); - - platform - .drive - .grove - .commit_transaction(transaction) - .unwrap() - .expect("expected to commit transaction"); - } } mod token_mint_tests_contract_has_recipient { 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 695a7928c06..9f63e40e9d1 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 @@ -2,7 +2,7 @@ use std::sync::Arc; use grovedb::TransactionArg; use dpp::block::block_info::BlockInfo; use dpp::consensus::basic::BasicError; -use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, DestinationIdentityForTokenMintingNotSetError}; +use dpp::consensus::basic::token::ChoosingTokenMintRecipientNotAllowedError; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_mint_transition::v0::TokenMintTransitionV0; use dpp::ProtocolError; @@ -116,6 +116,7 @@ impl TokenMintTransitionActionV0 { } }; + // First, validate that choosing recipient is allowed if a recipient is set if !base_action .token_configuration()? .distribution_rules() @@ -143,6 +144,7 @@ impl TokenMintTransitionActionV0 { )); } + // If no recipient is set, use the default recipient. If no default recipient, use the minter ID let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { base_action .data_contract_fetch_info_ref() @@ -271,6 +273,7 @@ impl TokenMintTransitionActionV0 { } }; + // First, validate that choosing recipient is allowed if a recipient is set if !base_action .token_configuration()? .distribution_rules() @@ -298,6 +301,7 @@ impl TokenMintTransitionActionV0 { )); } + // If no recipient is set, use the default recipient. If no default recipient, use the minter ID let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { base_action .data_contract_fetch_info_ref() diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 1a77988f810..ef0c74aa08b 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -66,7 +66,7 @@ use dpp::consensus::basic::document::{ContestedDocumentsTemporarilyNotAllowedErr use dpp::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use dpp::consensus::basic::identity::{DataContractBoundsNotPresentError, DisablingKeyIdAlsoBeingAddedInSameTransitionError, InvalidIdentityCreditWithdrawalTransitionAmountError, InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError}; use dpp::consensus::basic::overflow_error::OverflowError; -use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidTokenAmountError, InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError, InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError}; +use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, InvalidActionIdError, InvalidTokenAmountError, InvalidTokenConfigUpdateNoChangeError, InvalidTokenIdError, InvalidTokenNoteTooBigError, InvalidTokenPositionError, MissingDefaultLocalizationError, TokenTransferToOurselfError}; use dpp::consensus::state::data_contract::data_contract_update_action_not_allowed_error::DataContractUpdateActionNotAllowedError; use dpp::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError; use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; @@ -677,9 +677,6 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue { BasicError::TokenTransferToOurselfError(e) => { generic_consensus_error!(TokenTransferToOurselfError, e).into() } - BasicError::DestinationIdentityForTokenMintingNotSetError(e) => { - generic_consensus_error!(DestinationIdentityForTokenMintingNotSetError, e).into() - } BasicError::ChoosingTokenMintRecipientNotAllowedError(e) => { generic_consensus_error!(ChoosingTokenMintRecipientNotAllowedError, e).into() } From fb680d84eb561a33e8d3cc673728185ad135d4ab Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 19 Mar 2025 15:27:44 +0700 Subject: [PATCH 3/4] docs: update comment --- .../token_mint_transition_action/v0/transformer.rs | 2 ++ 1 file changed, 2 insertions(+) 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 9f63e40e9d1..ab3533960cd 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 @@ -145,6 +145,7 @@ impl TokenMintTransitionActionV0 { } // If no recipient is set, use the default recipient. If no default recipient, use the minter ID + // We already validated that the minter is allowed to mint tokens let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { base_action .data_contract_fetch_info_ref() @@ -302,6 +303,7 @@ impl TokenMintTransitionActionV0 { } // If no recipient is set, use the default recipient. If no default recipient, use the minter ID + // We already validated that the minter is allowed to mint tokens let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { base_action .data_contract_fetch_info_ref() From c4f2d47256ca41ce01a3be46bc80edfa2a143cab Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 19 Mar 2025 15:51:25 +0700 Subject: [PATCH 4/4] feat: replace old tests --- .../batch/tests/token/mod.rs | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs index 6ba0315c6b6..8933957865c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mod.rs @@ -402,6 +402,99 @@ mod token_tests { .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } + + #[test] + fn test_token_mint_by_owner_no_destination_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + None, + platform_version, + ); + + let base_supply = contract.tokens().get(&0).unwrap().base_supply(); + + let documents_batch_create_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!( + token_balance.expect("expected token balance") - base_supply, + 1337 + ); + } } mod token_mint_tests_no_recipient_minting { @@ -603,6 +696,103 @@ mod token_tests { .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } + + #[test] + fn test_token_mint_by_owned_id_no_destination_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration + .distribution_rules_mut() + .set_minting_allow_choosing_destination(false); + }), + None, + None, + platform_version, + ); + + let base_supply = contract.tokens().get(&0).unwrap().base_supply(); + + let documents_batch_create_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!( + token_balance.expect("expected token balance") - base_supply, + 1337 + ); + } } mod token_mint_tests_contract_has_recipient {