I am using truffle and zeppelin.solidity to compile and test a contract for an ICO. So far, so good. But I have a big question:
My contract sends the total supply to the creator wallet, and then automatically sends the correct amount+first week bonus to the buyer. For test purposes, when it deploys, it creates 1000000001 tokens. In the future, these tokens will be used to reward suppliers that have complied with the AS/EN 9100 aerospatial standards set within a DApp that I am currently developping. How do I make sure that only 49% of the tokens can be sold during the ICO?
Here is the contract's source code, I use a Factory.sol contract to create it on the ropsten test net (it's address is 0xafE52AdaAD275FCd30d3bAeF947CF96017f3f277 and its name is KToken.sol):
pragma solidity ^0.4.16;
import 'zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol';
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract KToken is StandardToken {
using SafeMath for uint256;
string public name = "K";
string public symbol = "₭‚";
uint256 public decimals = 18;
uint256 public totalSupply = 1000000001 * (uint256(10) ** decimals);
uint256 public totalRaised; // total ether raised (in wei)
uint256 public startTimestamp; // timestamp after which ICO will start
uint256 public durationSeconds = 4 * 7 * 24 * 60 * 60; // 4 weeks
uint256 public minCap; // the ICO ether goal (in wei)
uint256 public maxCap; // the ICO ether max cap (in wei)
/**
* Address which will receive raised funds
* and owns the total supply of tokens
*/
address public fundsWallet;
function KToken(
address _fundsWallet,
uint256 _startTimestamp,
uint256 _minCap,
uint256 _maxCap) {
fundsWallet = _fundsWallet;
startTimestamp = _startTimestamp;
minCap = _minCap;
maxCap = _maxCap;
// initially assign all tokens to the fundsWallet
balances[fundsWallet] = totalSupply;
Transfer(0x0, fundsWallet, totalSupply);
}
function() isIcoOpen payable {
totalRaised = totalRaised.add(msg.value);
uint256 tokenAmount = calculateTokenAmount(msg.value);
balances[fundsWallet] = balances[fundsWallet].sub(tokenAmount);
balances[msg.sender] = balances[msg.sender].add(tokenAmount);
Transfer(fundsWallet, msg.sender, tokenAmount);
// immediately transfer ether to fundsWallet
fundsWallet.transfer(msg.value);
}
function calculateTokenAmount(uint256 weiAmount) constant returns(uint256) {
// standard rate: 1 ETH : 9000 ₭‚
uint256 tokenAmount = weiAmount.mul(9000);
if (now <= startTimestamp + 7 days) {
// +50% bonus during first week
return tokenAmount.mul(150).div(100);
} else {
return tokenAmount;
}
}
function transfer(address _to, uint _value) isIcoFinished returns (bool) {
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint _value) isIcoFinished returns (bool) {
return super.transferFrom(_from, _to, _value);
}
modifier isIcoOpen() {
require(now >= startTimestamp);
require(now <= (startTimestamp + durationSeconds) || totalRaised < minCap);
require(totalRaised <= maxCap);
_;
}
modifier isIcoFinished() {
require(now >= startTimestamp);
require(totalRaised >= maxCap || (now >= (startTimestamp + durationSeconds) && totalRaised >= minCap));
_;
}
}