12345678910111213141516import {IKeyringPair} from '@polkadot/types/types';17import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util';1819async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise<any>) {20 const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));21 await call();22 await helper.wait.newBlocks(1);23 const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress));2425 expect(after < before).to.be.true;2627 return before - after;28}2930describe('Add collection admins', () => {31 let donor: IKeyringPair;3233 before(async function() {34 await usingEthPlaygrounds(async (_helper, privateKey) => {35 donor = await privateKey({filename: __filename});36 });37 });3839 itEth('Add admin by owner', async ({helper}) => {40 const owner = await helper.eth.createAccountWithBalance(donor);41 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');42 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);4344 const newAdmin = helper.eth.createAccount();4546 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();47 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);48 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())49 .to.be.eq(newAdmin.toLocaleLowerCase());50 });5152 itEth('Add cross account admin by owner', async ({helper, privateKey}) => {53 const owner = await helper.eth.createAccountWithBalance(donor);54 55 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');56 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);57 58 const newAdmin = await privateKey('//Bob');59 const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);60 await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();6162 const adminList = await helper.collection.getAdmins(collectionId);63 expect(adminList).to.be.like([{Substrate: newAdmin.address}]);64 });6566 67 68 69 70 7172 73 74 75 7677 78 79 80 81 82 83 8485 itEth('Verify owner or admin', async ({helper}) => {86 const owner = await helper.eth.createAccountWithBalance(donor);87 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');8889 const newAdmin = helper.eth.createAccount();90 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);91 92 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;93 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();94 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;95 });9697 98 99 100 101 102103 104 105 106 107108 109 110 111 112 113 114 115 116 itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {117 const owner = await helper.eth.createAccountWithBalance(donor);118 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');119120 const admin = await helper.eth.createAccountWithBalance(donor);121 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);122 await collectionEvm.methods.addCollectionAdmin(admin).send();123124 const user = helper.eth.createAccount();125 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))126 .to.be.rejectedWith('NoPermission');127128 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);129 expect(adminList.length).to.be.eq(1);130 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())131 .to.be.eq(admin.toLocaleLowerCase());132 });133134 itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => {135 const owner = await helper.eth.createAccountWithBalance(donor);136 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');137138 const notAdmin = await helper.eth.createAccountWithBalance(donor);139 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);140141 const user = helper.eth.createAccount();142 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))143 .to.be.rejectedWith('NoPermission');144145 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);146 expect(adminList.length).to.be.eq(0);147 });148149 itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => {150 const owner = await helper.eth.createAccountWithBalance(donor);151 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');152153 const admin = await helper.eth.createAccountWithBalance(donor);154 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);155 await collectionEvm.methods.addCollectionAdmin(admin).send();156157 const [notAdmin] = await helper.arrange.createAccounts([10n], donor);158 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))159 .to.be.rejectedWith('NoPermission');160161 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);162 expect(adminList.length).to.be.eq(1);163 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())164 .to.be.eq(admin.toLocaleLowerCase());165 });166167 itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => {168 const owner = await helper.eth.createAccountWithBalance(donor);169 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');170171 const notAdmin0 = await helper.eth.createAccountWithBalance(donor);172 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);173 const [notAdmin1] = await helper.arrange.createAccounts([10n], donor);174 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))175 .to.be.rejectedWith('NoPermission');176177 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);178 expect(adminList.length).to.be.eq(0);179 });180});181182describe('Remove collection admins', () => {183 let donor: IKeyringPair;184185 before(async function() {186 await usingEthPlaygrounds(async (_helper, privateKey) => {187 donor = await privateKey({filename: __filename});188 });189 });190191 itEth('Remove admin by owner', async ({helper}) => {192 const owner = await helper.eth.createAccountWithBalance(donor);193 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');194195 const newAdmin = helper.eth.createAccount();196 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);197 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();198199 {200 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);201 expect(adminList.length).to.be.eq(1);202 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())203 .to.be.eq(newAdmin.toLocaleLowerCase());204 }205206 await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();207 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);208 expect(adminList.length).to.be.eq(0);209 });210211 itEth.skip('Remove substrate admin by owner', async ({helper}) => {212 const owner = await helper.eth.createAccountWithBalance(donor);213 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');214215 const [newAdmin] = await helper.arrange.createAccounts([10n], donor);216 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);217 await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();218 {219 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);220 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())221 .to.be.eq(newAdmin.address.toLocaleLowerCase());222 }223224 await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();225 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);226 expect(adminList.length).to.be.eq(0);227 });228229 itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => {230 const owner = await helper.eth.createAccountWithBalance(donor);231 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');232233 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);234235 const admin0 = await helper.eth.createAccountWithBalance(donor);236 await collectionEvm.methods.addCollectionAdmin(admin0).send();237 const admin1 = await helper.eth.createAccountWithBalance(donor);238 await collectionEvm.methods.addCollectionAdmin(admin1).send();239240 await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))241 .to.be.rejectedWith('NoPermission');242 {243 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);244 expect(adminList.length).to.be.eq(2);245 expect(adminList.toString().toLocaleLowerCase())246 .to.be.deep.contains(admin0.toLocaleLowerCase())247 .to.be.deep.contains(admin1.toLocaleLowerCase());248 }249 });250251 itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => {252 const owner = await helper.eth.createAccountWithBalance(donor);253 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');254255 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);256257 const admin = await helper.eth.createAccountWithBalance(donor);258 await collectionEvm.methods.addCollectionAdmin(admin).send();259 const notAdmin = helper.eth.createAccount();260261 await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))262 .to.be.rejectedWith('NoPermission');263 {264 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);265 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())266 .to.be.eq(admin.toLocaleLowerCase());267 expect(adminList.length).to.be.eq(1);268 }269 });270271 itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => {272 const owner = await helper.eth.createAccountWithBalance(donor);273 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');274275 const [adminSub] = await helper.arrange.createAccounts([10n], donor);276 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);277 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();278 const adminEth = await helper.eth.createAccountWithBalance(donor);279 await collectionEvm.methods.addCollectionAdmin(adminEth).send();280281 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))282 .to.be.rejectedWith('NoPermission');283284 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);285 expect(adminList.length).to.be.eq(2);286 expect(adminList.toString().toLocaleLowerCase())287 .to.be.deep.contains(adminSub.address.toLocaleLowerCase())288 .to.be.deep.contains(adminEth.toLocaleLowerCase());289 });290291 itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => {292 const owner = await helper.eth.createAccountWithBalance(donor);293 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');294295 const [adminSub] = await helper.arrange.createAccounts([10n], donor);296 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);297 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();298 const notAdminEth = await helper.eth.createAccountWithBalance(donor);299300 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))301 .to.be.rejectedWith('NoPermission');302303 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);304 expect(adminList.length).to.be.eq(1);305 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())306 .to.be.eq(adminSub.address.toLocaleLowerCase());307 });308});309310describe('Change owner tests', () => {311 let donor: IKeyringPair;312313 before(async function() {314 await usingEthPlaygrounds(async (_helper, privateKey) => {315 donor = await privateKey({filename: __filename});316 });317 });318319 itEth('Change owner', async ({helper}) => {320 const owner = await helper.eth.createAccountWithBalance(donor);321 const newOwner = await helper.eth.createAccountWithBalance(donor);322 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');323 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);324325 await collectionEvm.methods.changeCollectionOwner(newOwner).send();326327 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;328 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;329 });330331 itEth('change owner call fee', async ({helper}) => {332 const owner = await helper.eth.createAccountWithBalance(donor);333 const newOwner = await helper.eth.createAccountWithBalance(donor);334 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');335 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);336 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());337 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));338 expect(cost > 0);339 });340341 itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {342 const owner = await helper.eth.createAccountWithBalance(donor);343 const newOwner = await helper.eth.createAccountWithBalance(donor);344 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');345 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);346347 await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;348 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;349 });350});351352describe('Change substrate owner tests', () => {353 let donor: IKeyringPair;354355 before(async function() {356 await usingEthPlaygrounds(async (_helper, privateKey) => {357 donor = await privateKey({filename: __filename});358 });359 });360361 itEth.skip('Change owner', async ({helper}) => {362 const owner = await helper.eth.createAccountWithBalance(donor);363 const [newOwner] = await helper.arrange.createAccounts([10n], donor);364 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');365 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);366367 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;368 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;369370 await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();371372 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;373 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;374 });375376 itEth.skip('change owner call fee', async ({helper}) => {377 const owner = await helper.eth.createAccountWithBalance(donor);378 const [newOwner] = await helper.arrange.createAccounts([10n], donor);379 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');380 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);381382 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());383 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));384 expect(cost > 0);385 });386387 itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {388 const owner = await helper.eth.createAccountWithBalance(donor);389 const otherReceiver = await helper.eth.createAccountWithBalance(donor);390 const [newOwner] = await helper.arrange.createAccounts([10n], donor);391 const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');392 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);393394 await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;395 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;396 });397});