git.delta.rocks / unique-network / refs/commits / 017086424d43

difftreelog

fix owner/admin ignores token restrictions

Daniel Shiposha2023-01-16parent: #670ea14.patch.diff
in: master

4 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
390 Ok(())390 Ok(())
391 }391 }
392392
393 /// Return **true** if `user` was not allowed to have tokens, and he can ignore such restrictions.393 /// Returns **true** if
394 /// * the `user`is a collection owner or admin
395 /// * the collection limits allow the owner/admins to transfer/burn any collection token
394 pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> bool {396 pub fn ignores_token_restrictions(&self, user: &T::CrossAccountId) -> bool {
395 self.limits.owner_can_transfer() && self.is_owner_or_admin(user)397 self.limits.owner_can_transfer() && self.is_owner_or_admin(user)
396 }398 }
397399
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
678 collection.check_allowlist(spender)?;678 collection.check_allowlist(spender)?;
679 }679 }
680
681 if collection.ignores_token_restrictions(spender) {
682 return Ok(Self::compute_allowance_decrease(
683 collection, from, spender, amount,
684 ));
685 }
686
680 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {687 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
681 // TODO: should collection owner be allowed to perform this transfer?
682 ensure!(688 ensure!(
683 <PalletStructure<T>>::check_indirectly_owned(689 <PalletStructure<T>>::check_indirectly_owned(
684 spender.clone(),690 spender.clone(),
692 return Ok(None);698 return Ok(None);
693 }699 }
700
694 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);701 let allowance = Self::compute_allowance_decrease(collection, from, spender, amount);
695 if allowance.is_none() {
696 ensure!(702 ensure!(allowance.is_some(), <CommonError<T>>::ApprovedValueTooLow);
697 collection.ignores_allowance(spender),
698 <CommonError<T>>::ApprovedValueTooLow
699 );
700 }
701703
702 Ok(allowance)704 Ok(allowance)
703 }705 }
706
707 /// Returns `Some(amount)` if the `spender` have allowance to spend this amount.
708 /// Otherwise, it returns `None`.
709 fn compute_allowance_decrease(
710 collection: &FungibleHandle<T>,
711 from: &T::CrossAccountId,
712 spender: &T::CrossAccountId,
713 amount: u128,
714 ) -> Option<u128> {
715 <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount)
716 }
704717
705 /// Transfer fungible tokens from one account to another.718 /// Transfer fungible tokens from one account to another.
706 /// Same as the [`transfer`][`Pallet::transfer`] but spender doesn't needs to be an owner of the token pieces.719 /// Same as the [`transfer`][`Pallet::transfer`] but spender doesn't needs to be an owner of the token pieces.
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
1246 collection.check_allowlist(spender)?;1246 collection.check_allowlist(spender)?;
1247 }1247 }
12481248
1249 if collection.limits.owner_can_transfer() && collection.is_owner_or_admin(spender) {1249 if collection.ignores_token_restrictions(spender) {
1250 return Ok(());1250 return Ok(());
1251 }1251 }
12521252
1269 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1269 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {
1270 return Ok(());1270 return Ok(());
1271 }1271 }
1272 ensure!(1272
1273 collection.ignores_allowance(spender),
1274 <CommonError<T>>::ApprovedValueTooLow1273 Err(<CommonError<T>>::ApprovedValueTooLow.into())
1275 );
1276 Ok(())
1277 }1274 }
12781275
1279 /// Transfer NFT token from one account to another.1276 /// Transfer NFT token from one account to another.
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
1178 collection.check_allowlist(spender)?;1178 collection.check_allowlist(spender)?;
1179 }1179 }
11801180
1181 if collection.limits.owner_can_transfer() && collection.is_owner_or_admin(spender) {1181 if collection.ignores_token_restrictions(spender) {
1182 return Ok(None);1182 return Ok(Self::compute_allowance_decrease(
1183 collection, token, from, &spender, amount,
1184 ));
1183 }1185 }
11841186
1185 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {1187 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
1197 return Ok(None);1199 return Ok(None);
1198 }1200 }
1201
1199 let allowance =1202 let allowance = Self::compute_allowance_decrease(collection, token, from, &spender, amount);
1200 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);1203 if allowance.is_some() {
1204 return Ok(allowance);
1205 }
12011206
1202 // Allowance (if any) would be reduced if spender is also wallet operator1207 // Allowance (if any) would be reduced if spender is also wallet operator
1203 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {1208 if <CollectionAllowance<T>>::get((collection.id, from, spender)) {
1204 return Ok(allowance);1209 return Ok(allowance);
1205 }1210 }
12061211
1207 if allowance.is_none() {
1208 ensure!(
1209 collection.ignores_allowance(spender),
1210 <CommonError<T>>::ApprovedValueTooLow1212 Err(<CommonError<T>>::ApprovedValueTooLow.into())
1211 );
1212 }
1213 Ok(allowance)
1214 }1213 }
1214
1215 /// Returns `Some(amount)` if the `spender` have allowance to spend this amount.
1216 /// Otherwise, it returns `None`.
1217 fn compute_allowance_decrease(
1218 collection: &RefungibleHandle<T>,
1219 token: TokenId,
1220 from: &T::CrossAccountId,
1221 spender: &T::CrossAccountId,
1222 amount: u128,
1223 ) -> Option<u128> {
1224 <Allowance<T>>::get((collection.id, token, from, spender)).checked_sub(amount)
1225 }
12151226
1216 /// Transfer RFT token pieces from one account to another.1227 /// Transfer RFT token pieces from one account to another.
1217 ///1228 ///