12345678910111213141516import {IKeyringPair} from '@polkadot/types/types';17import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util/playgrounds';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 = privateKey('//Alice');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.createNonfungibleCollection(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.skip('Add substrate admin by owner', async ({helper}) => {53 const owner = await helper.eth.createAccountWithBalance(donor);54 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');55 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);5657 const [newAdmin] = await helper.arrange.createAccounts([10n], donor);58 await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();5960 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);61 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())62 .to.be.eq(newAdmin.address.toLocaleLowerCase());63 });6465 itEth('Verify owner or admin', async ({helper}) => {66 const owner = await helper.eth.createAccountWithBalance(donor);67 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');6869 const newAdmin = helper.eth.createAccount();70 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);71 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;72 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();73 expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;74 });7576 itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => {77 const owner = await helper.eth.createAccountWithBalance(donor);78 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');7980 const admin = await helper.eth.createAccountWithBalance(donor);81 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);82 await collectionEvm.methods.addCollectionAdmin(admin).send();8384 const user = helper.eth.createAccount();85 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))86 .to.be.rejectedWith('NoPermission');8788 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);89 expect(adminList.length).to.be.eq(1);90 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())91 .to.be.eq(admin.toLocaleLowerCase());92 });9394 itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => {95 const owner = await helper.eth.createAccountWithBalance(donor);96 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');9798 const notAdmin = await helper.eth.createAccountWithBalance(donor);99 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);100101 const user = helper.eth.createAccount();102 await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))103 .to.be.rejectedWith('NoPermission');104105 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);106 expect(adminList.length).to.be.eq(0);107 });108109 itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => {110 const owner = await helper.eth.createAccountWithBalance(donor);111 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');112113 const admin = await helper.eth.createAccountWithBalance(donor);114 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);115 await collectionEvm.methods.addCollectionAdmin(admin).send();116117 const [notAdmin] = await helper.arrange.createAccounts([10n], donor);118 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))119 .to.be.rejectedWith('NoPermission');120121 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);122 expect(adminList.length).to.be.eq(1);123 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())124 .to.be.eq(admin.toLocaleLowerCase());125 });126127 itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => {128 const owner = await helper.eth.createAccountWithBalance(donor);129 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');130131 const notAdmin0 = await helper.eth.createAccountWithBalance(donor);132 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);133 const [notAdmin1] = await helper.arrange.createAccounts([10n], donor);134 await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))135 .to.be.rejectedWith('NoPermission');136137 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);138 expect(adminList.length).to.be.eq(0);139 });140});141142describe('Remove collection admins', () => {143 let donor: IKeyringPair;144145 before(async function() {146 await usingEthPlaygrounds(async (_helper, privateKey) => {147 donor = privateKey('//Alice');148 });149 });150151 itEth('Remove admin by owner', async ({helper}) => {152 const owner = await helper.eth.createAccountWithBalance(donor);153 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');154155 const newAdmin = helper.eth.createAccount();156 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);157 await collectionEvm.methods.addCollectionAdmin(newAdmin).send();158159 {160 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);161 expect(adminList.length).to.be.eq(1);162 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())163 .to.be.eq(newAdmin.toLocaleLowerCase());164 }165166 await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();167 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);168 expect(adminList.length).to.be.eq(0);169 });170171 itEth.skip('Remove substrate admin by owner', async ({helper}) => {172 const owner = await helper.eth.createAccountWithBalance(donor);173 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');174175 const [newAdmin] = await helper.arrange.createAccounts([10n], donor);176 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);177 await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();178 {179 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);180 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())181 .to.be.eq(newAdmin.address.toLocaleLowerCase());182 }183184 await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();185 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);186 expect(adminList.length).to.be.eq(0);187 });188189 itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => {190 const owner = await helper.eth.createAccountWithBalance(donor);191 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');192193 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);194195 const admin0 = await helper.eth.createAccountWithBalance(donor);196 await collectionEvm.methods.addCollectionAdmin(admin0).send();197 const admin1 = await helper.eth.createAccountWithBalance(donor);198 await collectionEvm.methods.addCollectionAdmin(admin1).send();199200 await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))201 .to.be.rejectedWith('NoPermission');202 {203 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);204 expect(adminList.length).to.be.eq(2);205 expect(adminList.toString().toLocaleLowerCase())206 .to.be.deep.contains(admin0.toLocaleLowerCase())207 .to.be.deep.contains(admin1.toLocaleLowerCase());208 }209 });210211 itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => {212 const owner = await helper.eth.createAccountWithBalance(donor);213 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');214215 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);216217 const admin = await helper.eth.createAccountWithBalance(donor);218 await collectionEvm.methods.addCollectionAdmin(admin).send();219 const notAdmin = helper.eth.createAccount();220221 await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))222 .to.be.rejectedWith('NoPermission');223 {224 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);225 expect(adminList[0].asEthereum.toString().toLocaleLowerCase())226 .to.be.eq(admin.toLocaleLowerCase());227 expect(adminList.length).to.be.eq(1);228 }229 });230231 itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => {232 const owner = await helper.eth.createAccountWithBalance(donor);233 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');234235 const [adminSub] = await helper.arrange.createAccounts([10n], donor);236 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);237 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();238 const adminEth = await helper.eth.createAccountWithBalance(donor);239 await collectionEvm.methods.addCollectionAdmin(adminEth).send();240241 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))242 .to.be.rejectedWith('NoPermission');243244 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);245 expect(adminList.length).to.be.eq(2);246 expect(adminList.toString().toLocaleLowerCase())247 .to.be.deep.contains(adminSub.address.toLocaleLowerCase())248 .to.be.deep.contains(adminEth.toLocaleLowerCase());249 });250251 itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => {252 const owner = await helper.eth.createAccountWithBalance(donor);253 const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');254255 const [adminSub] = await helper.arrange.createAccounts([10n], donor);256 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);257 await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();258 const notAdminEth = await helper.eth.createAccountWithBalance(donor);259260 await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))261 .to.be.rejectedWith('NoPermission');262263 const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);264 expect(adminList.length).to.be.eq(1);265 expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())266 .to.be.eq(adminSub.address.toLocaleLowerCase());267 });268});269270describe('Change owner tests', () => {271 let donor: IKeyringPair;272273 before(async function() {274 await usingEthPlaygrounds(async (_helper, privateKey) => {275 donor = privateKey('//Alice');276 });277 });278279 itEth('Change owner', async ({helper}) => {280 const owner = await helper.eth.createAccountWithBalance(donor);281 const newOwner = await helper.eth.createAccountWithBalance(donor);282 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');283 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);284285 await collectionEvm.methods.setOwner(newOwner).send();286287 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;288 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;289 });290291 itEth('change owner call fee', async ({helper}) => {292 const owner = await helper.eth.createAccountWithBalance(donor);293 const newOwner = await helper.eth.createAccountWithBalance(donor);294 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');295 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);296 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwner(newOwner).send());297 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));298 expect(cost > 0);299 });300301 itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => {302 const owner = await helper.eth.createAccountWithBalance(donor);303 const newOwner = await helper.eth.createAccountWithBalance(donor);304 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');305 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);306307 await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;308 expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;309 });310});311312describe('Change substrate owner tests', () => {313 let donor: IKeyringPair;314315 before(async function() {316 await usingEthPlaygrounds(async (_helper, privateKey) => {317 donor = privateKey('//Alice');318 });319 });320321 itEth.skip('Change owner', async ({helper}) => {322 const owner = await helper.eth.createAccountWithBalance(donor);323 const [newOwner] = await helper.arrange.createAccounts([10n], donor);324 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');325 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);326327 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;328 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;329330 await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();331332 expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;333 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;334 });335336 itEth.skip('change owner call fee', async ({helper}) => {337 const owner = await helper.eth.createAccountWithBalance(donor);338 const [newOwner] = await helper.arrange.createAccounts([10n], donor);339 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');340 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);341342 const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());343 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));344 expect(cost > 0);345 });346347 itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => {348 const owner = await helper.eth.createAccountWithBalance(donor);349 const otherReceiver = await helper.eth.createAccountWithBalance(donor);350 const [newOwner] = await helper.arrange.createAccounts([10n], donor);351 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');352 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);353354 await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;355 expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;356 });357});