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

    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));

1 Answer 1


Following the logic of your code, you add this constraint into your fallback function. Replace

balances[fundsWallet] = balances[fundsWallet].sub(tokenAmount);


uint256 newBalance = balances[fundsWallet].sub(tokenAmount); require(newBalance >= reservedTokens); balances[fundsWallet] = newBalance;

Number of reserved tokens can be calculated like:

uint256 reservedTokens = totalSupply.div(100).mul(51);

On a side note, it appears you have taken Zeppelin's token contract and extended it with custom ICO logic. It is not the intended approach. You might want to check https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/examples/SampleCrowdsale.sol to see how Zeppelin's contracts ought to be used.

  • thanks! I appreciated your answer, but I cannot upvote yet! hope others will do it for me Jan 29, 2018 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.