diff --git a/package.json b/package.json index 204320b79..ca2e0a84e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "lint:all": "npm run lint && npm run lint:sol", "lint:all:fix": "npm run lint:fix && npm run lint:sol:fix", "compile": "truffle compile --optimize-runs 200", - "ganache-cli": "node_modules/.bin/ganache-cli -i 15 --gasLimit 8900000", + "ganache-cli": "node_modules/.bin/ganache-cli -i 15 --gasLimit 90000000", "migrate:local": "truffle migrate --network=development --reset --all", "migrate:ropsten": "truffle migrate --network=ropsten --reset --all", "migrate:mainnet": "truffle migrate --network=mainnet", diff --git a/test/erc20_dividends.js b/test/erc20_dividends.js index a1f6ce7bd..760db1cc9 100644 --- a/test/erc20_dividends.js +++ b/test/erc20_dividends.js @@ -30,6 +30,7 @@ contract('ERC20DividendCheckpoint', accounts => { let account_investor2; let account_investor3; let account_investor4; + let account_temp; // investor Details let fromTime = latestTime(); @@ -60,7 +61,7 @@ contract('ERC20DividendCheckpoint', accounts => { const tokenDetails = "This is equity type of issuance"; const decimals = 18; const contact = "team@polymath.network"; - + let snapId; // Module key const delegateManagerKey = 1; const transferManagerKey = 2; @@ -81,6 +82,7 @@ contract('ERC20DividendCheckpoint', accounts => { account_investor2 = accounts[7]; account_investor3 = accounts[8]; account_investor4 = accounts[9]; + account_temp = accounts[2]; // ----------- POLYMATH NETWORK Configuration ------------ @@ -307,11 +309,82 @@ contract('ERC20DividendCheckpoint', accounts => { ); }); - it("Create new dividend of POLY tokens", async() => { + it("Should fail in creating the dividend", async() => { + let errorThrown = false; let maturity = latestTime(); let expiry = latestTime() + duration.days(10); await I_PolyToken.getTokens(web3.utils.toWei('1.5', 'ether'), token_owner); + try { + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because allowance = 0`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail in creating the dividend", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + try { + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because maturity > expiry`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail in creating the dividend", async() => { + let errorThrown = false; + let maturity = latestTime() - duration.days(2); + let expiry = latestTime() - duration.days(1); + try { + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because now > expiry`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail in creating the dividend", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + try { + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, 0, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because token address is 0x`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail in creating the dividend", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() + duration.days(10); + try { + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, 0, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because amount < 0`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Create new dividend of POLY tokens", async() => { + let maturity = latestTime() + duration.days(1); + let expiry = latestTime() + duration.days(10); + let tx = await I_ERC20DividendCheckpoint.createDividend(maturity, expiry, I_PolyToken.address, web3.utils.toWei('1.5', 'ether'), {from: token_owner}); assert.equal(tx.logs[0].args._checkpointId.toNumber(), 1, "Dividend should be created at checkpoint 1"); }); @@ -323,9 +396,48 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let errorThrown = false; + try { + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because dividend index has maturity in future`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let errorThrown = false; + // Increase time by 2 day + await increaseTime(duration.days(2)); + try { + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: account_temp}); + } catch(error) { + console.log(` tx -> failed because msg.sender is not the owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let errorThrown = false; + try { + await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because dividend index is greator than the dividend array length`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let _dev = await I_ERC20DividendCheckpoint.dividends.call(0); let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner, gas: 5000000}); let investor1BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter = BigNumber(await I_PolyToken.balanceOf(account_investor2)); assert.equal(investor1BalanceAfter.sub(investor1Balance).toNumber(), web3.utils.toWei('0.5', 'ether')); @@ -334,6 +446,36 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal((await I_ERC20DividendCheckpoint.dividends(0))[6].toNumber(), web3.utils.toWei('1.5', 'ether')); }); + it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + let errorThrown = false; + await increaseTime(duration.days(11)); + try { + await I_ERC20DividendCheckpoint.pushDividendPayment(0, 0, 10, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because dividend index has passed its expiry`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + // it("Issuer pushes dividends iterating over account holders - dividends proportional to checkpoint", async() => { + // let errorThrown = false; + // let tx = await I_ERC20DividendCheckpoint.reclaimDividend(0,{from: token_owner, gas: 500000}); + // assert.equal((tx.logs[0].args._claimedAmount).toNumber(), web3.utils.toWei("1.5", "ether")); + // try { + // await I_ERC20DividendCheckpoint.pushDividendPayment(2, 0, 10, {from: token_owner}); + // } catch(error) { + // console.log(` tx -> failed because dividend index has already reclaimed`.grey); + // ensureException(error); + // errorThrown = true; + // } + // assert.ok(errorThrown, message); + // await revertToSnapshot(snapId); + // }); + + + it("Buy some tokens for account_investor3 (7 ETH)", async() => { // Add the Investor in to the whitelist @@ -368,7 +510,22 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(tx.logs[0].args._checkpointId.toNumber(), 2, "Dividend should be created at checkpoint 2"); }); - it("Investor 3 claims dividend, issuer pushes remainder", async() => { + it("should investor 3 claims dividend", async() => { + let errorThrown = false; + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + try { + await I_ERC20DividendCheckpoint.pullDividendPayment(5, {from: account_investor3, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because dividend index is not valid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("should investor 3 claims dividend", async() => { let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); @@ -379,7 +536,24 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), 0); assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), web3.utils.toWei('7', 'ether')); + }); + it("should investor 3 claims dividend", async() => { + let errorThrown = false; + try { + await I_ERC20DividendCheckpoint.pullDividendPayment(1, {from: account_investor3, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because investor already claimed the dividend`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("should investor 3 claims dividend", async() => { + let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); await I_ERC20DividendCheckpoint.pushDividendPayment(1, 0, 10, {from: token_owner}); let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); @@ -391,11 +565,71 @@ contract('ERC20DividendCheckpoint', accounts => { assert.equal((await I_ERC20DividendCheckpoint.dividends(1))[6].toNumber(), web3.utils.toWei('10', 'ether')); }); - it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { - await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); - assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); - assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + // it("Investor 2 transfers 1 ETH of his token balance to investor 1", async() => { + // console.log(await I_SecurityToken.balanceOf(account_investor2)); + // await I_SecurityToken.transfer(account_investor1, web3.utils.toWei('1', 'ether'), {from: account_investor2}); + // assert.equal(await I_SecurityToken.balanceOf(account_investor1), web3.utils.toWei('1', 'ether')); + // assert.equal(await I_SecurityToken.balanceOf(account_investor2), web3.utils.toWei('2', 'ether')); + // assert.equal(await I_SecurityToken.balanceOf(account_investor3), web3.utils.toWei('7', 'ether')); + // }); + + it("Create another new dividend with explicit", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + let tx = await I_SecurityToken.createCheckpoint({from: token_owner}); + await I_PolyToken.getTokens(web3.utils.toWei('20', 'ether'), token_owner); + try { + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 3, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because allowance is not provided`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Create another new dividend with explicit", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() - duration.days(10); + await I_PolyToken.approve(I_ERC20DividendCheckpoint.address, web3.utils.toWei('20', 'ether'), {from: token_owner}); + try { + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 3, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because maturity > expiry`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Create another new dividend with explicit", async() => { + let errorThrown = false; + let maturity = latestTime() - duration.days(5); + let expiry = latestTime() - duration.days(2); + try { + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 3, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because now > expiry`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Create another new dividend with explicit", async() => { + let errorThrown = false; + let maturity = latestTime(); + let expiry = latestTime() + duration.days(2); + try { + tx = await I_ERC20DividendCheckpoint.createDividendWithCheckpoint(maturity, expiry, I_PolyToken.address, web3.utils.toWei('20', 'ether'), 5, {from: token_owner}); + } catch(error) { + console.log(` tx -> failed because checkpoint id > current checkpoint`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); }); it("Create another new dividend with explicit", async() => { @@ -409,28 +643,60 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Investor 2 claims dividend, issuer pushes investor 1", async() => { + let errorThrown = false; let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - await I_ERC20DividendCheckpoint.pullDividendPayment(2, {from: account_investor2, gasPrice: 0}); - let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), 0); - assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('4', 'ether')); - assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + try { + await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2, account_investor1],{from: account_investor2, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because not called by the owner`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); - await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor1], {from: token_owner}); - let investor1BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); - let investor2BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); - let investor3BalanceAfter2 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); - assert.equal(investor1BalanceAfter2.sub(investor1BalanceAfter1).toNumber(), web3.utils.toWei('2', 'ether')); - assert.equal(investor2BalanceAfter2.sub(investor2BalanceAfter1).toNumber(), 0); - assert.equal(investor3BalanceAfter2.sub(investor3BalanceAfter1).toNumber(), 0); - //Check fully claimed - assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[6].toNumber(), web3.utils.toWei('6', 'ether')); + it("Investor 2 claims dividend, issuer pushes investor 1", async() => { + let errorThrown = false; + let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + try { + await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(5, [account_investor2, account_investor1],{from: token_owner, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because dividend index is not valid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("should calculate dividend before the push dividend payment", async() => { + let dividendAmount = await I_ERC20DividendCheckpoint.calculateDividend.call(2, account_investor2); + assert.equal(dividendAmount.toNumber(), web3.utils.toWei("6", "ether")); }); + // it("Investor 2 claims dividend, issuer pushes investor 1", async() => { + // let investor1Balance = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + // let investor2Balance = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + // let investor3Balance = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + // await I_ERC20DividendCheckpoint.pushDividendPaymentToAddresses(2, [account_investor2],{from: account_investor2, gasPrice: 0}); + // let investor1BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor1)); + // let investor2BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor2)); + // let investor3BalanceAfter1 = BigNumber(await I_PolyToken.balanceOf(account_investor3)); + // //assert.equal(investor1BalanceAfter1.sub(investor1Balance).toNumber(), web3.utils.toWei('2', 'ether')) + // assert.equal(investor2BalanceAfter1.sub(investor2Balance).toNumber(), web3.utils.toWei('6', 'ether')); + // assert.equal(investor3BalanceAfter1.sub(investor3Balance).toNumber(), 0); + // //Check fully claimed + // assert.equal((await I_ERC20DividendCheckpoint.dividends(2))[6].toNumber(), web3.utils.toWei('6', 'ether')); + // }); + + // it("should calculate dividend after the push dividend payment", async() => { + // let dividendAmount = await I_ERC20DividendCheckpoint.calculateDividend.call(2, account_investor2); + // assert.equal(dividendAmount.toNumber(), 0); + // }); + it("Issuer unable to reclaim dividend (expiry not passed)", async() => { let errorThrown = false; try { @@ -444,11 +710,37 @@ contract('ERC20DividendCheckpoint', accounts => { }); it("Issuer is able to reclaim dividend after expiry", async() => { + let errorThrown = false; await increaseTime(11 * 24 * 60 * 60); + try { + await I_ERC20DividendCheckpoint.reclaimDividend(8, {from: token_owner, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because dividend index is not valid`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); await I_ERC20DividendCheckpoint.reclaimDividend(2, {from: token_owner, gasPrice: 0}); let tokenOwnerAfter = BigNumber(await I_PolyToken.balanceOf(token_owner)); - assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('14', 'ether')); + //assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('14', 'ether')); + assert.equal(tokenOwnerAfter.sub(tokenOwnerBalance).toNumber(), web3.utils.toWei('20', 'ether')); + }); + + it("Issuer is able to reclaim dividend after expiry", async() => { + let errorThrown = false; + let tokenOwnerBalance = BigNumber(await I_PolyToken.balanceOf(token_owner)); + try { + await I_ERC20DividendCheckpoint.reclaimDividend(2, {from: token_owner, gasPrice: 0}); + } catch(error) { + console.log(` tx -> failed because dividend are already reclaimed`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); }); it("Investor 3 unable to pull dividend after expiry", async() => { @@ -465,14 +757,46 @@ contract('ERC20DividendCheckpoint', accounts => { }); - describe("Test cases for the factory", async() => { - it("should get the details of the factory", async() => { - assert.equal(await I_ERC20DividendCheckpointFactory.setupCost.call(),0); - assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(),4); + it("Should give the right dividend index", async() => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(3); + assert.equal(index[0], 2); + }); + + it("Should give the right dividend index", async() => { + let index = await I_ERC20DividendCheckpoint.getDividendIndex.call(8); + assert.equal(index.length, 0); + }); + + it("Get the init data", async() => { + let tx = await I_ERC20DividendCheckpoint.getInitFunction.call(); + assert.equal(web3.utils.toAscii(tx).replace(/\u0000/g, ''),0); + }); + + it("Should get the listed permissions", async() => { + let tx = await I_ERC20DividendCheckpoint.getPermissions.call(); + assert.equal(tx.length,0); + }); + + describe("Test cases for the ERC20DividendCheckpointFactory", async() => { + it("should get the exact details of the factory", async() => { + assert.equal((await I_ERC20DividendCheckpointFactory.setupCost.call()).toNumber(), 0); + assert.equal(await I_ERC20DividendCheckpointFactory.getType.call(), 4); assert.equal(web3.utils.toAscii(await I_ERC20DividendCheckpointFactory.getName.call()) .replace(/\u0000/g, ''), "ERC20DividendCheckpoint", "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getDescription.call(), + "Create ERC20 dividends for token holders at a specific checkpoint", + "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getTitle.call(), + "ERC20 Dividend Checkpoint", + "Wrong Module added"); + assert.equal(await I_ERC20DividendCheckpointFactory.getInstructions.call(), + "Create a ERC20 dividend which will be paid out to token holders proportional to their balances at the point the dividend is created", + "Wrong Module added"); + let tags = await I_ERC20DividendCheckpointFactory.getTags.call(); + assert.equal(tags.length, 0); + }); }); diff --git a/test/manual_approval_transfer_manager.js b/test/manual_approval_transfer_manager.js index 54b66dc56..46d6cddb0 100644 --- a/test/manual_approval_transfer_manager.js +++ b/test/manual_approval_transfer_manager.js @@ -234,11 +234,7 @@ contract('ManualApprovalTransferManager', accounts => { // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._type.toNumber(), 2); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); LogAddModule.stopWatching(); }); @@ -314,12 +310,7 @@ contract('ManualApprovalTransferManager', accounts => { it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "ManualApprovalTransferManager", - "ManualApprovalTransferManager module was not added" - ); + assert.equal(web3.utils.toUtf8(tx.logs[2].args._name), "ManualApprovalTransferManager", "ManualApprovalTransferManager module was not added"); I_ManualApprovalTransferManager = ManualApprovalTransferManager.at(tx.logs[2].args._module); }); @@ -359,10 +350,78 @@ contract('ManualApprovalTransferManager', accounts => { ); }); + it("Should fail to add a manual approval because invalid _from address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualApproval("", account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _from address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to add a manual approval because invalid _to address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualApproval(account_investor1, "", web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _to address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to add a manual approval because invalid expiry time", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), 99999, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid expiry time`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + it("Add a manual approval for a 4th investor", async() => { await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); }); + it("Should fail to revoke manual approval because invalid _from address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.revokeManualApproval("", account_investor4, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _from address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to revoke manual approval because invalid _to address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, "", { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _to address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should revoke manual approval", async() => { + let tx = await I_ManualApprovalTransferManager.revokeManualApproval(account_investor1, account_investor4, { from: token_owner }); + assert.equal(tx.logs[0].args._from, account_investor1); + assert.equal(tx.logs[0].args._to, account_investor4); + assert.equal(tx.logs[0].args._addedBy, token_owner); + await I_ManualApprovalTransferManager.addManualApproval(account_investor1, account_investor4, web3.utils.toWei('2', 'ether'), latestTime() + duration.days(1), { from: token_owner }); + }); + it("Use 50% of manual approval for transfer", async() => { await I_SecurityToken.transfer(account_investor4, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); @@ -410,6 +469,42 @@ contract('ManualApprovalTransferManager', accounts => { }); + it("Should fail to add a manual block because invalid _from address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualBlocking("", account_investor2, latestTime() + duration.days(1), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _from address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to add a manual block because invalid _to address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, "", latestTime() + duration.days(1), { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _to address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to add a manual block because invalid expiry time", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, 99999, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid expiry time`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + it("Add a manual block for a 2nd investor", async() => { await I_ManualApprovalTransferManager.addManualBlocking(account_investor1, account_investor2, latestTime() + duration.days(1), { from: token_owner }); }); @@ -427,6 +522,30 @@ contract('ManualApprovalTransferManager', accounts => { }); + it("Should fail to revoke manual block because invalid _from address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.revokeManualBlocking("0x0", account_investor2, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _from address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + + it("Should fail to revoke manual block because invalid _to address", async() => { + let errorThrown = false; + try { + await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, "0x0", { from: token_owner }); + } catch(error) { + console.log(` tx revert -> invalid _to address`.grey); + ensureException(error); + errorThrown = true; + } + assert.ok(errorThrown, message); + }); + it("Revoke manual block and check transfer works", async() => { await I_ManualApprovalTransferManager.revokeManualBlocking(account_investor1, account_investor2, { from: token_owner }); await I_SecurityToken.transfer(account_investor2, web3.utils.toWei('1', 'ether'), { from: account_investor1 }); @@ -464,16 +583,16 @@ contract('ManualApprovalTransferManager', accounts => { const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._type.toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[2].args._name) - .replace(/\u0000/g, ''), - "CountTransferManager", - "CountTransferManager module was not added" - ); + let name = web3.utils.toUtf8(tx.logs[2].args._name); + assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); I_CountTransferManager = CountTransferManager.at(tx.logs[2].args._module); }); + it("Should get the permission list", async() => { + let perm = await I_ManualApprovalTransferManager.getPermissions.call(); + assert.equal(perm.length, 1); + }); // it("Check manual approval has a higher priority than an INVALID result from another TM", async() => { // //Should fail initial transfer @@ -497,15 +616,19 @@ contract('ManualApprovalTransferManager', accounts => { it("Should get the exact details of the factory", async() => { assert.equal(await I_ManualApprovalTransferManagerFactory.setupCost.call(),0); assert.equal(await I_ManualApprovalTransferManagerFactory.getType.call(),2); - assert.equal(web3.utils.toAscii(await I_ManualApprovalTransferManagerFactory.getName.call()) - .replace(/\u0000/g, ''), - "ManualApprovalTransferManager", - "Wrong Module added"); + let name = web3.utils.toUtf8(await I_ManualApprovalTransferManagerFactory.getName.call()); + assert.equal(name,"ManualApprovalTransferManager","Wrong Module added"); + let desc = await I_ManualApprovalTransferManagerFactory.getDescription.call(); + assert.equal(desc,"Manage transfers using single approvals / blocking","Wrong Module added"); + let title = await I_ManualApprovalTransferManagerFactory.getTitle.call(); + assert.equal(title,"Manual Approval Transfer Manager","Wrong Module added"); + let inst = await I_ManualApprovalTransferManagerFactory.getInstructions.call(); + assert.equal(inst,"Allows an issuer to set manual approvals or blocks for specific pairs of addresses and amounts. Init function takes no parameters.","Wrong Module added"); }); it("Should get the tags of the factory", async() => { let tags = await I_ManualApprovalTransferManagerFactory.getTags.call(); - assert.equal(web3.utils.toAscii(tags[0]).replace(/\u0000/g, ''), "ManualApproval"); + assert.equal(web3.utils.toUtf8(tags[0]), "ManualApproval"); }); }); diff --git a/test/module_registry.js b/test/module_registry.js index 32e2f8599..1362830b4 100644 --- a/test/module_registry.js +++ b/test/module_registry.js @@ -204,7 +204,21 @@ contract('ModuleRegistry', accounts => { describe("Test cases of register module", async() => { - it("Should succssfully registered the module", async() => { + it("Should fail to register module if registration is paused", async() => { + let errorThrown = false; + try { + await I_ModuleRegistry.pause({ from: account_polymath}); + await I_ModuleRegistry.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); + } catch(error) { + console.log(` tx revert -> Registration is paused`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should succssfully register the module", async() => { + await I_ModuleRegistry.unpause({ from: account_polymath}); let tx = await I_ModuleRegistry.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); assert.equal( diff --git a/test/security_token.js b/test/security_token.js index a147bd9c9..9b8a06a4f 100644 --- a/test/security_token.js +++ b/test/security_token.js @@ -269,11 +269,7 @@ contract('SecurityToken', accounts => { // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._type.toNumber(), transferManagerKey); - assert.equal( - web3.utils.toAscii(log.args._name) - .replace(/\u0000/g, ''), - "GeneralTransferManager" - ); + assert.equal(web3.utils.toUtf8(log.args._name),"GeneralTransferManager"); LogAddModule.stopWatching(); }); @@ -385,6 +381,38 @@ contract('SecurityToken', accounts => { await revertToSnapshot(id); }); + it("Should fail to attach the STO factory because not enough poly in contract", async () => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + let errorThrown = false; + try { + let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, true, { from: token_owner, gas: 60000000 }); + } catch (error) { + console.log(` tx revert -> not enough poly in contract`); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should fail to attach the STO factory because max cost too small", async () => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner}); + let errorThrown = false; + try { + let tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, web3.utils.toWei("1000","ether"), 0, true, { from: token_owner, gas: 60000000 }); + } catch (error) { + console.log(` tx revert -> max cost too small`); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + it("Should successfully attach the STO factory with the security token", async () => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); @@ -396,14 +424,44 @@ contract('SecurityToken', accounts => { const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, true, { from: token_owner, gas: 60000000 }); assert.equal(tx.logs[3].args._type, stoKey, "CappedSTO doesn't get deployed"); - assert.equal( - web3.utils.toAscii(tx.logs[3].args._name) - .replace(/\u0000/g, ''), - "CappedSTO", - "CappedSTOFactory module was not added" - ); + assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); }); + + }); + + describe("Upgradability functions", async() => { + + it("Should fail to change the security token registry address because address(0)", async() => { + let errorThrown = false; + try { + let tx = await I_SecurityToken.changeSecurityTokenRegistryAddress("0x0000000000000000000000000000000000000000", { from: token_owner }); + } catch (error) { + console.log(` tx revert -> msg.sender should be the owner of the token`); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should fail to change the security token registry address because same address", async() => { + let errorThrown = false; + try { + let tx = await I_SecurityToken.changeSecurityTokenRegistryAddress(I_SecurityTokenRegistry.address, { from: token_owner }); + } catch (error) { + console.log(` tx revert -> msg.sender should be the owner of the token`); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should successfully change the STR address", async() => { + let tx = await I_SecurityToken.changeSecurityTokenRegistryAddress("0x0000000000000000000000000000000000000001", { from: token_owner }); + assert.equal(tx.logs[0].args._newAddress, "0x0000000000000000000000000000000000000001") + await I_SecurityToken.changeSecurityTokenRegistryAddress(I_SecurityTokenRegistry.address, { from: token_owner }); + }); + }); describe("Module related functions", async() => { @@ -447,7 +505,7 @@ contract('SecurityToken', accounts => { try { let log = await I_SecurityToken.updateTokenDetails("new token details", {from: account_delegate}); } catch (error) { - console.log(`msg.sender should be the owner of the token`); + console.log(` tx revert -> msg.sender should be the owner of the token`); errorThrown = true; ensureException(error); } diff --git a/test/security_token_registry.js b/test/security_token_registry.js index fabd2e49f..96817ab60 100644 --- a/test/security_token_registry.js +++ b/test/security_token_registry.js @@ -252,7 +252,22 @@ contract('SecurityTokenRegistry', accounts => { assert.ok(errorThrown, message); }); + it("Should fail to generate token if registration is paused", async() => { + let errorThrown = false; + try { + await I_SecurityTokenRegistry.pause({ from: account_polymath}); + await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner}); + await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); + } catch(error) { + console.log(` tx revert -> Registration is paused`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + it("Should generate the new security token with the same symbol as registered above", async () => { + await I_SecurityTokenRegistry.unpause({ from: account_polymath}); await I_PolyToken.approve(I_SecurityTokenRegistry.address, initRegFee, { from: token_owner}); let tx = await I_SecurityTokenRegistry.generateSecurityToken(name, symbol, tokenDetails, false, { from: token_owner, gas:60000000 }); @@ -334,7 +349,7 @@ contract('SecurityTokenRegistry', accounts => { describe("Generate custom tokens", async() => { - it("Should fail in adding the new custom token in the polymath network", async() => { + it("Should fail if msg.sender is not polymath", async() => { let errorThrown = false; try { await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_delegate}); @@ -346,43 +361,54 @@ contract('SecurityTokenRegistry', accounts => { assert.ok(errorThrown, message); }); - it("Should fail in adding the new custom token in the polymath network", async() => { + it("Should fail if registration is paused", async() => { let errorThrown = false; try { - await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", "Swarm hash", {from: account_polymath}); + await I_SecurityTokenRegistry.pause({ from: account_polymath}); + await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); } catch(error) { - console.log(` tx revert -> Security token address is 0`.grey); + console.log(` tx revert -> Registration is paused`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); }); - it("Should fail in adding the new custom token in the polymath network", async() => { + it("Should successfully generate token if registration is unpaused", async() => { + await I_SecurityTokenRegistry.unpause({ from: account_polymath}); + let tx = await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN2", "LOG2", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); + assert.equal(tx.logs[0].args._symbol, "LOG2"); + assert.equal(tx.logs[0].args._securityToken, dummy_token); + let symbolDetails = await I_TickerRegistry.getDetails("LOG2"); + assert.equal(symbolDetails[0], account_temp); + assert.equal(symbolDetails[2], "LOGAN2"); + }); + + it("Should fail if ST address is 0 address", async() => { let errorThrown = false; try { - await I_SecurityTokenRegistry.addCustomSecurityToken("", "", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); + await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, 0, "I am custom ST", "Swarm hash", {from: account_polymath}); } catch(error) { - console.log(` tx revert -> Symbol and name of zero length`.grey); + console.log(` tx revert -> Security token address is 0`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); }); - it("Should fail in adding the new custom token in the polymath network", async() => { + it("Should fail if symbol or name of length 0", async() => { let errorThrown = false; try { - await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_delegate}); + await I_SecurityTokenRegistry.addCustomSecurityToken("", "", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); } catch(error) { - console.log(` tx revert -> msg.sender is not polymath account`.grey); + console.log(` tx revert -> Symbol and name of zero length`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); }); - it("Should fail in adding the new custom token in the polymath network", async() => { + it("Should fail if symbol is reserved", async() => { let errorThrown = false; try { await I_SecurityTokenRegistry.addCustomSecurityToken(name2, symbol2, account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); @@ -394,7 +420,7 @@ contract('SecurityTokenRegistry', accounts => { assert.ok(errorThrown, message); }); - it("Should Add the new custom token in the polymath network", async() => { + it("Should successfully generate the custom token", async() => { let tx = await I_SecurityTokenRegistry.addCustomSecurityToken("LOGAN", "LOG", account_temp, dummy_token, "I am custom ST", "Swarm hash", {from: account_polymath}); assert.equal(tx.logs[0].args._symbol, "LOG"); assert.equal(tx.logs[0].args._securityToken, dummy_token); diff --git a/test/ticker_registry.js b/test/ticker_registry.js index 230bb674e..558829542 100644 --- a/test/ticker_registry.js +++ b/test/ticker_registry.js @@ -265,6 +265,53 @@ contract('TickerRegistry', accounts => { assert.equal(tx.logs[0].args._owner, account_temp); assert.equal(tx.logs[0].args._symbol, symbol); }); + + it("Should fail to register ticker if registration is paused", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.pause({ from: account_polymath}); + await I_PolyToken.approve(I_TickerRegistry.address, initRegFee, { from: token_owner}); + let tx = await I_TickerRegistry.registerTicker(token_owner, "AAA", name, swarmHash, { from: token_owner }); + } catch(error) { + console.log(` tx revert -> Registration is paused`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should fail to pause if already paused", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.pause({ from: account_polymath}); + } catch(error) { + console.log(` tx revert -> Registration is already paused`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should successfully register ticker if registration is unpaused", async() => { + await I_TickerRegistry.unpause({ from: account_polymath}); + await I_PolyToken.approve(I_TickerRegistry.address, initRegFee, { from: token_owner}); + let tx = await I_TickerRegistry.registerTicker(token_owner, "AAA", name, swarmHash, { from: token_owner }); + assert.equal(tx.logs[0].args._owner, token_owner); + assert.equal(tx.logs[0].args._symbol, "AAA"); + }); + + it("Should fail to unpause if already unpaused", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.unpause({ from: account_polymath}); + } catch(error) { + console.log(` tx revert -> Registration is already unpaused`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + }); describe("Test cases for the expiry limit", async() => { @@ -346,6 +393,22 @@ contract('TickerRegistry', accounts => { }); }); + describe("Test cases for isReserved", async() => { + + it("Should fail to check if reserved because msg.sender is not STR", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.isReserved(symbol, account_temp, name, swarmHash, {from: accounts[9]}); + } catch(error) { + console.log(` tx revert -> msg.sender is not the STR`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + }); + describe("Test cases for IRegistry functionality", async() => { describe("Test cases for changePolyRegisterationFee", async() => { @@ -367,6 +430,18 @@ contract('TickerRegistry', accounts => { assert.ok(errorThrown, message); }); + it("Should fail to change the registration fee if fee is equivalent", async() => { + let errorThrown = false; + try { + let tx = await I_TickerRegistry.changePolyRegisterationFee(initRegFee, { from: account_polymath }); + } catch(error) { + console.log(` tx revert -> Failed to change registrationFee`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + it("Should successfully change the registration fee", async() => { await I_TickerRegistry.changePolyRegisterationFee(400 * Math.pow(10, 18), { from: account_polymath }); let fee = await I_TickerRegistry.registrationFee.call(); @@ -385,6 +460,30 @@ contract('TickerRegistry', accounts => { assert.isAbove(bal2, bal1); }); + it("Should fail to reclaim tokens if address provided is 0 address", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.reclaimERC20("0x0000000000000000000000000000000000000000"); + } catch(error) { + console.log(` tx revert -> Address provided is address(0)`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + + it("Should fail to reclaim tokens if token transfer fails", async() => { + let errorThrown = false; + try { + await I_TickerRegistry.reclaimERC20("0x0000000000000000000000000000000000000001"); + } catch(error) { + console.log(` tx revert -> Address provided is address(0)`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + }); + }); describe("Test cases for changing contract address reference", async() => {