difftreelog
basic test
in: master
3 files changed
tests/src/eth/allowlist.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {expect} from 'chai';19import {isAllowlisted, normalizeAccountId} from '../util/helpers';20import {21 contractHelpers,22 createEthAccount,23 createEthAccountWithBalance,24 deployFlipper,25 evmCollection,26 evmCollectionHelpers,27 getCollectionAddressFromResult,28 itWeb3,29} from './util/helpers';30import {itEth, usingEthPlaygrounds} from './util/playgrounds';3132describe('EVM contract allowlist', () => {33 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {34 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);35 const flipper = await deployFlipper(web3, owner);3637 const helpers = contractHelpers(web3, owner);3839 // Any user is allowed by default40 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;4142 // Enable43 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});44 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.true;4546 // Disable47 await helpers.methods.toggleAllowlist(flipper.options.address, false).send({from: owner});48 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;49 });5051 itWeb3('Non-allowlisted user can\'t call contract with allowlist enabled', async ({api, web3, privateKeyWrapper}) => {52 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);53 const flipper = await deployFlipper(web3, owner);54 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);5556 const helpers = contractHelpers(web3, owner);5758 // User can flip with allowlist disabled59 await flipper.methods.flip().send({from: caller});60 expect(await flipper.methods.getValue().call()).to.be.true;6162 // Tx will be reverted if user is not in allowlist63 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});64 await expect(flipper.methods.flip().send({from: caller})).to.rejected;65 expect(await flipper.methods.getValue().call()).to.be.true;6667 // Adding caller to allowlist will make contract callable again68 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});69 await flipper.methods.flip().send({from: caller});70 expect(await flipper.methods.getValue().call()).to.be.false;71 });72});7374describe('EVM collection allowlist', () => {75 let donor: IKeyringPair;7677 before(async function() {78 await usingEthPlaygrounds(async (_helper, privateKey) => {79 donor = privateKey('//Alice');80 });81 });82 83 itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {84 const owner = await helper.eth.createAccountWithBalance(donor);85 const user = helper.eth.createAccount();86 87 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');88 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);89 90 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;91 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});92 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;93 94 await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});95 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;96 });9798 // TODO: Temprorary off. Need refactor99 // itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {100 // const owner = await helper.eth.createAccountWithBalance(donor);101 // const user = donor;102 103 // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');104 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);105 106 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;107 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});108 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;109 110 // await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});111 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;112 // });113114 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {115 const owner = await helper.eth.createAccountWithBalance(donor);116 const notOwner = await helper.eth.createAccountWithBalance(donor);117 const user = helper.eth.createAccount();118 119 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');120 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);121 122 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;123 await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');124 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;125 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});126 127 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;128 await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');129 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;130 });131132 // TODO: Temprorary off. Need refactor133 // itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {134 // const owner = await helper.eth.createAccountWithBalance(donor);135 // const notOwner = await helper.eth.createAccountWithBalance(donor);136 // const user = donor;137 138 // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');139 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);140 141 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;142 // await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');143 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;144 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});145 146 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;147 // await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');148 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;149 // });150});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';18import {expect} from 'chai';19import {isAllowlisted, normalizeAccountId} from '../util/helpers';20import {21 contractHelpers,22 createEthAccountWithBalance,23 deployFlipper,24 itWeb3,25} from './util/helpers';26import {itEth, usingEthPlaygrounds} from './util/playgrounds';2728describe('EVM contract allowlist', () => {29 itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => {30 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);31 const flipper = await deployFlipper(web3, owner);3233 const helpers = contractHelpers(web3, owner);3435 // Any user is allowed by default36 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;3738 // Enable39 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});40 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.true;4142 // Disable43 await helpers.methods.toggleAllowlist(flipper.options.address, false).send({from: owner});44 expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false;45 });4647 itWeb3('Non-allowlisted user can\'t call contract with allowlist enabled', async ({api, web3, privateKeyWrapper}) => {48 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);49 const flipper = await deployFlipper(web3, owner);50 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);5152 const helpers = contractHelpers(web3, owner);5354 // User can flip with allowlist disabled55 await flipper.methods.flip().send({from: caller});56 expect(await flipper.methods.getValue().call()).to.be.true;5758 // Tx will be reverted if user is not in allowlist59 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});60 await expect(flipper.methods.flip().send({from: caller})).to.rejected;61 expect(await flipper.methods.getValue().call()).to.be.true;6263 // Adding caller to allowlist will make contract callable again64 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});65 await flipper.methods.flip().send({from: caller});66 expect(await flipper.methods.getValue().call()).to.be.false;67 });68});6970describe('EVM collection allowlist', () => {71 let donor: IKeyringPair;7273 before(async function() {74 await usingEthPlaygrounds(async (_helper, privateKey) => {75 donor = privateKey('//Alice');76 });77 });78 79 itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => {80 const owner = await helper.eth.createAccountWithBalance(donor);81 const user = helper.eth.createAccount();82 83 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');84 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);85 86 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;87 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});88 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;89 90 await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner});91 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;92 });9394 // TODO: Temprorary off. Need refactor95 // itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => {96 // const owner = await helper.eth.createAccountWithBalance(donor);97 // const user = donor;98 99 // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');100 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);101 102 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;103 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});104 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;105 106 // await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner});107 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;108 // });109110 itEth('Collection allowlist can not be add and remove [eth] address by not owner', async ({helper}) => {111 const owner = await helper.eth.createAccountWithBalance(donor);112 const notOwner = await helper.eth.createAccountWithBalance(donor);113 const user = helper.eth.createAccount();114 115 const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');116 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);117 118 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;119 await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');120 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false;121 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});122 123 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;124 await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission');125 expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true;126 });127128 // TODO: Temprorary off. Need refactor129 // itEth('Collection allowlist can not be add and remove [sub] address by not owner', async ({helper}) => {130 // const owner = await helper.eth.createAccountWithBalance(donor);131 // const notOwner = await helper.eth.createAccountWithBalance(donor);132 // const user = donor;133 134 // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C');135 // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);136 137 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;138 // await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');139 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;140 // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner});141 142 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;143 // await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission');144 // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;145 // });146});tests/src/eth/proxyContract.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/proxyContract.test.ts
@@ -0,0 +1,124 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {IKeyringPair} from '@polkadot/types/types';
+
+import {itEth, expect, usingEthPlaygrounds, EthUniqueHelper} from './util/playgrounds';
+
+describe('EVM payable contracts', () => {
+ let donor: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (_, privateKey) => {
+ donor = privateKey('//Alice');
+ });
+ });
+
+ itEth('Update proxy contract', async({helper}) => {
+ const deployer = await helper.eth.createAccountWithBalance(donor);
+ const proxyContract = await deployProxyContract(helper, deployer);
+ const realContractV1 = await deployRealContractV1(helper, deployer);
+ await proxyContract.methods.updateVersion(realContractV1.options.address).send();
+ await proxyContract.methods.flip().send();
+ await proxyContract.methods.flip().send();
+ await proxyContract.methods.flip().send();
+ const value1 = await proxyContract.methods.getValue().call();
+ const flipCount1 = await proxyContract.methods.getFlipCount().call();
+ expect(value1).to.be.equal(true);
+ expect(flipCount1).to.be.equal('3');
+ const realContractV2 = await deployRealContractV2(helper, deployer);
+ await proxyContract.methods.updateVersion(realContractV2.options.address).send();
+ await proxyContract.methods.flip().send();
+ await proxyContract.methods.flip().send();
+ const value2 = await proxyContract.methods.getValue().call();
+ const flipCount2 = await proxyContract.methods.getFlipCount().call();
+ expect(value2).to.be.equal(true);
+ expect(flipCount2).to.be.equal('1');
+ });
+
+ async function deployProxyContract(helper: EthUniqueHelper, deployer: string) {
+ return await helper.ethContract.deployByCode(deployer, 'ProxyContract', `
+ // SPDX-License-Identifier: UNLICENSED
+ pragma solidity ^0.8.6;
+
+ contract ProxyContract {
+ address realContract;
+ event NewEvent(uint data);
+ receive() external payable {}
+ constructor() {}
+ function updateVersion(address newContractAddress) external {
+ realContract = newContractAddress;
+ }
+ function flip() external {
+ RealContract(realContract).flip();
+ }
+ function getValue() external view returns (bool) {
+ return RealContract(realContract).getValue();
+ }
+ function getFlipCount() external view returns (uint) {
+ return RealContract(realContract).getFlipCount();
+ }
+ }
+
+ interface RealContract {
+ function flip() external;
+ function getValue() external view returns (bool);
+ function getFlipCount() external view returns (uint);
+ }`);
+ }
+
+ async function deployRealContractV1(helper: EthUniqueHelper, deployer: string) {
+ return await helper.ethContract.deployByCode(deployer, 'RealContractV1', `
+ // SPDX-License-Identifier: UNLICENSED
+ pragma solidity ^0.8.6;
+
+ contract RealContractV1 {
+ bool value = false;
+ uint flipCount = 0;
+ function flip() external {
+ value = !value;
+ flipCount++;
+ }
+ function getValue() external view returns (bool) {
+ return value;
+ }
+ function getFlipCount() external view returns (uint) {
+ return flipCount;
+ }
+ }`);
+ }
+
+ async function deployRealContractV2(helper: EthUniqueHelper, deployer: string) {
+ return await helper.ethContract.deployByCode(deployer, 'RealContractV2', `
+ // SPDX-License-Identifier: UNLICENSED
+ pragma solidity ^0.8.6;
+
+ contract RealContractV2 {
+ bool value = false;
+ uint flipCount = 10;
+ function flip() external {
+ value = !value;
+ flipCount--;
+ }
+ function getValue() external view returns (bool) {
+ return value;
+ }
+ function getFlipCount() external view returns (uint) {
+ return flipCount;
+ }
+ }`);
+ }
+});
\ No newline at end of file
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -71,7 +71,6 @@
},
},
}), {import: await this.findImports(imports)})).contracts[`${name}.sol`][name];
-
return {
abi: out.abi,
object: '0x' + out.evm.bytecode.object,