diff --git a/examples/multi-token/mt/src/lib.rs b/examples/multi-token/mt/src/lib.rs index fd4ae3c3a..f4e7610d7 100644 --- a/examples/multi-token/mt/src/lib.rs +++ b/examples/multi-token/mt/src/lib.rs @@ -48,7 +48,6 @@ impl ExampleMTContract { #[init] pub fn new(owner_id: AccountId, metadata: MtContractMetadata) -> Self { - require!(!env::state_exists(), "Already initialized"); metadata.assert_valid(); Self { diff --git a/near-contract-standards/src/multi_token/approval/approval_impl.rs b/near-contract-standards/src/multi_token/approval/approval_impl.rs index 2a7f85d59..4193edb73 100644 --- a/near-contract-standards/src/multi_token/approval/approval_impl.rs +++ b/near-contract-standards/src/multi_token/approval/approval_impl.rs @@ -153,20 +153,14 @@ impl MultiTokenApproval for MultiToken { for (idx, (token_id, amount)) in token_ids.iter().zip(amounts).enumerate() { let by_owner = by_token.get(token_id).unwrap_or_default(); - let grantee_to_approval = match by_owner.get(&owner_id) { - Some(grantee_to_approval) => grantee_to_approval, - None => return false, + let approval = match by_owner + .get(&owner_id) + .and_then(|grantee_to_approval| grantee_to_approval.get(&approved_account_id)) + { + Some(approval) if approval.amount.eq(&amount.into()) => approval, + _ => return false, }; - let approval = match grantee_to_approval.get(&approved_account_id) { - Some(approval) => approval, - None => return false, - }; - - if !approval.amount.eq(&amount.into()) { - return false; - } - if let Some(given_approval) = approval_ids.get(idx) { if !approval.approval_id.eq(given_approval) { return false; diff --git a/near-contract-standards/src/multi_token/core/core_impl.rs b/near-contract-standards/src/multi_token/core/core_impl.rs index 72a7fdebb..15f6282f6 100644 --- a/near-contract-standards/src/multi_token/core/core_impl.rs +++ b/near-contract-standards/src/multi_token/core/core_impl.rs @@ -1,5 +1,5 @@ use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; -use near_sdk::collections::{LookupMap, TreeMap, UnorderedMap, UnorderedSet}; +use near_sdk::collections::{LookupMap, UnorderedMap, UnorderedSet}; use near_sdk::json_types::U128; use near_sdk::{ assert_one_yocto, env, log, require, AccountId, Balance, BorshStorageKey, CryptoHash, Gas, @@ -49,7 +49,7 @@ pub struct MultiToken { pub extra_storage_in_bytes_per_emission: StorageUsage, /// Owner of each token - pub owner_by_id: TreeMap, + pub owner_by_id: UnorderedMap, /// Total supply for each token pub total_supply: LookupMap, @@ -124,7 +124,7 @@ impl MultiToken { let mut this = Self { owner_id, extra_storage_in_bytes_per_emission: 0, - owner_by_id: TreeMap::new(owner_by_id_prefix), + owner_by_id: UnorderedMap::new(owner_by_id_prefix), total_supply: LookupMap::new(StorageKey::TotalSupply { supply: 0 }), token_metadata_by_id: token_metadata_prefix.map(LookupMap::new), tokens_per_owner: enumeration_prefix.map(LookupMap::new), diff --git a/near-contract-standards/src/multi_token/enumeration/enumeration_impl.rs b/near-contract-standards/src/multi_token/enumeration/enumeration_impl.rs index 9ec7e1245..f9773ee7b 100644 --- a/near-contract-standards/src/multi_token/enumeration/enumeration_impl.rs +++ b/near-contract-standards/src/multi_token/enumeration/enumeration_impl.rs @@ -24,7 +24,7 @@ impl MultiTokenEnumeration for MultiToken { self.owner_by_id.len() as u128 >= start_index, "Out of bounds, please use a smaller from_index." ); - let limit = limit.map(|v| v as usize).unwrap_or(usize::MAX); + let limit = limit.unwrap_or(u64::MAX); require!(limit != 0, "Limit cannot be 0"); self.owner_by_id diff --git a/near-contract-standards/src/multi_token/token.rs b/near-contract-standards/src/multi_token/token.rs index 46b80ae26..c10569b30 100644 --- a/near-contract-standards/src/multi_token/token.rs +++ b/near-contract-standards/src/multi_token/token.rs @@ -18,9 +18,16 @@ pub struct Approval { // How Approvals are stored in the contract pub type ApprovalContainer = LookupMap>>; -// Represents a temporary record of an Approval -// that was removed from the ApprovalContainer but may be restored in case of rollback in XCC. -// Values are (owner_id, approval_id, amount) +// Represents a record of an Approval that has been temporarily added or removed +// from the ApprovalContainer during cross-contract calls (XCC). +// This data is stored to facilitate possible rollback scenarios where the +// approval needs to be restored. +// +// The tuple contains the following elements: +// - `AccountId`: The Account ID of the owner who initially granted the approval. +// - `Approval`: A struct containing: +// - `amount`: The number of tokens that were initially approved for transfer. +// - `approval_id`: A unique identifier assigned to this specific approval. pub type ClearedApproval = (AccountId, Approval); /// Info on individual token