difftreelog
fix correct gas metering
in: master
1 file changed
pallets/nft/src/lib.rsdiffbeforeafterboth34use frame_system::{self as system, ensure_signed, ensure_root};34use frame_system::{self as system, ensure_signed, ensure_root};35use sp_core::H160;35use sp_core::H160;36use sp_std::vec;36use sp_std::vec;37use sp_runtime::sp_std::prelude::Vec;37use sp_runtime::{DispatchError, sp_std::prelude::Vec};38use core::ops::{Deref, DerefMut};38use core::ops::{Deref, DerefMut};39use nft_data_structs::{39use nft_data_structs::{40 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,40 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,202 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {202 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {203 self.recorder.log_sub(log)203 self.recorder.log_sub(log)204 }204 }205 #[allow(dead_code)]205 fn consume_gas(&self, gas: u64) -> DispatchResult {206 fn consume_gas(&self, gas: u64) -> DispatchResult {206 self.recorder.consume_gas_sub(gas)207 self.recorder.consume_gas_sub(gas)207 }208 }209 fn consume_sload(&self) -> DispatchResult {210 self.recorder.consume_sload_sub()211 }212 fn consume_sstore(&self) -> DispatchResult {213 self.recorder.consume_sstore_sub()214 }208 pub fn submit_logs(self) -> DispatchResult {215 pub fn submit_logs(self) -> DispatchResult {209 self.recorder.submit_logs()216 self.recorder.submit_logs()210 }217 }1276 item_id: TokenId,1283 item_id: TokenId,1277 value: u128,1284 value: u128,1278 ) -> DispatchResult {1285 ) -> DispatchResult {1279 target_collection.consume_gas(2000000)?;1280 // Limits check1286 // Limits check1281 Self::is_correct_transfer(target_collection, recipient)?;1287 Self::is_correct_transfer(target_collection, recipient)?;128212881283 // Transfer permissions check1289 // Transfer permissions check1284 ensure!(1290 ensure!(1285 Self::is_item_owner(sender, target_collection, item_id)1291 Self::is_item_owner(sender, target_collection, item_id)?1286 || Self::is_owner_or_admin_permissions(target_collection, sender),1292 || Self::is_owner_or_admin_permissions(target_collection, sender)?,1287 Error::<T>::NoPermission1293 Error::<T>::NoPermission1288 );1294 );128912951330 item_id: TokenId,1336 item_id: TokenId,1331 amount: u128,1337 amount: u128,1332 ) -> DispatchResult {1338 ) -> DispatchResult {1333 collection.consume_gas(2000000)?;1334 Self::token_exists(collection, item_id)?;1339 Self::token_exists(collection, item_id)?;133513401336 // Transfer permissions check1341 // Transfer permissions check1337 let bypasses_limits = collection.limits.owner_can_transfer1342 let bypasses_limits = collection.limits.owner_can_transfer1338 && Self::is_owner_or_admin_permissions(collection, sender);1343 && Self::is_owner_or_admin_permissions(collection, sender)?;133913441340 let allowance_limit = if bypasses_limits {1345 let allowance_limit = if bypasses_limits {1341 None1346 None1342 } else if let Some(amount) = Self::owned_amount(sender, collection, item_id) {1347 } else if let Some(amount) = Self::owned_amount(sender, collection, item_id)? {1343 Some(amount)1348 Some(amount)1344 } else {1349 } else {1345 fail!(Error::<T>::NoPermission);1350 fail!(Error::<T>::NoPermission);1350 Self::check_white_list(collection, spender)?;1355 Self::check_white_list(collection, spender)?;1351 }1356 }135213571358 collection.consume_sload()?;1353 let allowance: u128 = amount1359 let allowance: u128 = amount1354 .checked_add(<Allowances<T>>::get(1360 .checked_add(<Allowances<T>>::get(1355 collection.id,1361 collection.id,1359 if let Some(limit) = allowance_limit {1365 if let Some(limit) = allowance_limit {1360 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1366 ensure!(limit >= allowance, Error::<T>::TokenValueTooLow);1361 }1367 }1368 collection.consume_sstore()?;1362 <Allowances<T>>::insert(1369 <Allowances<T>>::insert(1363 collection.id,1370 collection.id,1364 (item_id, sender.as_sub(), spender.as_sub()),1371 (item_id, sender.as_sub(), spender.as_sub()),1401 item_id: TokenId,1408 item_id: TokenId,1402 amount: u128,1409 amount: u128,1403 ) -> DispatchResult {1410 ) -> DispatchResult {1411 // Check approval1404 collection.consume_gas(2000000)?;1412 collection.consume_sload()?;1405 // Check approval1406 let approval: u128 =1413 let approval: u128 =1407 <Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));1414 <Allowances<T>>::get(collection.id, (item_id, from.as_sub(), sender.as_sub()));140814151413 ensure!(1420 ensure!(1414 approval >= amount1421 approval >= amount1415 || (collection.limits.owner_can_transfer1422 || (collection.limits.owner_can_transfer1416 && Self::is_owner_or_admin_permissions(collection, sender)),1423 && Self::is_owner_or_admin_permissions(collection, sender)?),1417 Error::<T>::NoPermission1424 Error::<T>::NoPermission1418 );1425 );14191426142414311425 // Reduce approval by transferred amount or remove if remaining approval drops to 01432 // Reduce approval by transferred amount or remove if remaining approval drops to 01426 let allowance = approval.saturating_sub(amount);1433 let allowance = approval.saturating_sub(amount);1434 collection.consume_sstore()?;1427 if allowance > 0 {1435 if allowance > 0 {1428 <Allowances<T>>::insert(1436 <Allowances<T>>::insert(1429 collection.id,1437 collection.id,147714851478 // Modify permissions check1486 // Modify permissions check1479 ensure!(1487 ensure!(1480 Self::is_item_owner(sender, collection, item_id)1488 Self::is_item_owner(sender, collection, item_id)?1481 || Self::is_owner_or_admin_permissions(collection, sender),1489 || Self::is_owner_or_admin_permissions(collection, sender)?,1482 Error::<T>::NoPermission1490 Error::<T>::NoPermission1483 );1491 );148414921519 value: u128,1527 value: u128,1520 ) -> DispatchResult {1528 ) -> DispatchResult {1521 ensure!(1529 ensure!(1522 Self::is_item_owner(sender, collection, item_id)1530 Self::is_item_owner(sender, collection, item_id)?1523 || (collection.limits.owner_can_transfer1531 || (collection.limits.owner_can_transfer1524 && Self::is_owner_or_admin_permissions(collection, sender)),1532 && Self::is_owner_or_admin_permissions(collection, sender)?),1525 Error::<T>::NoPermission1533 Error::<T>::NoPermission1526 );1534 );152715351563 let collection_id = collection.id;1571 let collection_id = collection.id;156415721565 // check token limit and account token limit1573 // check token limit and account token limit1574 collection.consume_sload()?;1566 let account_items: u32 =1575 let account_items: u32 =1567 <AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;1576 <AddressTokens<T>>::get(collection_id, recipient.as_sub()).len() as u32;1568 ensure!(1577 ensure!(1601 Error::<T>::AccountTokenLimitExceeded1610 Error::<T>::AccountTokenLimitExceeded1602 );1611 );160316121604 if !Self::is_owner_or_admin_permissions(collection, sender) {1613 if !Self::is_owner_or_admin_permissions(collection, sender)? {1605 ensure!(collection.mint_mode, Error::<T>::PublicMintingNotAllowed);1614 ensure!(collection.mint_mode, Error::<T>::PublicMintingNotAllowed);1606 Self::check_white_list(collection, owner)?;1615 Self::check_white_list(collection, owner)?;1607 Self::check_white_list(collection, sender)?;1616 Self::check_white_list(collection, sender)?;1711 let collection_id = collection.id;1720 let collection_id = collection.id;171217211713 // Does new owner already have an account?1722 // Does new owner already have an account?1723 collection.consume_sload()?;1714 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;1724 let balance: u128 = <FungibleItemList<T>>::get(collection_id, owner.as_sub()).value;171517251716 // Mint1726 // Mint1717 let item = FungibleItemType {1727 let item = FungibleItemType {1718 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,1728 value: balance.checked_add(value).ok_or(Error::<T>::NumOverflow)?,1719 };1729 };1730 collection.consume_sstore()?;1720 <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);1731 <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), item);172117321722 // Update balance1733 // Update balance1734 collection.consume_sload()?;1723 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())1735 let new_balance = <Balance<T>>::get(collection_id, owner.as_sub())1724 .checked_add(value)1736 .checked_add(value)1725 .ok_or(Error::<T>::NumOverflow)?;1737 .ok_or(Error::<T>::NumOverflow)?;1738 collection.consume_sstore()?;1726 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);1739 <Balance<T>>::insert(collection_id, owner.as_sub(), new_balance);172717401741 collection.log(ERC20Events::Transfer {1742 from: H160::default(),1743 to: *owner.as_eth(),1744 value: value.into(),1745 })?;1728 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));1746 Self::deposit_event(RawEvent::ItemCreated(collection_id, 0, owner.clone()));1729 Ok(())1747 Ok(())1730 }1748 }1746 let value = item_owner.fraction;1764 let value = item_owner.fraction;1747 let owner = item_owner.owner.clone();1765 let owner = item_owner.owner.clone();174817661749 Self::add_token_index(collection_id, current_index, &owner)?;1767 Self::add_token_index(collection, current_index, &owner)?;175017681751 <ItemListIndex>::insert(collection_id, current_index);1769 <ItemListIndex>::insert(collection_id, current_index);1752 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);1770 <ReFungibleItemList<T>>::insert(collection_id, current_index, itemcopy);1772 .ok_or(Error::<T>::NumOverflow)?;1790 .ok_or(Error::<T>::NumOverflow)?;177317911774 let item_owner = item.owner.clone();1792 let item_owner = item.owner.clone();1775 Self::add_token_index(collection_id, current_index, &item.owner)?;1793 Self::add_token_index(collection, current_index, &item.owner)?;177617941777 <ItemListIndex>::insert(collection_id, current_index);1795 <ItemListIndex>::insert(collection_id, current_index);1778 <NftItemList<T>>::insert(collection_id, current_index, item);1796 <NftItemList<T>>::insert(collection_id, current_index, item);1810 .iter()1828 .iter()1811 .find(|&i| i.owner == *owner)1829 .find(|&i| i.owner == *owner)1812 .ok_or(Error::<T>::TokenNotFound)?;1830 .ok_or(Error::<T>::TokenNotFound)?;1813 Self::remove_token_index(collection_id, item_id, owner)?;1831 Self::remove_token_index(collection, item_id, owner)?;181418321815 // update balance1833 // update balance1816 let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.as_sub())1834 let new_balance = <Balance<T>>::get(collection_id, rft_balance.owner.as_sub())184318611844 let item =1862 let item =1845 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;1863 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;1846 Self::remove_token_index(collection_id, item_id, &item.owner)?;1864 Self::remove_token_index(collection, item_id, &item.owner)?;184718651848 // update balance1866 // update balance1849 let new_balance = <Balance<T>>::get(collection_id, item.owner.as_sub())1867 let new_balance = <Balance<T>>::get(collection_id, item.owner.as_sub())1909 fn is_owner_or_admin_permissions(1927 fn is_owner_or_admin_permissions(1910 collection: &CollectionHandle<T>,1928 collection: &CollectionHandle<T>,1911 subject: &T::CrossAccountId,1929 subject: &T::CrossAccountId,1912 ) -> bool {1930 ) -> Result<bool, DispatchError> {1931 collection.consume_sload()?;1913 *subject.as_sub() == collection.owner1932 Ok(*subject.as_sub() == collection.owner1914 || <AdminList<T>>::get(collection.id).contains(subject)1933 || <AdminList<T>>::get(collection.id).contains(subject))1915 }1934 }191619351917 fn check_owner_or_admin_permissions(1936 fn check_owner_or_admin_permissions(1918 collection: &CollectionHandle<T>,1937 collection: &CollectionHandle<T>,1919 subject: &T::CrossAccountId,1938 subject: &T::CrossAccountId,1920 ) -> DispatchResult {1939 ) -> DispatchResult {1921 ensure!(1940 ensure!(1922 Self::is_owner_or_admin_permissions(collection, subject),1941 Self::is_owner_or_admin_permissions(collection, subject)?,1923 Error::<T>::NoPermission1942 Error::<T>::NoPermission1924 );1943 );192519441926 Ok(())1945 Ok(())1927 }1946 }192819471929 fn owned_amount(1948 fn owned_amount(1949 subject: &T::CrossAccountId,1950 collection: &CollectionHandle<T>,1951 item_id: TokenId,1952 ) -> Result<Option<u128>, DispatchError> {1953 collection.consume_sload()?;1954 Ok(Self::owned_amount_unchecked(subject, collection, item_id))1955 }19561957 fn owned_amount_unchecked(1930 subject: &T::CrossAccountId,1958 subject: &T::CrossAccountId,1931 target_collection: &CollectionHandle<T>,1959 target_collection: &CollectionHandle<T>,1932 item_id: TokenId,1960 item_id: TokenId,1953 subject: &T::CrossAccountId,1981 subject: &T::CrossAccountId,1954 target_collection: &CollectionHandle<T>,1982 target_collection: &CollectionHandle<T>,1955 item_id: TokenId,1983 item_id: TokenId,1956 ) -> bool {1984 ) -> Result<bool, DispatchError> {1957 match target_collection.mode {1985 Ok(match target_collection.mode {1958 CollectionMode::Fungible(_) => true,1986 CollectionMode::Fungible(_) => true,1959 _ => Self::owned_amount(subject, target_collection, item_id).is_some(),1987 _ => Self::owned_amount(subject, target_collection, item_id)?.is_some(),1960 }1988 })1961 }1989 }196219901963 fn check_white_list(1991 fn check_white_list(1964 collection: &CollectionHandle<T>,1992 collection: &CollectionHandle<T>,1965 address: &T::CrossAccountId,1993 address: &T::CrossAccountId,1966 ) -> DispatchResult {1994 ) -> DispatchResult {1967 let collection_id = collection.id;1995 collection.consume_sload()?;19681969 let mes = Error::<T>::AddresNotInWhiteList;1970 ensure!(1996 ensure!(1971 <WhiteList<T>>::contains_key(collection_id, address.as_sub()),1997 <WhiteList<T>>::contains_key(collection.id, address.as_sub()),1972 mes1998 Error::<T>::AddresNotInWhiteList,1973 );1999 );19741975 Ok(())2000 Ok(())2000 ) -> DispatchResult {2025 ) -> DispatchResult {2001 let collection_id = collection.id;2026 let collection_id = collection.id;200220272028 collection.consume_sload()?;2003 let mut balance = <FungibleItemList<T>>::get(collection_id, owner.as_sub());2029 let mut balance = <FungibleItemList<T>>::get(collection_id, owner.as_sub());2004 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);2030 ensure!(balance.value >= value, Error::<T>::TokenValueTooLow);200520312006 // Send balance to recipient (updates balanceOf of recipient)2032 // Send balance to recipient (updates balanceOf of recipient)2007 Self::add_fungible_item(collection, recipient, value)?;2033 Self::add_fungible_item(collection, recipient, value)?;200820342009 // update balanceOf of sender2035 // update balanceOf of sender2036 collection.consume_sstore()?;2010 <Balance<T>>::insert(collection_id, owner.as_sub(), balance.value - value);2037 <Balance<T>>::insert(collection_id, owner.as_sub(), balance.value - value);201120382012 // Reduce or remove sender2039 // Reduce or remove sender2040 collection.consume_sstore()?;2013 if balance.value == value {2041 if balance.value == value {2014 <FungibleItemList<T>>::remove(collection_id, owner.as_sub());2042 <FungibleItemList<T>>::remove(collection_id, owner.as_sub());2015 } else {2043 } else {2041 new_owner: T::CrossAccountId,2069 new_owner: T::CrossAccountId,2042 ) -> DispatchResult {2070 ) -> DispatchResult {2043 let collection_id = collection.id;2071 let collection_id = collection.id;2072 collection.consume_sload()?;2044 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id)2073 let full_item = <ReFungibleItemList<T>>::get(collection_id, item_id)2045 .ok_or(Error::<T>::TokenNotFound)?;2074 .ok_or(Error::<T>::TokenNotFound)?;20462075205320822054 ensure!(amount >= value, Error::<T>::TokenValueTooLow);2083 ensure!(amount >= value, Error::<T>::TokenValueTooLow);205520842085 collection.consume_sload()?;2056 // update balance2086 // update balance2057 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2087 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2058 .checked_sub(value)2088 .checked_sub(value)2059 .ok_or(Error::<T>::NumOverflow)?;2089 .ok_or(Error::<T>::NumOverflow)?;2090 collection.consume_sstore()?;2060 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);2091 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);206120922093 collection.consume_sload()?;2062 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2094 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2063 .checked_add(value)2095 .checked_add(value)2064 .ok_or(Error::<T>::NumOverflow)?;2096 .ok_or(Error::<T>::NumOverflow)?;2097 collection.consume_sstore()?;2065 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);2098 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);206620992067 let old_owner = item.owner.clone();2100 let old_owner = item.owner.clone();2078 .find(|i| i.owner == owner)2111 .find(|i| i.owner == owner)2079 .expect("old owner does present in refungible")2112 .expect("old owner does present in refungible")2080 .owner = new_owner.clone();2113 .owner = new_owner.clone();2114 collection.consume_sstore()?;2081 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2115 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);208221162083 // update index collection2117 // update index collection2084 Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;2118 Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;2085 } else {2119 } else {2086 new_full_item2120 new_full_item2087 .owner2121 .owner2105 owner: new_owner.clone(),2139 owner: new_owner.clone(),2106 fraction: value,2140 fraction: value,2107 });2141 });2108 Self::add_token_index(collection_id, item_id, &new_owner)?;2142 Self::add_token_index(collection, item_id, &new_owner)?;2109 }2143 }211021442145 collection.consume_sstore()?;2111 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2146 <ReFungibleItemList<T>>::insert(collection_id, item_id, new_full_item);2112 }2147 }211321482129 new_owner: T::CrossAccountId,2164 new_owner: T::CrossAccountId,2130 ) -> DispatchResult {2165 ) -> DispatchResult {2131 let collection_id = collection.id;2166 let collection_id = collection.id;2167 collection.consume_sload()?;2132 let mut item =2168 let mut item =2133 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;2169 <NftItemList<T>>::get(collection_id, item_id).ok_or(Error::<T>::TokenNotFound)?;213421702135 ensure!(sender == item.owner, Error::<T>::MustBeTokenOwner);2171 ensure!(sender == item.owner, Error::<T>::MustBeTokenOwner);213621722173 collection.consume_sload()?;2137 // update balance2174 // update balance2138 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2175 let balance_old_owner = <Balance<T>>::get(collection_id, item.owner.as_sub())2139 .checked_sub(1)2176 .checked_sub(1)2140 .ok_or(Error::<T>::NumOverflow)?;2177 .ok_or(Error::<T>::NumOverflow)?;2178 collection.consume_sstore()?;2141 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);2179 <Balance<T>>::insert(collection_id, item.owner.as_sub(), balance_old_owner);214221802181 collection.consume_sload()?;2143 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2182 let balance_new_owner = <Balance<T>>::get(collection_id, new_owner.as_sub())2144 .checked_add(1)2183 .checked_add(1)2145 .ok_or(Error::<T>::NumOverflow)?;2184 .ok_or(Error::<T>::NumOverflow)?;2185 collection.consume_sstore()?;2146 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);2186 <Balance<T>>::insert(collection_id, new_owner.as_sub(), balance_new_owner);214721872148 // change owner2188 // change owner2149 let old_owner = item.owner.clone();2189 let old_owner = item.owner.clone();2150 item.owner = new_owner.clone();2190 item.owner = new_owner.clone();2191 collection.consume_sstore()?;2151 <NftItemList<T>>::insert(collection_id, item_id, item);2192 <NftItemList<T>>::insert(collection_id, item_id, item);215221932153 // update index collection2194 // update index collection2154 Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;2195 Self::move_token_index(collection, item_id, &old_owner, &new_owner)?;215521962156 collection.log(ERC721Events::Transfer {2197 collection.log(ERC721Events::Transfer {2157 from: *sender.as_eth(),2198 from: *sender.as_eth(),2232 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();2273 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();223322742234 Self::add_token_index(collection_id, current_index, &item.owner).unwrap();2275 Self::add_token_index(2276 &CollectionHandle::get(collection_id).unwrap(),2277 current_index,2278 &item.owner,2279 )2280 .unwrap();223522812251 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();2297 let current_index = <ItemListIndex>::get(collection_id).checked_add(1).unwrap();225222982253 Self::add_token_index(collection_id, current_index, owner).unwrap();2299 Self::add_token_index(2300 &CollectionHandle::get(collection_id).unwrap(),2301 current_index,2302 owner,2303 )2304 .unwrap();225423052272 let owner = item.owner.first().unwrap().owner.clone();2323 let owner = item.owner.first().unwrap().owner.clone();227323242274 Self::add_token_index(collection_id, current_index, &owner).unwrap();2325 Self::add_token_index(2326 &CollectionHandle::get(collection_id).unwrap(),2327 current_index,2328 &owner,2329 )2330 .unwrap();227523312283 }2339 }228423402285 fn add_token_index(2341 fn add_token_index(2286 collection_id: CollectionId,2342 collection: &CollectionHandle<T>,2287 item_index: TokenId,2343 item_index: TokenId,2288 owner: &T::CrossAccountId,2344 owner: &T::CrossAccountId,2289 ) -> DispatchResult {2345 ) -> DispatchResult {2290 // add to account limit2346 // add to account limit2347 collection.consume_sload()?;2291 if <AccountItemCount<T>>::contains_key(owner.as_sub()) {2348 if <AccountItemCount<T>>::contains_key(owner.as_sub()) {2292 // bound Owned tokens by a single address2349 // bound Owned tokens by a single address2350 collection.consume_sload()?;2293 let count = <AccountItemCount<T>>::get(owner.as_sub());2351 let count = <AccountItemCount<T>>::get(owner.as_sub());2294 ensure!(2352 ensure!(2295 count < ChainLimit::get().account_token_ownership_limit,2353 count < ChainLimit::get().account_token_ownership_limit,2296 Error::<T>::AddressOwnershipLimitExceeded2354 Error::<T>::AddressOwnershipLimitExceeded2297 );2355 );229823562357 collection.consume_sstore()?;2299 <AccountItemCount<T>>::insert(2358 <AccountItemCount<T>>::insert(2300 owner.as_sub(),2359 owner.as_sub(),2301 count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,2360 count.checked_add(1).ok_or(Error::<T>::NumOverflow)?,2302 );2361 );2303 } else {2362 } else {2363 collection.consume_sstore()?;2304 <AccountItemCount<T>>::insert(owner.as_sub(), 1);2364 <AccountItemCount<T>>::insert(owner.as_sub(), 1);2305 }2365 }230623662367 collection.consume_sload()?;2307 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());2368 let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());2308 if list_exists {2369 if list_exists {2370 collection.consume_sload()?;2309 let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());2371 let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());2310 let item_contains = list.contains(&item_index.clone());2372 let item_contains = list.contains(&item_index.clone());231123732312 if !item_contains {2374 if !item_contains {2313 list.push(item_index);2375 list.push(item_index);2314 }2376 }231523772378 collection.consume_sstore()?;2316 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);2379 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);2317 } else {2380 } else {2318 let itm = vec![item_index];2381 let itm = vec![item_index];2382 collection.consume_sstore()?;2319 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), itm);2383 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), itm);2320 }2384 }232123852322 Ok(())2386 Ok(())2323 }2387 }232423882325 fn remove_token_index(2389 fn remove_token_index(2326 collection_id: CollectionId,2390 collection: &CollectionHandle<T>,2327 item_index: TokenId,2391 item_index: TokenId,2328 owner: &T::CrossAccountId,2392 owner: &T::CrossAccountId,2329 ) -> DispatchResult {2393 ) -> DispatchResult {2330 // update counter2394 // update counter2395 collection.consume_sload()?;2396 collection.consume_sstore()?;2331 <AccountItemCount<T>>::insert(2397 <AccountItemCount<T>>::insert(2332 owner.as_sub(),2398 owner.as_sub(),2333 <AccountItemCount<T>>::get(owner.as_sub())2399 <AccountItemCount<T>>::get(owner.as_sub())2334 .checked_sub(1)2400 .checked_sub(1)2335 .ok_or(Error::<T>::NumOverflow)?,2401 .ok_or(Error::<T>::NumOverflow)?,2336 );2402 );233724032404 collection.consume_sload()?;2338 let list_exists = <AddressTokens<T>>::contains_key(collection_id, owner.as_sub());2405 let list_exists = <AddressTokens<T>>::contains_key(collection.id, owner.as_sub());2339 if list_exists {2406 if list_exists {2407 collection.consume_sload()?;2340 let mut list = <AddressTokens<T>>::get(collection_id, owner.as_sub());2408 let mut list = <AddressTokens<T>>::get(collection.id, owner.as_sub());2341 let item_contains = list.contains(&item_index.clone());2409 let item_contains = list.contains(&item_index.clone());234224102343 if item_contains {2411 if item_contains {2344 list.retain(|&item| item != item_index);2412 list.retain(|&item| item != item_index);2413 collection.consume_sstore()?;2345 <AddressTokens<T>>::insert(collection_id, owner.as_sub(), list);2414 <AddressTokens<T>>::insert(collection.id, owner.as_sub(), list);2346 }2415 }2347 }2416 }234824172349 Ok(())2418 Ok(())2350 }2419 }235124202352 fn move_token_index(2421 fn move_token_index(2353 collection_id: CollectionId,2422 collection: &CollectionHandle<T>,2354 item_index: TokenId,2423 item_index: TokenId,2355 old_owner: &T::CrossAccountId,2424 old_owner: &T::CrossAccountId,2356 new_owner: &T::CrossAccountId,2425 new_owner: &T::CrossAccountId,2357 ) -> DispatchResult {2426 ) -> DispatchResult {2358 Self::remove_token_index(collection_id, item_index, old_owner)?;2427 Self::remove_token_index(collection, item_index, old_owner)?;2359 Self::add_token_index(collection_id, item_index, new_owner)?;2428 Self::add_token_index(collection, item_index, new_owner)?;236024292361 Ok(())2430 Ok(())2362 }2431 }