I actually do not like the concept of splitting the code into lots and lots of contracts.
I basically wrote one crowed sale contract that handles tiers. I do not need time limits.
Everything works fine. But If I send 100000000000000000 WEI (which is the max amount you can send in one transaction) after the second time it jumps into if(weiRaised.add(weiAmount) > cap[currentTier])
which makes no sense because twice 100000000000000000 WEI is exactly the cap[2]
. Thus result in if(100000000000000000 + 100000000000000000 > 200000000000000000)
which should be FALSE
. I'm little confused.
In the end - it does not really matter because it just produces two 0
value transactions. Because overFunded = 0
. But anyway. Seems awkward.
In short it looks like (I know it seems long but it's pretty straight forward and easy. I only put in the relevant function. Working code here:
contract Crowdsale{
using SafeMath for uint256;
// The token being sold
Token public token;
// address where funds are collected
address public wallet;
// how many token units a buyer gets per wei in each tier
mapping (uint256 => uint256) public rate;
// max cap in eacht tier
mapping (uint256 => uint256) public cap;
// the current tier we are in
uint256 public currentTier;
// amount of token raised in "wei"
uint256 public tokenRaised = 0;
// amount of raised money in wei
uint256 public weiRaised = 0;
event TokenPurchase(address indexed purchaser, address indexed
beneficiary, uint256 value, uint256 amount);
function Crowdsale(address _wallet, IWToken _token) public {
require(_wallet != address(0));
require(_token != address(0));
/* HERE THE VARIABLES GET INIT */
// set token address
token = _token;
owner = msg.sender;
// set rates
rate[1] = 23000;
rate[2] = 22000;
rate[3] = 21000;
rate[4] = 20000;
// set caps in Wei
cap[1] = 100000000000000000;
cap[2] = 200000000000000000;
cap[3] = 300000000000000000;
cap[4] = 1000000000000000000;
// the current tier
currentTier = 1;
wallet = _wallet;
/* INIT DONE */
}
// token purchase function
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(!stopped);
require(msg.value <= 100000000000000000);
require(msg.value > 0);
uint256 weiAmount = msg.value;
uint256 tokens;
// in case that the cap is exceeded
if(weiRaised.add(weiAmount) > cap[currentTier]){
// split the fund
uint256 overFunded = weiRaised.add(weiAmount).sub(cap[currentTier]);
weiAmount = msg.value.sub(overFunded);
// update state
// calculate token amount to be created
tokens = weiAmount.mul(rate[currentTier]);
weiRaised = weiRaised.add(weiAmount);
tokenRaised = tokenRaised.add(tokens);
// first fraction of token
token.ICOmint(beneficiary, tokens);
TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
forwardFunds(weiAmount);
// go into next tier
currentTier = currentTier+1;
if(currentTier > 4){
// Refund overspend wei
msg.sender.transfer(overFunded);
// stop token sale
stopped = true;
} else {
// fund the remaining
tokens = overFunded.mul(rate[currentTier]);
weiRaised = weiRaised.add(overFunded);
tokenRaised = tokenRaised.add(tokens);
// second fraction of token
token.ICOmint(beneficiary, tokens);
TokenPurchase(msg.sender, beneficiary, overFunded, tokens);
forwardFunds(overFunded);
}
} else {
// calculate token amount to be created
tokens = weiAmount.mul(rate[currentTier]);
weiRaised = weiRaised.add(weiAmount);
tokenRaised = tokenRaised.add(tokens);
token.ICOmint(beneficiary, tokens);
TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
forwardFunds(msg.value);
}
}
function forwardFunds(uint256 _amount) internal {
wallet.transfer(_amount);
}