--- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -22,7 +22,10 @@ pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId}; use pallet_evm_coder_substrate::dispatch_to_evm; use sp_std::vec::Vec; -use up_data_structs::{Property, SponsoringRateLimit, NestingRule, OwnerRestrictedSet, AccessMode}; +use up_data_structs::{ + Property, SponsoringRateLimit, NestingRule, OwnerRestrictedSet, AccessMode, + CollectionPermissions, +}; use alloc::format; use crate::{Pallet, CollectionHandle, Config, CollectionProperties}; @@ -211,10 +214,20 @@ #[solidity(rename_selector = "setNesting")] fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result { check_is_owner_or_admin(caller, self)?; - self.collection.permissions.nesting = Some(match enable { - false => NestingRule::Disabled, - true => NestingRule::Owner, - }); + let permissions = CollectionPermissions { + nesting: Some(match enable { + false => NestingRule::Disabled, + true => NestingRule::Owner, + }), + ..Default::default() + }; + self.collection.permissions = >::clamp_permissions( + self.collection.mode.clone(), + &self.collection.permissions, + permissions, + ) + .map_err(dispatch_to_evm::)?; + save(self)?; Ok(()) } @@ -237,19 +250,29 @@ ))); } check_is_owner_or_admin(caller, self)?; - self.collection.permissions.nesting = Some(match enable { - false => NestingRule::Disabled, - true => { - let mut bv = OwnerRestrictedSet::new(); - for i in collections { - bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or_else(|| { - Error::Revert("Can't convert address into collection id".into()) - })?) - .map_err(|e| Error::Revert(format!("{:?}", e)))?; + let permissions = CollectionPermissions { + nesting: Some(match enable { + false => NestingRule::Disabled, + true => { + let mut bv = OwnerRestrictedSet::new(); + for i in collections { + bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or_else(|| { + Error::Revert("Can't convert address into collection id".into()) + })?) + .map_err(|e| Error::Revert(format!("{:?}", e)))?; + } + NestingRule::OwnerRestricted(bv) } - NestingRule::OwnerRestricted(bv) - } - }); + }), + ..Default::default() + }; + self.collection.permissions = >::clamp_permissions( + self.collection.mode.clone(), + &self.collection.permissions, + permissions, + ) + .map_err(dispatch_to_evm::)?; + save(self)?; Ok(()) } --- a/tests/src/setCollectionLimits.test.ts +++ b/tests/src/setCollectionLimits.test.ts @@ -46,6 +46,7 @@ before(async () => { await usingApi(async (api, privateKeyWrapper) => { alice = privateKeyWrapper('//Alice'); + bob = privateKeyWrapper('//Bob'); collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}}); }); }); @@ -115,6 +116,21 @@ }); }); + it('execute setCollectionLimits from admin collection', async () => { + await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address); + await usingApi(async (api: ApiPromise) => { + tx = api.tx.unique.setCollectionLimits( + collectionIdForTesting, + { + accountTokenOwnershipLimit, + sponsoredDataSize, + // sponsoredMintSize, + tokenLimit, + }, + ); + await expect(submitTransactionAsync(bob, tx)).to.be.not.rejected; + }); + }); }); describe('setCollectionLimits negative', () => { @@ -143,21 +159,6 @@ }); }); it('execute setCollectionLimits from user who is not owner of this collection', async () => { - await usingApi(async (api: ApiPromise) => { - tx = api.tx.unique.setCollectionLimits( - collectionIdForTesting, - { - accountTokenOwnershipLimit, - sponsoredDataSize, - // sponsoredMintSize, - tokenLimit, - }, - ); - await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected; - }); - }); - it('execute setCollectionLimits from admin collection', async () => { - await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address); await usingApi(async (api: ApiPromise) => { tx = api.tx.unique.setCollectionLimits( collectionIdForTesting, --- a/tests/src/setCollectionSponsor.test.ts +++ b/tests/src/setCollectionSponsor.test.ts @@ -65,6 +65,11 @@ await setCollectionSponsorExpectSuccess(collectionId, bob.address); await setCollectionSponsorExpectSuccess(collectionId, charlie.address); }); + it('Collection admin add sponsor', async () => { + const collectionId = await createCollectionExpectSuccess(); + await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); + await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob'); + }); }); describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => { @@ -93,10 +98,5 @@ const collectionId = await createCollectionExpectSuccess(); await destroyCollectionExpectSuccess(collectionId); await setCollectionSponsorExpectFailure(collectionId, bob.address); - }); - it('(!negative test!) Collection admin add sponsor', async () => { - const collectionId = await createCollectionExpectSuccess(); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await setCollectionSponsorExpectFailure(collectionId, charlie.address, '//Bob'); }); }); --- a/tests/src/setMintPermission.test.ts +++ b/tests/src/setMintPermission.test.ts @@ -67,6 +67,14 @@ await setMintPermissionExpectSuccess(alice, collectionId, false); }); }); + + it('Collection admin success on set', async () => { + await usingApi(async () => { + const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); + await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); + await setMintPermissionExpectSuccess(bob, collectionId, true); + }); + }); }); describe('Negative Integration Test setMintPermission', () => { @@ -100,14 +108,6 @@ const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); await enableAllowListExpectSuccess(alice, collectionId); await setMintPermissionExpectFailure(bob, collectionId, true); - }); - - it('Collection admin fails on set', async () => { - await usingApi(async () => { - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); - await setMintPermissionExpectFailure(bob, collectionId, true); - }); }); it('ensure non-allow-listed non-privileged address can\'t mint tokens', async () => { --- a/tests/src/setPublicAccessMode.test.ts +++ b/tests/src/setPublicAccessMode.test.ts @@ -103,22 +103,23 @@ await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected; }); }); -}); -describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => { - before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); - }); - }); it('setPublicAccessMode by collection admin', async () => { await usingApi(async (api: ApiPromise) => { // tslint:disable-next-line: no-bitwise const collectionId = await createCollectionExpectSuccess(); await addCollectionAdminExpectSuccess(alice, collectionId, bob.address); const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'}); - await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected; + await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.not.rejected; + }); + }); +}); + +describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => { + before(async () => { + await usingApi(async (api, privateKeyWrapper) => { + alice = privateKeyWrapper('//Alice'); + bob = privateKeyWrapper('//Bob'); }); }); });