Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/crowdsale/price/IncreasingPriceCrowdsale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
9 changes: 1 addition & 8 deletions contracts/ownership/Heritable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down
79 changes: 41 additions & 38 deletions test/crowdsale/CappedCrowdsale.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
});
90 changes: 54 additions & 36 deletions test/crowdsale/IncreasingPriceCrowdsale.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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));
});
});
});
});
17 changes: 17 additions & 0 deletions test/crowdsale/MintedCrowdsale.test.js
Original file line number Diff line number Diff line change
@@ -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);
Expand Down Expand Up @@ -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 }));
});
});
});
57 changes: 33 additions & 24 deletions test/crowdsale/PostDeliveryCrowdsale.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand All @@ -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(
Expand All @@ -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);
});
});
});
});
});
Loading