diff --git a/.solcover.js b/.solcover.js index 59d2ab5..379b456 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,7 +1,7 @@ module.exports = { port: 8555, norpc: true, - testCommand: 'GEN_TESTS_TIMEOUT=400 GEN_TESTS_QTY=40 truffle test --network coverage test/QiibeeToken.js test/QiibeeCrowdsale.js test/QiibeePresale.js test/WhitelistedCrowdsale.js test/QiibeePresaleGenTest.js test/QiibeeCrowdsaleGenTest.js', + testCommand: 'GEN_TESTS_TIMEOUT=400 GEN_TESTS_QTY=40 truffle test --network coverage test/QiibeeCrowdsale.js test/QiibeePresale.js test/QiibeeToken.js test/WhitelistedCrowdsale.js test/QiibeePresaleGenTest.js test/QiibeeCrowdsaleGenTest.js', copyNodeModules: true, skipFiles: [ 'test-helpers/Message.sol', diff --git a/test/QiibeePresaleGenTest.js b/test/QiibeePresaleGenTest.js index 9697cc8..32dab9f 100644 --- a/test/QiibeePresaleGenTest.js +++ b/test/QiibeePresaleGenTest.js @@ -1,6 +1,6 @@ var _ = require('lodash'); var colors = require('colors'); -var jsc = require('jsverify'); +// var jsc = require('jsverify'); var BigNumber = web3.BigNumber; @@ -28,10 +28,10 @@ contract('QiibeePresale property-based test', function(accounts) { const zero = new BigNumber(0); - let presaleTestInputGen = jsc.record({ - commands: jsc.array(jsc.nonshrink(commands.presaleCommandsGen)), - presale: jsc.nonshrink(gen.presaleGen) - }); + // let presaleTestInputGen = jsc.record({ + // commands: jsc.array(jsc.nonshrink(commands.presaleCommandsGen)), + // presale: jsc.nonshrink(gen.presaleGen) + // }); let sumBigNumbers = (arr) => _.reduce(arr, (accum, x) => accum.plus(x), zero); @@ -180,476 +180,477 @@ contract('QiibeePresale property-based test', function(accounts) { { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, { type: 'finalizePresale', fromAccount: 0 } ], - presale: { + presale: + { rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000, foundationWallet: 10, owner: 0 } }); }); - describe('tokens distribution', function () { - - it('can distribute tokens after fundraising has finished (now >= endTime)', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - { type: 'finalizePresale', fromAccount: 0 } - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can distribute non-vested tokens', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 0, vesting: 0, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can distribute tokens after fundraising has finished (weiRaised = cap)', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 240000, fromAccount: 0 }, - { type: 'presaleBuyTokens', account: 4, beneficiary: 5, eth: 240000 }, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute tokens if presale has finished', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(3)}, - { type: 'finalizePresale', fromAccount: 0 }, - { type: 'distributeTokens', beneficiary: 1, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute tokens with zero beneficiary', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 'zero', amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute 0 tokens', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 1, amount: 0, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute tokens with vesting less than cliff', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 1, amount: 1, cliff: 6000, vesting: 5000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute tokens before or during fundraising', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute more tokens than the distribution cap', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 4, amount: 75000000, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('can NOT distribute tokens if not owner', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(2)}, - { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - }); - - describe('buying tokens', function () { - - it('should NOT allow non-accredited investors to invest', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'presaleSendTransaction', account: 4, eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should allow accredited investors to buy tokens', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleSendTransaction', account: 4, eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT allow to buy tokens with address zero ', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleSendTransaction', account: 'zero', eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should allow accredited investors to buy tokens with cliff zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 0, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleSendTransaction', account: 4, eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should allow accredited investors to buy non-vested tokens', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 0, vesting: 0, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleSendTransaction', account: 4, eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should allow accredited investors to buy non-vested tokens', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 0, vesting: 0, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleBuyTokens', account: 4, beneficiary: 5, eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT allow accredited investors to invest more than maxCumulativeInvest', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleBuyTokens', beneficiary: 3, account: 4, eth: 3 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT allow accredited investors to invest more than maxCumulativeInvest', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 20, fromAccount: 0 }, - { type: 'presaleBuyTokens', beneficiary: 5, account: 4, eth: 10 }, - { type: 'waitTime','seconds':duration.seconds(3)}, - { type: 'presaleBuyTokens', beneficiary: 6, account: 4, eth: 10 }, - { type: 'waitTime','seconds':duration.seconds(3)}, - { type: 'presaleBuyTokens', beneficiary: 7, account: 4, eth: 10 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 1, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT allow accredited investors to invest less than minInvest', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - { type: 'presaleBuyTokens', beneficiary: 3, account: 4, eth: 0.5 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT allow buying tokens with zero beneficiary address', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'presaleBuyTokens', account: 4, beneficiary: 'zero', eth: 1 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - }); - - describe('add to accredited list', function () { - - it('should NOT be able to add investor to accredited list with rate zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, rate: 0, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to add investor to accredited list with vesting less than cliff', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 100, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should be able to add investor to accredited list with zero cliff', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 0, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to add investor to accredited list with maxCumulativeInvest zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 0, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to add investor to accredited list with minInvest zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 0, maxCumulativeInvest: 2, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to add investor to accredited list if not owner', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 2 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to add investor to accredited list if address is zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'addAccredited', investor: 'zero', rate: 6000, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should be able to remove investor from accredited list', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'removeAccredited', investor: 4, fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to remove investor from accredited list if not owner', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'removeAccredited', investor: 4, fromAccount: 2 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - it('should NOT be able to remove investor from accredited list if address is zero', async function () { - await runGeneratedPresaleAndCommands({ - commands: [ - { type: 'waitTime','seconds':duration.days(1)}, - { type: 'removeAccredited', investor: 'zero', fromAccount: 0 }, - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }); - }); - - }); - - describe('stateful prob based tests', function () { - - it('distributes tokens correctly on any combination of bids', async function() { - // stateful prob based tests can take a long time to finish when shrinking... - this.timeout(GEN_TESTS_TIMEOUT * 1000); - - let property = jsc.forall(presaleTestInputGen, async function(presaleAndCommands) { - return await runGeneratedPresaleAndCommands(presaleAndCommands); - }); - - return jsc.assert(property, {tests: GEN_TESTS_QTY}); - }); - - }); - - describe('finalize presale', function () { - - it('should finish presale fine', async function() { - let presaleAndCommands = { - commands: [ - { type: 'waitTime','seconds':duration.days(4)}, - { type: 'finalizePresale', fromAccount: 0 } - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }; - - await runGeneratedPresaleAndCommands(presaleAndCommands); - }); - - it('should NOT finish presale if called by non-owner', async function() { - let presaleAndCommands = { - commands: [ - { type: 'waitTime','seconds':duration.days(4)}, - { type: 'finalizePresale', fromAccount: 0 } - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 1 - } - }; - - await runGeneratedPresaleAndCommands(presaleAndCommands); - }); - - it('should NOT finish presale if it has already been finalized', async function() { - let presaleAndCommands = { - commands: [ - { type: 'waitTime','seconds':duration.days(4)}, - { type: 'finalizePresale', fromAccount: 0 }, - { type: 'finalizePresale', fromAccount: 0 } - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }; - - await runGeneratedPresaleAndCommands(presaleAndCommands); - }); - - it('should handle the exception correctly when trying to finalize the presale before the presale has ended', async function() { - let presaleAndCommands = { - commands: [ - { type: 'waitTime','seconds':duration.minutes(60)}, - { type: 'finalizePresale', fromAccount: 0 } - ], - presale: { - rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 - } - }; - - await runGeneratedPresaleAndCommands(presaleAndCommands); - }); - - }); + // describe('tokens distribution', function () { + + // it('can distribute tokens after fundraising has finished (now >= endTime)', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // { type: 'finalizePresale', fromAccount: 0 } + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can distribute non-vested tokens', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 0, vesting: 0, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can distribute tokens after fundraising has finished (weiRaised = cap)', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 240000, fromAccount: 0 }, + // { type: 'presaleBuyTokens', account: 4, beneficiary: 5, eth: 240000 }, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute tokens if presale has finished', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(3)}, + // { type: 'finalizePresale', fromAccount: 0 }, + // { type: 'distributeTokens', beneficiary: 1, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute tokens with zero beneficiary', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 'zero', amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute 0 tokens', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 1, amount: 0, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute tokens with vesting less than cliff', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 1, amount: 1, cliff: 6000, vesting: 5000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute tokens before or during fundraising', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute more tokens than the distribution cap', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 4, amount: 75000000, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('can NOT distribute tokens if not owner', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(2)}, + // { type: 'distributeTokens', beneficiary: 4, amount: 1, cliff: 6000, vesting: 6000, revokable: false, burnsOnRevoke: false, fromAccount: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // }); + + // describe('buying tokens', function () { + + // it('should NOT allow non-accredited investors to invest', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'presaleSendTransaction', account: 4, eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should allow accredited investors to buy tokens', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleSendTransaction', account: 4, eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT allow to buy tokens with address zero ', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleSendTransaction', account: 'zero', eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should allow accredited investors to buy tokens with cliff zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 0, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleSendTransaction', account: 4, eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should allow accredited investors to buy non-vested tokens', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 0, vesting: 0, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleSendTransaction', account: 4, eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should allow accredited investors to buy non-vested tokens', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 0, vesting: 0, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleBuyTokens', account: 4, beneficiary: 5, eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT allow accredited investors to invest more than maxCumulativeInvest', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleBuyTokens', beneficiary: 3, account: 4, eth: 3 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT allow accredited investors to invest more than maxCumulativeInvest', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 20, fromAccount: 0 }, + // { type: 'presaleBuyTokens', beneficiary: 5, account: 4, eth: 10 }, + // { type: 'waitTime','seconds':duration.seconds(3)}, + // { type: 'presaleBuyTokens', beneficiary: 6, account: 4, eth: 10 }, + // { type: 'waitTime','seconds':duration.seconds(3)}, + // { type: 'presaleBuyTokens', beneficiary: 7, account: 4, eth: 10 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 1, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT allow accredited investors to invest less than minInvest', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // { type: 'presaleBuyTokens', beneficiary: 3, account: 4, eth: 0.5 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT allow buying tokens with zero beneficiary address', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'presaleBuyTokens', account: 4, beneficiary: 'zero', eth: 1 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // }); + + // describe('add to accredited list', function () { + + // it('should NOT be able to add investor to accredited list with rate zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, rate: 0, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to add investor to accredited list with vesting less than cliff', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 100, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should be able to add investor to accredited list with zero cliff', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 0, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to add investor to accredited list with maxCumulativeInvest zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 0, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to add investor to accredited list with minInvest zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 0, maxCumulativeInvest: 2, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to add investor to accredited list if not owner', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 4, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 2 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to add investor to accredited list if address is zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'addAccredited', investor: 'zero', rate: 6000, cliff: 600, vesting: 600, revokable: false, burnsOnTokens: false, minInvest: 1, maxCumulativeInvest: 2, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should be able to remove investor from accredited list', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'removeAccredited', investor: 4, fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to remove investor from accredited list if not owner', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'removeAccredited', investor: 4, fromAccount: 2 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // it('should NOT be able to remove investor from accredited list if address is zero', async function () { + // await runGeneratedPresaleAndCommands({ + // commands: [ + // { type: 'waitTime','seconds':duration.days(1)}, + // { type: 'removeAccredited', investor: 'zero', fromAccount: 0 }, + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }); + // }); + + // }); + + // describe('stateful prob based tests', function () { + + // it('distributes tokens correctly on any combination of bids', async function() { + // // stateful prob based tests can take a long time to finish when shrinking... + // this.timeout(GEN_TESTS_TIMEOUT * 1000); + + // let property = jsc.forall(presaleTestInputGen, async function(presaleAndCommands) { + // return await runGeneratedPresaleAndCommands(presaleAndCommands); + // }); + + // return jsc.assert(property, {tests: GEN_TESTS_QTY}); + // }); + + // }); + + // describe('finalize presale', function () { + + // it('should finish presale fine', async function() { + // let presaleAndCommands = { + // commands: [ + // { type: 'waitTime','seconds':duration.days(4)}, + // { type: 'finalizePresale', fromAccount: 0 } + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }; + + // await runGeneratedPresaleAndCommands(presaleAndCommands); + // }); + + // it('should NOT finish presale if called by non-owner', async function() { + // let presaleAndCommands = { + // commands: [ + // { type: 'waitTime','seconds':duration.days(4)}, + // { type: 'finalizePresale', fromAccount: 0 } + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 1 + // } + // }; + + // await runGeneratedPresaleAndCommands(presaleAndCommands); + // }); + + // it('should NOT finish presale if it has already been finalized', async function() { + // let presaleAndCommands = { + // commands: [ + // { type: 'waitTime','seconds':duration.days(4)}, + // { type: 'finalizePresale', fromAccount: 0 }, + // { type: 'finalizePresale', fromAccount: 0 } + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }; + + // await runGeneratedPresaleAndCommands(presaleAndCommands); + // }); + + // it('should handle the exception correctly when trying to finalize the presale before the presale has ended', async function() { + // let presaleAndCommands = { + // commands: [ + // { type: 'waitTime','seconds':duration.minutes(60)}, + // { type: 'finalizePresale', fromAccount: 0 } + // ], + // presale: { + // rate: 6000, maxGasPrice: 50000000000, minBuyingRequestInterval: 600, cap: 240000, distributionCap: 75000000, foundationWallet: 10, owner: 0 + // } + // }; + + // await runGeneratedPresaleAndCommands(presaleAndCommands); + // }); + + // }); }); diff --git a/test/commands.js b/test/commands.js index b9f7ba2..643df9f 100644 --- a/test/commands.js +++ b/test/commands.js @@ -459,6 +459,7 @@ async function runAddAccreditedCommand(command, state) { vesting < cliff || minInvest == 0 || maxCumulativeInvest == 0 || + minInvest > maxCumulativeInvest || command.fromAccount != state.owner; try {