diff --git a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol index dd5fa0942d2..841f09bc36b 100644 --- a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol +++ b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol @@ -22,8 +22,8 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale { * @param _finalRate Number of tokens a buyer gets per wei at the end of the crowdsale */ constructor(uint256 _initialRate, uint256 _finalRate) public { - require(_initialRate >= _finalRate); require(_finalRate > 0); + require(_initialRate >= _finalRate); initialRate = _initialRate; finalRate = _finalRate; } diff --git a/contracts/ownership/Heritable.sol b/contracts/ownership/Heritable.sol index 4f36e3d3ee0..5daa95a56d9 100644 --- a/contracts/ownership/Heritable.sol +++ b/contracts/ownership/Heritable.sol @@ -47,7 +47,7 @@ contract Heritable is Ownable { * before the heir can take ownership. */ constructor(uint256 _heartbeatTimeout) public { - setHeartbeatTimeout(_heartbeatTimeout); + heartbeatTimeout_ = _heartbeatTimeout; } function setHeir(address _newHeir) public onlyOwner { @@ -113,13 +113,6 @@ contract Heritable is Ownable { timeOfDeath_ = 0; } - function setHeartbeatTimeout(uint256 _newHeartbeatTimeout) - internal onlyOwner - { - require(ownerLives()); - heartbeatTimeout_ = _newHeartbeatTimeout; - } - function ownerLives() internal view returns (bool) { return timeOfDeath_ == 0; } diff --git a/test/crowdsale/CappedCrowdsale.test.js b/test/crowdsale/CappedCrowdsale.test.js index d7a1bf6256b..94ed0aedda4 100644 --- a/test/crowdsale/CappedCrowdsale.test.js +++ b/test/crowdsale/CappedCrowdsale.test.js @@ -19,55 +19,58 @@ contract('CappedCrowdsale', function ([_, wallet]) { beforeEach(async function () { this.token = await SimpleToken.new(); - this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap); - await this.token.transfer(this.crowdsale.address, tokenSupply); }); - describe('creating a valid crowdsale', function () { - it('should fail with zero cap', async function () { - await expectThrow( - CappedCrowdsale.new(rate, wallet, 0, this.token.address), - EVMRevert, - ); - }); + it('rejects a cap of zero', async function () { + await expectThrow( + CappedCrowdsale.new(rate, wallet, this.token.address, 0), + EVMRevert, + ); }); - describe('accepting payments', function () { - it('should accept payments within cap', async function () { - await this.crowdsale.send(cap.minus(lessThanCap)); - await this.crowdsale.send(lessThanCap); + context('with crowdsale', function () { + beforeEach(async function () { + this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap); + await this.token.transfer(this.crowdsale.address, tokenSupply); }); - it('should reject payments outside cap', async function () { - await this.crowdsale.send(cap); - await expectThrow( - this.crowdsale.send(1), - EVMRevert, - ); - }); + describe('accepting payments', function () { + it('should accept payments within cap', async function () { + await this.crowdsale.send(cap.minus(lessThanCap)); + await this.crowdsale.send(lessThanCap); + }); - it('should reject payments that exceed cap', async function () { - await expectThrow( - this.crowdsale.send(cap.plus(1)), - EVMRevert, - ); - }); - }); + it('should reject payments outside cap', async function () { + await this.crowdsale.send(cap); + await expectThrow( + this.crowdsale.send(1), + EVMRevert, + ); + }); - describe('ending', function () { - it('should not reach cap if sent under cap', async function () { - await this.crowdsale.send(lessThanCap); - (await this.crowdsale.capReached()).should.equal(false); + it('should reject payments that exceed cap', async function () { + await expectThrow( + this.crowdsale.send(cap.plus(1)), + EVMRevert, + ); + }); }); - it('should not reach cap if sent just under cap', async function () { - await this.crowdsale.send(cap.minus(1)); - (await this.crowdsale.capReached()).should.equal(false); - }); + describe('ending', function () { + it('should not reach cap if sent under cap', async function () { + await this.crowdsale.send(lessThanCap); + (await this.crowdsale.capReached()).should.equal(false); + }); + + it('should not reach cap if sent just under cap', async function () { + await this.crowdsale.send(cap.minus(1)); + (await this.crowdsale.capReached()).should.equal(false); + }); - it('should reach cap if cap sent', async function () { - await this.crowdsale.send(cap); - (await this.crowdsale.capReached()).should.equal(true); + it('should reach cap if cap sent', async function () { + await this.crowdsale.send(cap); + (await this.crowdsale.capReached()).should.equal(true); + }); }); }); }); diff --git a/test/crowdsale/IncreasingPriceCrowdsale.test.js b/test/crowdsale/IncreasingPriceCrowdsale.test.js index 9453d12bba4..e68d451bd46 100644 --- a/test/crowdsale/IncreasingPriceCrowdsale.test.js +++ b/test/crowdsale/IncreasingPriceCrowdsale.test.js @@ -2,6 +2,7 @@ const { ether } = require('../helpers/ether'); const { advanceBlock } = require('../helpers/advanceToBlock'); const { increaseTimeTo, duration } = require('../helpers/increaseTime'); const { latestTime } = require('../helpers/latestTime'); +const { assertRevert } = require('../helpers/assertRevert'); const BigNumber = web3.BigNumber; @@ -32,52 +33,69 @@ contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser]) this.closingTime = this.startTime + duration.weeks(1); this.afterClosingTime = this.closingTime + duration.seconds(1); this.token = await SimpleToken.new(); - this.crowdsale = await IncreasingPriceCrowdsale.new( - this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate - ); - await this.token.transfer(this.crowdsale.address, tokenSupply); }); - it('at start', async function () { - await increaseTimeTo(this.startTime); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(initialRate)); + it('rejects a final rate larger than the initial rate', async function () { + await assertRevert(IncreasingPriceCrowdsale.new( + this.startTime, this.closingTime, wallet, this.token.address, initialRate, initialRate.plus(1) + )); }); - it('at time 150', async function () { - await increaseTimeTo(this.startTime + 150); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150)); + it('rejects a final rate of zero', async function () { + await assertRevert(IncreasingPriceCrowdsale.new( + this.startTime, this.closingTime, wallet, this.token.address, initialRate, 0 + )); }); - it('at time 300', async function () { - await increaseTimeTo(this.startTime + 300); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime300)); - }); + context('with crowdsale', function () { + beforeEach(async function () { + this.crowdsale = await IncreasingPriceCrowdsale.new( + this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate + ); + await this.token.transfer(this.crowdsale.address, tokenSupply); + }); - it('at time 1500', async function () { - await increaseTimeTo(this.startTime + 1500); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime1500)); - }); + it('at start', async function () { + await increaseTimeTo(this.startTime); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(initialRate)); + }); - it('at time 30', async function () { - await increaseTimeTo(this.startTime + 30); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime30)); - }); + it('at time 150', async function () { + await increaseTimeTo(this.startTime + 150); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150)); + }); - it('at time 150000', async function () { - await increaseTimeTo(this.startTime + 150000); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150000)); - }); + it('at time 300', async function () { + await increaseTimeTo(this.startTime + 300); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime300)); + }); + + it('at time 1500', async function () { + await increaseTimeTo(this.startTime + 1500); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime1500)); + }); + + it('at time 30', async function () { + await increaseTimeTo(this.startTime + 30); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime30)); + }); + + it('at time 150000', async function () { + await increaseTimeTo(this.startTime + 150000); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150000)); + }); - it('at time 450000', async function () { - await increaseTimeTo(this.startTime + 450000); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime450000)); + it('at time 450000', async function () { + await increaseTimeTo(this.startTime + 450000); + await this.crowdsale.buyTokens(investor, { value, from: purchaser }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime450000)); + }); }); }); }); diff --git a/test/crowdsale/MintedCrowdsale.test.js b/test/crowdsale/MintedCrowdsale.test.js index f0a74bd1575..5fc89422c54 100644 --- a/test/crowdsale/MintedCrowdsale.test.js +++ b/test/crowdsale/MintedCrowdsale.test.js @@ -1,11 +1,13 @@ const { shouldBehaveLikeMintedCrowdsale } = require('./MintedCrowdsale.behavior'); const { ether } = require('../helpers/ether'); +const { assertRevert } = require('../helpers/assertRevert'); const BigNumber = web3.BigNumber; const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl'); const MintableToken = artifacts.require('MintableToken'); const RBACMintableToken = artifacts.require('RBACMintableToken'); +const StandardToken = artifacts.require('StandardToken'); contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) { const rate = new BigNumber(1000); @@ -40,4 +42,19 @@ contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) { shouldBehaveLikeMintedCrowdsale([_, investor, wallet, purchaser], rate, value); }); + + describe('using non-mintable token', function () { + beforeEach(async function () { + this.token = await StandardToken.new(); + this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); + }); + + it('rejects bare payments', async function () { + await assertRevert(this.crowdsale.send(value)); + }); + + it('rejects token purchases', async function () { + await assertRevert(this.crowdsale.buyTokens(investor, { value: value, from: purchaser })); + }); + }); }); diff --git a/test/crowdsale/PostDeliveryCrowdsale.test.js b/test/crowdsale/PostDeliveryCrowdsale.test.js index 5511d07573f..ebc41111c3d 100644 --- a/test/crowdsale/PostDeliveryCrowdsale.test.js +++ b/test/crowdsale/PostDeliveryCrowdsale.test.js @@ -16,7 +16,6 @@ const SimpleToken = artifacts.require('SimpleToken'); contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { const rate = new BigNumber(1); - const value = ether(42); const tokenSupply = new BigNumber('1e22'); before(async function () { @@ -27,7 +26,6 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { beforeEach(async function () { this.openingTime = (await latestTime()) + duration.weeks(1); this.closingTime = this.openingTime + duration.weeks(1); - this.beforeEndTime = this.closingTime - duration.hours(1); this.afterClosingTime = this.closingTime + duration.seconds(1); this.token = await SimpleToken.new(); this.crowdsale = await PostDeliveryCrowdsale.new( @@ -36,30 +34,41 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { await this.token.transfer(this.crowdsale.address, tokenSupply); }); - it('should not immediately assign tokens to beneficiary', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(0); - }); + context('after opening time', function () { + beforeEach(async function () { + await increaseTimeTo(this.openingTime); + }); - it('should not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { - await increaseTimeTo(this.beforeEndTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert); - }); + context('with bought tokens', function () { + const value = ether(42); - it('should allow beneficiaries to withdraw tokens after crowdsale ends', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.withdrawTokens({ from: investor }); - }); + beforeEach(async function () { + await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); + }); + + it('does not immediately assign tokens to beneficiaries', async function () { + (await this.token.balanceOf(investor)).should.be.bignumber.equal(0); + }); + + it('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { + await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert); + }); + + context('after closing time', function () { + beforeEach(async function () { + await increaseTimeTo(this.afterClosingTime); + }); + + it('allows beneficiaries to withdraw tokens', async function () { + await this.crowdsale.withdrawTokens({ from: investor }); + (await this.token.balanceOf(investor)).should.be.bignumber.equal(value); + }); - it('should return the amount of tokens bought', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.withdrawTokens({ from: investor }); - (await this.token.balanceOf(investor)).should.be.bignumber.equal(value); + it('rejects multiple withdrawals', async function () { + await this.crowdsale.withdrawTokens({ from: investor }); + await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert); + }); + }); + }); }); }); diff --git a/test/crowdsale/RefundableCrowdsale.test.js b/test/crowdsale/RefundableCrowdsale.test.js index 743342cb9e4..320697267aa 100644 --- a/test/crowdsale/RefundableCrowdsale.test.js +++ b/test/crowdsale/RefundableCrowdsale.test.js @@ -30,56 +30,85 @@ contract('RefundableCrowdsale', function ([_, owner, wallet, investor, purchaser this.openingTime = (await latestTime()) + duration.weeks(1); this.closingTime = this.openingTime + duration.weeks(1); this.afterClosingTime = this.closingTime + duration.seconds(1); + this.preWalletBalance = await ethGetBalance(wallet); this.token = await SimpleToken.new(); - this.crowdsale = await RefundableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, goal, { from: owner } + }); + + it('rejects a goal of zero', async function () { + await expectThrow( + RefundableCrowdsale.new( + this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner } + ), + EVMRevert, ); - await this.token.transfer(this.crowdsale.address, tokenSupply); }); - describe('creating a valid crowdsale', function () { - it('should fail with zero goal', async function () { - await expectThrow( - RefundableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner } - ), - EVMRevert, + context('with crowdsale', function () { + beforeEach(async function () { + this.crowdsale = await RefundableCrowdsale.new( + this.openingTime, this.closingTime, rate, wallet, this.token.address, goal, { from: owner } ); + + await this.token.transfer(this.crowdsale.address, tokenSupply); }); - }); - it('should deny refunds before end', async function () { - await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); - await increaseTimeTo(this.openingTime); - await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); - }); + context('before opening time', function () { + it('denies refunds', async function () { + await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); + }); + }); - it('should deny refunds after end if goal was reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: goal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); - }); + context('after opening time', function () { + beforeEach(async function () { + await increaseTimeTo(this.openingTime); + }); - it('should allow refunds after end if goal was not reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }); - const pre = await ethGetBalance(investor); - await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 }); - const post = await ethGetBalance(investor); - post.minus(pre).should.be.bignumber.equal(lessThanGoal); - }); + it('denies refunds', async function () { + await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); + }); - it('should forward funds to wallet after end if goal was reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: goal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - const pre = await ethGetBalance(wallet); - await this.crowdsale.finalize({ from: owner }); - const post = await ethGetBalance(wallet); - post.minus(pre).should.be.bignumber.equal(goal); + context('with unreached goal', function () { + beforeEach(async function () { + await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor }); + }); + + context('after closing time and finalization', function () { + beforeEach(async function () { + await increaseTimeTo(this.afterClosingTime); + await this.crowdsale.finalize({ from: owner }); + }); + + it('refunds', async function () { + const pre = await ethGetBalance(investor); + await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 }); + const post = await ethGetBalance(investor); + post.minus(pre).should.be.bignumber.equal(lessThanGoal); + }); + }); + }); + + context('with reached goal', function () { + beforeEach(async function () { + await this.crowdsale.sendTransaction({ value: goal, from: investor }); + }); + + context('after closing time and finalization', function () { + beforeEach(async function () { + await increaseTimeTo(this.afterClosingTime); + await this.crowdsale.finalize({ from: owner }); + }); + + it('denies refunds', async function () { + await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert); + }); + + it('forwards funds to wallet', async function () { + const postWalletBalance = await ethGetBalance(wallet); + postWalletBalance.minus(this.preWalletBalance).should.be.bignumber.equal(goal); + }); + }); + }); + }); }); }); diff --git a/test/crowdsale/TimedCrowdsale.test.js b/test/crowdsale/TimedCrowdsale.test.js index 4456ee07e3b..ad9ca29f556 100644 --- a/test/crowdsale/TimedCrowdsale.test.js +++ b/test/crowdsale/TimedCrowdsale.test.js @@ -29,32 +29,49 @@ contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) { this.closingTime = this.openingTime + duration.weeks(1); this.afterClosingTime = this.closingTime + duration.seconds(1); this.token = await SimpleToken.new(); - this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address); - await this.token.transfer(this.crowdsale.address, tokenSupply); }); - it('should be ended only after end', async function () { - (await this.crowdsale.hasClosed()).should.equal(false); - await increaseTimeTo(this.afterClosingTime); - (await this.crowdsale.hasClosed()).should.equal(true); + it('rejects an opening time in the past', async function () { + await expectThrow(TimedCrowdsale.new( + (await latestTime()) - duration.days(1), this.closingTime, rate, wallet, this.token.address + ), EVMRevert); }); - describe('accepting payments', function () { - it('should reject payments before start', async function () { - await expectThrow(this.crowdsale.send(value), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(investor, { from: purchaser, value: value }), EVMRevert); - }); + it('rejects a closing time before the opening time', async function () { + await expectThrow(TimedCrowdsale.new( + this.openingTime, this.openingTime - duration.seconds(1), rate, wallet, this.token.address + ), EVMRevert); + }); - it('should accept payments after start', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.send(value); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); + context('with crowdsale', function () { + beforeEach(async function () { + this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address); + await this.token.transfer(this.crowdsale.address, tokenSupply); }); - it('should reject payments after end', async function () { + it('should be ended only after end', async function () { + (await this.crowdsale.hasClosed()).should.equal(false); await increaseTimeTo(this.afterClosingTime); - await expectThrow(this.crowdsale.send(value), EVMRevert); - await expectThrow(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }), EVMRevert); + (await this.crowdsale.hasClosed()).should.equal(true); + }); + + describe('accepting payments', function () { + it('should reject payments before start', async function () { + await expectThrow(this.crowdsale.send(value), EVMRevert); + await expectThrow(this.crowdsale.buyTokens(investor, { from: purchaser, value: value }), EVMRevert); + }); + + it('should accept payments after start', async function () { + await increaseTimeTo(this.openingTime); + await this.crowdsale.send(value); + await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); + }); + + it('should reject payments after end', async function () { + await increaseTimeTo(this.afterClosingTime); + await expectThrow(this.crowdsale.send(value), EVMRevert); + await expectThrow(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }), EVMRevert); + }); }); }); }); diff --git a/test/payment/SplitPayment.test.js b/test/payment/SplitPayment.test.js index d55a9968d16..bb09ea73cac 100644 --- a/test/payment/SplitPayment.test.js +++ b/test/payment/SplitPayment.test.js @@ -14,28 +14,28 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1, const amount = web3.toWei(1.0, 'ether'); const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - it('cannot be created with no payees', async function () { + it('rejects an empty set of payees', async function () { await expectThrow(SplitPayment.new([], []), EVMRevert); }); - it('requires shares for each payee', async function () { + it('rejects more payees than shares', async function () { await expectThrow(SplitPayment.new([payee1, payee2, payee3], [20, 30]), EVMRevert); }); - it('requires a payee for each share', async function () { + it('rejects more shares than payees', async function () { await expectThrow(SplitPayment.new([payee1, payee2], [20, 30, 40]), EVMRevert); }); - it('requires non-null payees', async function () { + it('rejects null payees', async function () { await expectThrow(SplitPayment.new([payee1, ZERO_ADDRESS], [20, 30]), EVMRevert); }); - it('requires non-zero shares', async function () { + it('rejects zero-valued shares', async function () { await expectThrow(SplitPayment.new([payee1, payee2], [20, 0]), EVMRevert); }); it('rejects repeated payees', async function () { - await expectThrow(SplitPayment.new([payee1, payee1], [20, 0]), EVMRevert); + await expectThrow(SplitPayment.new([payee1, payee1], [20, 30]), EVMRevert); }); context('once deployed', function () {