Commit 4d7c3cca by Santiago Palladino Committed by Francisco Giordano

Move token creation outside of crowdsale contract (#690)

Fixes #358
parent 05413470
...@@ -10,7 +10,9 @@ import "../math/SafeMath.sol"; ...@@ -10,7 +10,9 @@ import "../math/SafeMath.sol";
* Crowdsales have a start and end timestamps, 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 * token purchases and the crowdsale will assign them tokens based
* on a token per ETH rate. Funds collected are forwarded to a wallet * on a token per ETH rate. Funds collected are forwarded to a wallet
* as they arrive. * as they arrive. The contract requires a MintableToken that will be
* minted as contributions arrive, note that the crowdsale contract
* must be owner of the token in order to be able to mint it.
*/ */
contract Crowdsale { contract Crowdsale {
using SafeMath for uint256; using SafeMath for uint256;
...@@ -41,17 +43,18 @@ contract Crowdsale { ...@@ -41,17 +43,18 @@ contract Crowdsale {
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) public { function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet, MintableToken _token) public {
require(_startTime >= now); require(_startTime >= now);
require(_endTime >= _startTime); require(_endTime >= _startTime);
require(_rate > 0); require(_rate > 0);
require(_wallet != address(0)); require(_wallet != address(0));
require(_token != address(0));
token = createTokenContract();
startTime = _startTime; startTime = _startTime;
endTime = _endTime; endTime = _endTime;
rate = _rate; rate = _rate;
wallet = _wallet; wallet = _wallet;
token = _token;
} }
// fallback function can be used to buy tokens // fallback function can be used to buy tokens
...@@ -83,12 +86,6 @@ contract Crowdsale { ...@@ -83,12 +86,6 @@ contract Crowdsale {
return now > endTime; return now > endTime;
} }
// creates the token to be sold.
// override this method to have crowdsale of a specific mintable token.
function createTokenContract() internal returns (MintableToken) {
return new MintableToken();
}
// Override this method to have a way to add business logic to your crowdsale when buying // Override this method to have a way to add business logic to your crowdsale when buying
function getTokenAmount(uint256 weiAmount) internal view returns(uint256) { function getTokenAmount(uint256 weiAmount) internal view returns(uint256) {
return weiAmount.mul(rate); return weiAmount.mul(rate);
......
...@@ -32,19 +32,14 @@ contract SampleCrowdsaleToken is MintableToken { ...@@ -32,19 +32,14 @@ contract SampleCrowdsaleToken is MintableToken {
*/ */
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale { contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale {
function SampleCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _goal, uint256 _cap, address _wallet) public function SampleCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _goal, uint256 _cap, address _wallet, MintableToken _token) public
CappedCrowdsale(_cap) CappedCrowdsale(_cap)
FinalizableCrowdsale() FinalizableCrowdsale()
RefundableCrowdsale(_goal) RefundableCrowdsale(_goal)
Crowdsale(_startTime, _endTime, _rate, _wallet) Crowdsale(_startTime, _endTime, _rate, _wallet, _token)
{ {
//As goal needs to be met for a successful crowdsale //As goal needs to be met for a successful crowdsale
//the value needs to less or equal than a cap which is limit for accepted funds //the value needs to less or equal than a cap which is limit for accepted funds
require(_goal <= _cap); require(_goal <= _cap);
} }
function createTokenContract() internal returns (MintableToken) {
return new SampleCrowdsaleToken();
}
} }
...@@ -11,9 +11,10 @@ contract CappedCrowdsaleImpl is CappedCrowdsale { ...@@ -11,9 +11,10 @@ contract CappedCrowdsaleImpl is CappedCrowdsale {
uint256 _endTime, uint256 _endTime,
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
uint256 _cap uint256 _cap,
MintableToken _token
) public ) public
Crowdsale(_startTime, _endTime, _rate, _wallet) Crowdsale(_startTime, _endTime, _rate, _wallet, _token)
CappedCrowdsale(_cap) CappedCrowdsale(_cap)
{ {
} }
......
...@@ -10,9 +10,10 @@ contract FinalizableCrowdsaleImpl is FinalizableCrowdsale { ...@@ -10,9 +10,10 @@ contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
uint256 _startTime, uint256 _startTime,
uint256 _endTime, uint256 _endTime,
uint256 _rate, uint256 _rate,
address _wallet address _wallet,
MintableToken _token
) public ) public
Crowdsale(_startTime, _endTime, _rate, _wallet) Crowdsale(_startTime, _endTime, _rate, _wallet, _token)
{ {
} }
......
...@@ -11,9 +11,10 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale { ...@@ -11,9 +11,10 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale {
uint256 _endTime, uint256 _endTime,
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
uint256 _goal uint256 _goal,
MintableToken _token
) public ) public
Crowdsale(_startTime, _endTime, _rate, _wallet) Crowdsale(_startTime, _endTime, _rate, _wallet, _token)
RefundableCrowdsale(_goal) RefundableCrowdsale(_goal)
{ {
} }
......
...@@ -29,9 +29,9 @@ contract('CappedCrowdsale', function ([_, wallet]) { ...@@ -29,9 +29,9 @@ contract('CappedCrowdsale', function ([_, wallet]) {
this.startTime = latestTime() + duration.weeks(1); this.startTime = latestTime() + duration.weeks(1);
this.endTime = this.startTime + duration.weeks(1); this.endTime = this.startTime + duration.weeks(1);
this.crowdsale = await CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, cap); this.token = await MintableToken.new();
this.crowdsale = await CappedCrowdsale.new(this.startTime, this.endTime, rate, wallet, cap, this.token.address);
this.token = MintableToken.at(await this.crowdsale.token()); await this.token.transferOwnership(this.crowdsale.address);
}); });
describe('creating a valid crowdsale', function () { describe('creating a valid crowdsale', function () {
......
...@@ -30,9 +30,9 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) { ...@@ -30,9 +30,9 @@ contract('Crowdsale', function ([_, investor, wallet, purchaser]) {
this.endTime = this.startTime + duration.weeks(1); this.endTime = this.startTime + duration.weeks(1);
this.afterEndTime = this.endTime + duration.seconds(1); this.afterEndTime = this.endTime + duration.seconds(1);
this.crowdsale = await Crowdsale.new(this.startTime, this.endTime, rate, wallet); this.token = await MintableToken.new();
this.crowdsale = await Crowdsale.new(this.startTime, this.endTime, rate, wallet, this.token.address);
this.token = MintableToken.at(await this.crowdsale.token()); await this.token.transferOwnership(this.crowdsale.address);
}); });
it('should be token owner', async function () { it('should be token owner', async function () {
......
...@@ -26,9 +26,11 @@ contract('FinalizableCrowdsale', function ([_, owner, wallet, thirdparty]) { ...@@ -26,9 +26,11 @@ contract('FinalizableCrowdsale', function ([_, owner, wallet, thirdparty]) {
this.endTime = this.startTime + duration.weeks(1); this.endTime = this.startTime + duration.weeks(1);
this.afterEndTime = this.endTime + duration.seconds(1); this.afterEndTime = this.endTime + duration.seconds(1);
this.crowdsale = await FinalizableCrowdsale.new(this.startTime, this.endTime, rate, wallet, { from: owner }); this.token = await MintableToken.new();
this.crowdsale = await FinalizableCrowdsale.new(
this.token = MintableToken.at(await this.crowdsale.token()); this.startTime, this.endTime, rate, wallet, this.token.address, { from: owner }
);
await this.token.transferOwnership(this.crowdsale.address);
}); });
it('cannot be finalized before ending', async function () { it('cannot be finalized before ending', async function () {
......
...@@ -12,6 +12,7 @@ require('chai') ...@@ -12,6 +12,7 @@ require('chai')
.should(); .should();
const RefundableCrowdsale = artifacts.require('mocks/RefundableCrowdsaleImpl.sol'); const RefundableCrowdsale = artifacts.require('mocks/RefundableCrowdsaleImpl.sol');
const MintableToken = artifacts.require('MintableToken');
contract('RefundableCrowdsale', function ([_, owner, wallet, investor]) { contract('RefundableCrowdsale', function ([_, owner, wallet, investor]) {
const rate = new BigNumber(1000); const rate = new BigNumber(1000);
...@@ -28,7 +29,11 @@ contract('RefundableCrowdsale', function ([_, owner, wallet, investor]) { ...@@ -28,7 +29,11 @@ contract('RefundableCrowdsale', function ([_, owner, wallet, investor]) {
this.endTime = this.startTime + duration.weeks(1); this.endTime = this.startTime + duration.weeks(1);
this.afterEndTime = this.endTime + duration.seconds(1); this.afterEndTime = this.endTime + duration.seconds(1);
this.crowdsale = await RefundableCrowdsale.new(this.startTime, this.endTime, rate, wallet, goal, { from: owner }); this.token = await MintableToken.new();
this.crowdsale = await RefundableCrowdsale.new(
this.startTime, this.endTime, rate, wallet, goal, this.token.address, { from: owner }
);
await this.token.transferOwnership(this.crowdsale.address);
}); });
describe('creating a valid crowdsale', function () { describe('creating a valid crowdsale', function () {
......
...@@ -29,8 +29,11 @@ contract('SampleCrowdsale', function ([owner, wallet, investor]) { ...@@ -29,8 +29,11 @@ contract('SampleCrowdsale', function ([owner, wallet, investor]) {
this.endTime = this.startTime + duration.weeks(1); this.endTime = this.startTime + duration.weeks(1);
this.afterEndTime = this.endTime + duration.seconds(1); this.afterEndTime = this.endTime + duration.seconds(1);
this.crowdsale = await SampleCrowdsale.new(this.startTime, this.endTime, RATE, GOAL, CAP, wallet); this.token = await SampleCrowdsaleToken.new();
this.token = SampleCrowdsaleToken.at(await this.crowdsale.token()); this.crowdsale = await SampleCrowdsale.new(
this.startTime, this.endTime, RATE, GOAL, CAP, wallet, this.token.address
);
await this.token.transferOwnership(this.crowdsale.address);
}); });
it('should create crowdsale with correct parameters', async function () { it('should create crowdsale with correct parameters', async function () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment