--- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -201,7 +201,7 @@ Ok(()) } - fn remove_admin(&self, caller: caller, admin: address) -> Result { + fn remove_collection_admin(&self, caller: caller, admin: address) -> Result { let caller = T::CrossAccountId::from_eth(caller); let admin = T::CrossAccountId::from_eth(admin); >::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::)?; @@ -220,12 +220,21 @@ } #[solidity(rename_selector = "setNesting")] - fn set_nesting(&mut self, caller: caller, enable: bool, collections: Vec
) -> Result { + fn set_nesting( + &mut self, + caller: caller, + enable: bool, + collections: Vec
, + ) -> Result { if collections.is_empty() { return Err("No addresses provided".into()); } if collections.len() >= OwnerRestrictedSet::bound() { - return Err(Error::Revert(format!("Out of bound: {} >= {}", collections.len(), OwnerRestrictedSet::bound()))); + return Err(Error::Revert(format!( + "Out of bound: {} >= {}", + collections.len(), + OwnerRestrictedSet::bound() + ))); } check_is_owner_or_admin(caller, self)?; self.collection.permissions.nesting = Some(match enable { @@ -238,7 +247,7 @@ })?) .map_err(|e| Error::Revert(format!("{:?}", e)))?; } - NestingRule::OwnerRestricted (bv) + NestingRule::OwnerRestricted(bv) } }); save(self)?; --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -148,7 +148,6 @@ .saturating_mul(writes), )) } - pub fn save(self) -> DispatchResult { >::insert(self.id, self.collection); Ok(()) --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -51,147 +51,6 @@ event MintingFinished(); } -// Selector: 2da6e59e -contract Collection is Dummy, ERC165 { - // Selector: setCollectionProperty(string,bytes) 2f073f66 - function setCollectionProperty(string memory key, bytes memory value) - public - { - require(false, stub_error); - key; - value; - dummy = 0; - } - - // Selector: deleteCollectionProperty(string) 7b7debce - function deleteCollectionProperty(string memory key) public { - require(false, stub_error); - key; - dummy = 0; - } - - // Throws error if key not found - // - // Selector: collectionProperty(string) cf24fd6d - function collectionProperty(string memory key) - public - view - returns (bytes memory) - { - require(false, stub_error); - key; - dummy; - return hex""; - } - - // Selector: setCollectionSponsor(address) 7623402e - function setCollectionSponsor(address sponsor) public { - require(false, stub_error); - sponsor; - dummy = 0; - } - - // Selector: confirmCollectionSponsorship() 3c50e97a - function confirmCollectionSponsorship() public { - require(false, stub_error); - dummy = 0; - } - - // Selector: setCollectionLimit(string,uint32) 6a3841db - function setCollectionLimit(string memory limit, uint32 value) public { - require(false, stub_error); - limit; - value; - dummy = 0; - } - - // Selector: setCollectionLimit(string,bool) 993b7fba - function setCollectionLimit(string memory limit, bool value) public { - require(false, stub_error); - limit; - value; - dummy = 0; - } - - // Selector: contractAddress() f6b4dfb4 - function contractAddress() public view returns (address) { - require(false, stub_error); - dummy; - return 0x0000000000000000000000000000000000000000; - } - - // Selector: addCollectionAdminSubstrate(uint256) 5730062b - function addCollectionAdminSubstrate(uint256 newAdmin) public view { - require(false, stub_error); - newAdmin; - dummy; - } - - // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9 - function removeCollectionAdminSubstrate(uint256 newAdmin) public view { - require(false, stub_error); - newAdmin; - dummy; - } - - // Selector: addCollectionAdmin(address) 92e462c7 - function addCollectionAdmin(address newAdmin) public view { - require(false, stub_error); - newAdmin; - dummy; - } - - // Selector: removeAdmin(address) 1785f53c - function removeAdmin(address admin) public view { - require(false, stub_error); - admin; - dummy; - } - - // Selector: setNesting(bool) e8fc50dd - function setNesting(bool enable) public { - require(false, stub_error); - enable; - dummy = 0; - } - - // Selector: setNesting(bool,address[]) 7df12a9a - function setNesting(bool enable, address[] memory collections) public { - require(false, stub_error); - enable; - collections; - dummy = 0; - } - - // Selector: setCollectionAccess(uint8) 41835d4c - function setCollectionAccess(uint8 mode) public { - require(false, stub_error); - mode; - dummy = 0; - } - - // Selector: addToCollectionAllowList(address) 67844fe6 - function addToCollectionAllowList(address user) public view { - require(false, stub_error); - user; - dummy; - } - - // Selector: removeFromCollectionAllowList(address) 85c51acb - function removeFromCollectionAllowList(address user) public view { - require(false, stub_error); - user; - dummy; - } - - // Selector: setMintMode(bool) 5dea9bd5 - function setMintMode(bool mode) public { - require(false, stub_error); - mode; - dummy = 0; - } -} - // Selector: 41369377 contract TokenProperties is Dummy, ERC165 { // Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa @@ -471,6 +330,147 @@ } } +// Selector: c0de6be0 +contract Collection is Dummy, ERC165 { + // Selector: setCollectionProperty(string,bytes) 2f073f66 + function setCollectionProperty(string memory key, bytes memory value) + public + { + require(false, stub_error); + key; + value; + dummy = 0; + } + + // Selector: deleteCollectionProperty(string) 7b7debce + function deleteCollectionProperty(string memory key) public { + require(false, stub_error); + key; + dummy = 0; + } + + // Throws error if key not found + // + // Selector: collectionProperty(string) cf24fd6d + function collectionProperty(string memory key) + public + view + returns (bytes memory) + { + require(false, stub_error); + key; + dummy; + return hex""; + } + + // Selector: setCollectionSponsor(address) 7623402e + function setCollectionSponsor(address sponsor) public { + require(false, stub_error); + sponsor; + dummy = 0; + } + + // Selector: confirmCollectionSponsorship() 3c50e97a + function confirmCollectionSponsorship() public { + require(false, stub_error); + dummy = 0; + } + + // Selector: setCollectionLimit(string,uint32) 6a3841db + function setCollectionLimit(string memory limit, uint32 value) public { + require(false, stub_error); + limit; + value; + dummy = 0; + } + + // Selector: setCollectionLimit(string,bool) 993b7fba + function setCollectionLimit(string memory limit, bool value) public { + require(false, stub_error); + limit; + value; + dummy = 0; + } + + // Selector: contractAddress() f6b4dfb4 + function contractAddress() public view returns (address) { + require(false, stub_error); + dummy; + return 0x0000000000000000000000000000000000000000; + } + + // Selector: addCollectionAdminSubstrate(uint256) 5730062b + function addCollectionAdminSubstrate(uint256 newAdmin) public view { + require(false, stub_error); + newAdmin; + dummy; + } + + // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9 + function removeCollectionAdminSubstrate(uint256 newAdmin) public view { + require(false, stub_error); + newAdmin; + dummy; + } + + // Selector: addCollectionAdmin(address) 92e462c7 + function addCollectionAdmin(address newAdmin) public view { + require(false, stub_error); + newAdmin; + dummy; + } + + // Selector: removeCollectionAdmin(address) fafd7b42 + function removeCollectionAdmin(address admin) public view { + require(false, stub_error); + admin; + dummy; + } + + // Selector: setNesting(bool) e8fc50dd + function setNesting(bool enable) public { + require(false, stub_error); + enable; + dummy = 0; + } + + // Selector: setNesting(bool,address[]) 7df12a9a + function setNesting(bool enable, address[] memory collections) public { + require(false, stub_error); + enable; + collections; + dummy = 0; + } + + // Selector: setCollectionAccess(uint8) 41835d4c + function setCollectionAccess(uint8 mode) public { + require(false, stub_error); + mode; + dummy = 0; + } + + // Selector: addToCollectionAllowList(address) 67844fe6 + function addToCollectionAllowList(address user) public view { + require(false, stub_error); + user; + dummy; + } + + // Selector: removeFromCollectionAllowList(address) 85c51acb + function removeFromCollectionAllowList(address user) public view { + require(false, stub_error); + user; + dummy; + } + + // Selector: setMintMode(bool) 5dea9bd5 + function setMintMode(bool mode) public { + require(false, stub_error); + mode; + dummy = 0; + } +} + // Selector: d74d154f contract ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb --- a/runtime/tests/src/tests.rs +++ b/runtime/tests/src/tests.rs @@ -1286,7 +1286,7 @@ account(3) ))); - // remove admin 3 + // remove admin 3 assert_ok!(Unique::remove_collection_admin( origin1, CollectionId(1), --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -42,69 +42,6 @@ event MintingFinished(); } -// Selector: 2da6e59e -interface Collection is Dummy, ERC165 { - // Selector: setCollectionProperty(string,bytes) 2f073f66 - function setCollectionProperty(string memory key, bytes memory value) - external; - - // Selector: deleteCollectionProperty(string) 7b7debce - function deleteCollectionProperty(string memory key) external; - - // Throws error if key not found - // - // Selector: collectionProperty(string) cf24fd6d - function collectionProperty(string memory key) - external - view - returns (bytes memory); - - // Selector: setCollectionSponsor(address) 7623402e - function setCollectionSponsor(address sponsor) external; - - // Selector: confirmCollectionSponsorship() 3c50e97a - function confirmCollectionSponsorship() external; - - // Selector: setCollectionLimit(string,uint32) 6a3841db - function setCollectionLimit(string memory limit, uint32 value) external; - - // Selector: setCollectionLimit(string,bool) 993b7fba - function setCollectionLimit(string memory limit, bool value) external; - - // Selector: contractAddress() f6b4dfb4 - function contractAddress() external view returns (address); - - // Selector: addCollectionAdminSubstrate(uint256) 5730062b - function addCollectionAdminSubstrate(uint256 newAdmin) external view; - - // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9 - function removeCollectionAdminSubstrate(uint256 newAdmin) external view; - - // Selector: addCollectionAdmin(address) 92e462c7 - function addCollectionAdmin(address newAdmin) external view; - - // Selector: removeAdmin(address) 1785f53c - function removeAdmin(address admin) external view; - - // Selector: setNesting(bool) e8fc50dd - function setNesting(bool enable) external; - - // Selector: setNesting(bool,address[]) 7df12a9a - function setNesting(bool enable, address[] memory collections) external; - - // Selector: setCollectionAccess(uint8) 41835d4c - function setCollectionAccess(uint8 mode) external; - - // Selector: addToCollectionAllowList(address) 67844fe6 - function addToCollectionAllowList(address user) external view; - - // Selector: removeFromCollectionAllowList(address) 85c51acb - function removeFromCollectionAllowList(address user) external view; - - // Selector: setMintMode(bool) 5dea9bd5 - function setMintMode(bool mode) external; -} - // Selector: 41369377 interface TokenProperties is Dummy, ERC165 { // Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa @@ -254,6 +191,69 @@ function totalSupply() external view returns (uint256); } +// Selector: c0de6be0 +interface Collection is Dummy, ERC165 { + // Selector: setCollectionProperty(string,bytes) 2f073f66 + function setCollectionProperty(string memory key, bytes memory value) + external; + + // Selector: deleteCollectionProperty(string) 7b7debce + function deleteCollectionProperty(string memory key) external; + + // Throws error if key not found + // + // Selector: collectionProperty(string) cf24fd6d + function collectionProperty(string memory key) + external + view + returns (bytes memory); + + // Selector: setCollectionSponsor(address) 7623402e + function setCollectionSponsor(address sponsor) external; + + // Selector: confirmCollectionSponsorship() 3c50e97a + function confirmCollectionSponsorship() external; + + // Selector: setCollectionLimit(string,uint32) 6a3841db + function setCollectionLimit(string memory limit, uint32 value) external; + + // Selector: setCollectionLimit(string,bool) 993b7fba + function setCollectionLimit(string memory limit, bool value) external; + + // Selector: contractAddress() f6b4dfb4 + function contractAddress() external view returns (address); + + // Selector: addCollectionAdminSubstrate(uint256) 5730062b + function addCollectionAdminSubstrate(uint256 newAdmin) external view; + + // Selector: removeCollectionAdminSubstrate(uint256) 4048fcf9 + function removeCollectionAdminSubstrate(uint256 newAdmin) external view; + + // Selector: addCollectionAdmin(address) 92e462c7 + function addCollectionAdmin(address newAdmin) external view; + + // Selector: removeCollectionAdmin(address) fafd7b42 + function removeCollectionAdmin(address admin) external view; + + // Selector: setNesting(bool) e8fc50dd + function setNesting(bool enable) external; + + // Selector: setNesting(bool,address[]) 7df12a9a + function setNesting(bool enable, address[] memory collections) external; + + // Selector: setCollectionAccess(uint8) 41835d4c + function setCollectionAccess(uint8 mode) external; + + // Selector: addToCollectionAllowList(address) 67844fe6 + function addToCollectionAllowList(address user) external view; + + // Selector: removeFromCollectionAllowList(address) 85c51acb + function removeFromCollectionAllowList(address user) external view; + + // Selector: setMintMode(bool) 5dea9bd5 + function setMintMode(bool mode) external; +} + // Selector: d74d154f interface ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb --- a/tests/src/eth/contractSponsoring.test.ts +++ b/tests/src/eth/contractSponsoring.test.ts @@ -221,7 +221,6 @@ expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200'); }); - //TODO: CORE-302 add eth methods itWeb3('Sponsoring collection from evm address via access list', async ({api, web3}) => { const owner = await createEthAccountWithBalance(api, web3); const collectionHelpers = evmCollectionHelpers(web3, owner); @@ -229,13 +228,13 @@ const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); const sponsor = await createEthAccountWithBalance(api, web3); const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - result = await collectionEvm.methods.ethSetSponsor(sponsor).send({from: owner}); + result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner}); let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor'); - await collectionEvm.methods.ethConfirmSponsorship().send({from: sponsor}); + await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor}); collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; expect(collectionSub.sponsorship.isConfirmed).to.be.true; expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); @@ -248,15 +247,16 @@ expect(oldPermissions.mintMode).to.be.false; expect(oldPermissions.access).to.be.equal('Normal'); - await collectionEvm.methods.setAccess('AllowList').send({from: owner}); - await collectionEvm.methods.addToAllowList(user).send({from: owner}); + await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner}); + await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner}); await collectionEvm.methods.setMintMode(true).send({from: owner}); const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman(); expect(newPermissions.mintMode).to.be.true; expect(newPermissions.access).to.be.equal('AllowList'); - // const [alicesBalanceBefore] = await getBalance(api, [alicesPublicKey]); + const ownerBalanceBefore = await ethBalanceViaSub(api, owner); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); { const nextTokenId = await collectionEvm.methods.nextTokenId().call(); @@ -265,13 +265,12 @@ user, nextTokenId, 'Test URI', - ).call({from: user}); - console.log(result); + ).send({from: user}); const events = normalizeEvents(result.events); expect(events).to.be.deep.equal([ { - collectionIdAddress, + address: collectionIdAddress, event: 'Transfer', args: { from: '0x0000000000000000000000000000000000000000', @@ -281,7 +280,12 @@ }, ]); + const ownerBalanceAfter = await ethBalanceViaSub(api, owner); + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); + expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter); + expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true; } }); @@ -292,19 +296,19 @@ const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); const sponsor = await createEthAccountWithBalance(api, web3); const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - result = await collectionEvm.methods.ethSetSponsor(sponsor).send(); + result = await collectionEvm.methods.setCollectionSponsor(sponsor).send(); let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); - await expect(collectionEvm.methods.ethConfirmSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor'); + await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor'); const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress); - await sponsorCollection.methods.ethConfirmSponsorship().send(); + await sponsorCollection.methods.confirmCollectionSponsorship().send(); collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; expect(collectionSub.sponsorship.isConfirmed).to.be.true; expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor)); const user = createEthAccount(web3); - await collectionEvm.methods.addAdmin(user).send(); + await collectionEvm.methods.addCollectionAdmin(user).send(); const ownerBalanceBefore = await ethBalanceViaSub(api, owner); const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); --- a/tests/src/eth/nonFungibleAbi.json +++ b/tests/src/eth/nonFungibleAbi.json @@ -302,7 +302,7 @@ "inputs": [ { "internalType": "address", "name": "admin", "type": "address" } ], - "name": "removeAdmin", + "name": "removeCollectionAdmin", "outputs": [], "stateMutability": "view", "type": "function" --- a/tests/src/eth/proxy/nonFungibleProxy.test.ts +++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts @@ -99,7 +99,7 @@ const collectionEvmOwned = evmCollection(web3, owner, collectionIdAddress); const collectionEvm = evmCollection(web3, caller, collectionIdAddress); const contract = await proxyWrap(api, web3, collectionEvm); - await collectionEvmOwned.methods.addAdmin(contract.options.address).send(); + await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send(); { const nextTokenId = await contract.methods.nextTokenId().call();