-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
165 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const RefundableCrowdsale = artifacts.require('AgiCrowdsale.sol') | ||
const MintableToken = artifacts.require('MintableToken') | ||
|
||
const ether = require('./helpers/ether') | ||
const { advanceBlock } = require('./helpers/advanceToBlock') | ||
const { increaseTimeTo, duration } = require('./helpers/increaseTime') | ||
const latestTime = require('./helpers/latestTime') | ||
const EVMThrow = 'Invalid opcode' | ||
|
||
const BigNumber = web3.BigNumber | ||
|
||
contract('AgiCrowdsale', function ([_, owner, wallet, investor]) { | ||
|
||
const rate = new BigNumber(1000) | ||
const goal = ether(800) | ||
const lessThanGoal = ether(750) | ||
|
||
before(async function () { | ||
//Advance to the next block to correctly read time in the solidity "now" function interpreted by testrpc | ||
await advanceBlock() | ||
}) | ||
|
||
beforeEach(async function () { | ||
this.startTime = latestTime() + duration.weeks(1) | ||
this.endTime = this.startTime + duration.weeks(1) | ||
this.afterEndTime = this.endTime + duration.seconds(1) | ||
|
||
this.crowdsale = await RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, goal, { from: owner }) | ||
}) | ||
|
||
describe('creating a valid crowdsale', function () { | ||
|
||
it('should fail with zero goal', async function () { | ||
await RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, 0, { from: owner }).should.be.rejectedWith(EVMThrow); | ||
}) | ||
|
||
}); | ||
|
||
it('should deny refunds before end', async function () { | ||
await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMThrow) | ||
await increaseTimeTo(this.startTime) | ||
await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMThrow) | ||
}) | ||
|
||
it('should deny refunds after end if goal was reached', async function () { | ||
await increaseTimeTo(this.startTime) | ||
await this.crowdsale.sendTransaction({ value: goal, from: investor }) | ||
await increaseTimeTo(this.afterEndTime) | ||
await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMThrow) | ||
}) | ||
|
||
it('should allow refunds after end if goal was not reached', async function () { | ||
await increaseTimeTo(this.startTime) | ||
await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor }) | ||
await increaseTimeTo(this.afterEndTime) | ||
|
||
await this.crowdsale.finalize({ from: owner }) | ||
|
||
const pre = web3.eth.getBalance(investor) | ||
await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 }) | ||
.should.be.fulfilled | ||
const post = web3.eth.getBalance(investor) | ||
|
||
post.minus(pre).should.be.bignumber.equal(lessThanGoal) | ||
}) | ||
|
||
it('should forward funds to wallet after end if goal was reached', async function () { | ||
await increaseTimeTo(this.startTime) | ||
await this.crowdsale.sendTransaction({ value: goal, from: investor }) | ||
await increaseTimeTo(this.afterEndTime) | ||
|
||
const pre = web3.eth.getBalance(wallet) | ||
await this.crowdsale.finalize({ from: owner }) | ||
const post = web3.eth.getBalance(wallet) | ||
|
||
post.minus(pre).should.be.bignumber.equal(goal) | ||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
exports.advanceBlock = function() { | ||
return new Promise((resolve, reject) => { | ||
web3.currentProvider.sendAsync({ | ||
jsonrpc: '2.0', | ||
method: 'evm_mine', | ||
id: Date.now(), | ||
}, (err, res) => { | ||
return err ? reject(err) : resolve(res) | ||
}) | ||
}) | ||
} | ||
|
||
// Advances the block number so that the last mined block is `number`. | ||
exports.advanceToBlock = async function(number) { | ||
if (web3.eth.blockNumber > number) { | ||
throw Error(`block number ${number} is in the past (current is ${web3.eth.blockNumber})`) | ||
} | ||
|
||
while (web3.eth.blockNumber < number) { | ||
await advanceBlock() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = function(n) { | ||
return new web3.BigNumber(web3.toWei(n, 'ether')) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
const latestTime = require('./latestTime') | ||
|
||
// Increases testrpc time by the passed duration in seconds | ||
exports.increaseTime = function(duration) { | ||
const id = Date.now() | ||
|
||
return new Promise((resolve, reject) => { | ||
web3.currentProvider.sendAsync({ | ||
jsonrpc: '2.0', | ||
method: 'evm_increaseTime', | ||
params: [duration], | ||
id: id, | ||
}, err1 => { | ||
if (err1) return reject(err1) | ||
|
||
web3.currentProvider.sendAsync({ | ||
jsonrpc: '2.0', | ||
method: 'evm_mine', | ||
id: id+1, | ||
}, (err2, res) => { | ||
return err2 ? reject(err2) : resolve(res) | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
/** | ||
* Beware that due to the need of calling two separate testrpc methods and rpc calls overhead | ||
* it's hard to increase time precisely to a target point so design your test to tolerate | ||
* small fluctuations from time to time. | ||
* | ||
* @param target time in seconds | ||
*/ | ||
exports.increaseTimeTo = function(target) { | ||
let now = latestTime(); | ||
if (target < now) throw Error(`Cannot increase current time(${now}) to a moment in the past(${target})`); | ||
let diff = target - now; | ||
return increaseTime(diff); | ||
} | ||
|
||
exports.duration = { | ||
seconds: function(val) { return val}, | ||
minutes: function(val) { return val * this.seconds(60) }, | ||
hours: function(val) { return val * this.minutes(60) }, | ||
days: function(val) { return val * this.hours(24) }, | ||
weeks: function(val) { return val * this.days(7) }, | ||
years: function(val) { return val * this.days(365)} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// Returns the time of the last mined block in seconds | ||
module.exports = function() { | ||
return web3.eth.getBlock('latest').timestamp; | ||
} |