diff --git a/contracts/crowdsale/Crowdsale.sol b/contracts/crowdsale/Crowdsale.sol index 4c1e526ff..e4cc4eb07 100644 --- a/contracts/crowdsale/Crowdsale.sol +++ b/contracts/crowdsale/Crowdsale.sol @@ -6,7 +6,7 @@ import '../math/SafeMath.sol'; /** * @title Crowdsale * @dev Crowdsale is a base contract for managing a token crowdsale. - * Crowdsales have a start and end block, where investors can make + * Crowdsales have a start and end timestamps, where investors can make * token purchases and the crowdsale will assign them tokens based * on a token per ETH rate. Funds collected are forwarded to a wallet * as they arrive. @@ -17,9 +17,9 @@ contract Crowdsale { // The token being sold MintableToken public token; - // start and end block where investments are allowed (both inclusive) - uint256 public startBlock; - uint256 public endBlock; + // start and end timestamps where investments are allowed (both inclusive) + uint256 public startTime; + uint256 public endTime; // address where funds are collected address public wallet; @@ -40,15 +40,15 @@ contract Crowdsale { event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); - function Crowdsale(uint256 _startBlock, uint256 _endBlock, uint256 _rate, address _wallet) { - require(_startBlock >= block.number); - require(_endBlock >= _startBlock); + function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) { + require(_startTime >= now); + require(_endTime >= _startTime); require(_rate > 0); require(_wallet != 0x0); token = createTokenContract(); - startBlock = _startBlock; - endBlock = _endBlock; + startTime = _startTime; + endTime = _endTime; rate = _rate; wallet = _wallet; } @@ -92,15 +92,14 @@ contract Crowdsale { // @return true if the transaction can buy tokens function validPurchase() internal constant returns (bool) { - uint256 current = block.number; - bool withinPeriod = current >= startBlock && current <= endBlock; + bool withinPeriod = now >= startTime && now <= endTime; bool nonZeroPurchase = msg.value != 0; return withinPeriod && nonZeroPurchase; } // @return true if crowdsale event has ended function hasEnded() public constant returns (bool) { - return block.number > endBlock; + return now > endTime; } diff --git a/test/Crowdsale.js b/test/Crowdsale.js index 5160fea42..698592690 100644 --- a/test/Crowdsale.js +++ b/test/Crowdsale.js @@ -1,5 +1,8 @@ +import moment from 'moment' import ether from './helpers/ether' import advanceToBlock from './helpers/advanceToBlock' +import increaseTime from './helpers/increaseTime' +import latestTime from './helpers/latestTime' import EVMThrow from './helpers/EVMThrow' const BigNumber = web3.BigNumber @@ -19,11 +22,16 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { const expectedTokenAmount = rate.mul(value) + before(async function() { + //Advance to the next block to correctly read time in the solidity "now" function interpreted by testrpc + await advanceToBlock(web3.eth.getBlock('latest').number + 1) + }) + beforeEach(async function () { - this.startBlock = web3.eth.blockNumber + 10 - this.endBlock = web3.eth.blockNumber + 20 + this.startTime = latestTime().unix() + moment.duration(1, 'week').asSeconds(); + this.endTime = latestTime().unix() + moment.duration(2, 'week').asSeconds(); - this.crowdsale = await Crowdsale.new(this.startBlock, this.endBlock, rate, wallet) + this.crowdsale = await Crowdsale.new(this.startTime, this.endTime, rate, wallet) this.token = MintableToken.at(await this.crowdsale.token()) }) @@ -36,7 +44,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { it('should be ended only after end', async function () { let ended = await this.crowdsale.hasEnded() ended.should.equal(false) - await advanceToBlock(this.endBlock + 1) + await increaseTime(moment.duration(2.1, 'week')) ended = await this.crowdsale.hasEnded() ended.should.equal(true) }) @@ -49,13 +57,13 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { }) it('should accept payments after start', async function () { - await advanceToBlock(this.startBlock - 1) + await increaseTime(moment.duration(1, 'week')) await this.crowdsale.send(value).should.be.fulfilled await this.crowdsale.buyTokens(investor, {value: value, from: purchaser}).should.be.fulfilled }) it('should reject payments after end', async function () { - await advanceToBlock(this.endBlock) + await increaseTime(moment.duration(2.1, 'week')) await this.crowdsale.send(value).should.be.rejectedWith(EVMThrow) await this.crowdsale.buyTokens(investor, {value: value, from: purchaser}).should.be.rejectedWith(EVMThrow) }) @@ -65,7 +73,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { describe('high-level purchase', function () { beforeEach(async function() { - await advanceToBlock(this.startBlock) + await increaseTime(moment.duration(1, 'week')) }) it('should log purchase', async function () { @@ -104,7 +112,7 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { describe('low-level purchase', function () { beforeEach(async function() { - await advanceToBlock(this.startBlock) + await increaseTime(moment.duration(1, 'week')) }) it('should log purchase', async function () {