contract ZanteCoin is ERC20Coin {

    /* Basic coin data */

    string public constant name = "Zpay";
    string public constant symbol = "ZPAY";
    uint8  public constant decimals = 18;

    /* ICO dates */

    uint public constant DATE_ICO_START = 1521072000; // 15-Mar-2018 00:00 UTC
    uint public constant DATE_ICO_END   = 1531612800; // 15-Jul-2018 00:00 UTC

    /* Max ICO and other coin supply parameters */  

    uint public constant COIN_SUPPLY_ICO_PHASE_0 = 30000000 * 10**18;  //  30M coins Pre-ICO
    uint public constant COIN_SUPPLY_ICO_PHASE_1 = 70000000 * 10**18;  //  70M coins
    uint public constant COIN_SUPPLY_ICO_PHASE_2 = 200000000 * 10**18; // 200M coins
    uint public constant COIN_SUPPLY_ICO_PHASE_3 = 300000000 * 10**18; // 300M coins
    uint public constant COIN_SUPPLY_ICO_TOTAL   = 
        COIN_SUPPLY_ICO_PHASE_0
        + COIN_SUPPLY_ICO_PHASE_1
        + COIN_SUPPLY_ICO_PHASE_2
        + COIN_SUPPLY_ICO_PHASE_3;

    uint public constant COIN_SUPPLY_MKT_TOTAL = 600000000 * 10**18;

    uint public constant COIN_SUPPLY_COMPANY_TOTAL = 800000000 * 10**18;

    uint public constant COIN_SUPPLY_TOTAL = 
        COIN_SUPPLY_ICO_TOTAL
        + COIN_SUPPLY_MKT_TOTAL
        + COIN_SUPPLY_COMPANY_TOTAL;

    /* Other ICO parameters */  

    uint public constant MIN_CONTRIBUTION = 1 ether / 100; // 0.01 ether
    uint public constant MAX_CONTRIBUTION = 15610 ether;

    /* Current coin supply variables */

    uint public coinsIssuedIco = 0;
    uint public coinsIssuedMkt = 0;
    uint public coinsIssuedCmp = 0;  

    // Events ---------------------------

    event IcoCoinsIssued(address indexed _owner, uint _coins);
    event MarketingCoinsGranted(address indexed _participant, uint _coins, uint _balance);
    event CompanyCoinsGranted(address indexed _participant, uint _coins, uint _balance);

    // Basic Functions ------------------

    /* Initialize (owner is set to msg.sender by Owned.Owned() */

    function ZanteCoin() public {  }

    /* Fallback */

    function () public {
        // Not a payable to prevent ether transfers to this contract.
    }

    function issueIcoCoins(address _participant, uint _coins) public onlyOwner {
        // Check if enough supply remaining
        require(_coins <= COIN_SUPPLY_ICO_TOTAL.sub(coinsIssuedIco));

        // update balances
        balances[_participant] = balances[_participant].add(_coins);
        coinsIssuedIco = coinsIssuedIco.add(_coins);
        coinsIssuedTotal = coinsIssuedTotal.add(_coins);

        // log the minting
        Transfer(0x0, _participant, _coins);
        IcoCoinsIssued(_participant, _coins);
    }

    /* Granting / minting of marketing coins by owner */
    function grantMarketingCoins(address _participant, uint _coins) public onlyOwner {
        // check amount
        require(_coins <= COIN_SUPPLY_MKT_TOTAL.sub(coinsIssuedMkt));

        // update balances
        balances[_participant] = balances[_participant].add(_coins);
        coinsIssuedMkt = coinsIssuedMkt.add(_coins);
        coinsIssuedTotal = coinsIssuedTotal.add(_coins);

        // log the minting
        Transfer(0x0, _participant, _coins);
        MarketingCoinsGranted(_participant, _coins, balances[_participant]);
    }

    /* Granting / minting of Company bonus coins by owner */
    function grantCompanyCoins(address _participant, uint _coins) public onlyOwner {
        // check amount
        require(_coins <= COIN_SUPPLY_COMPANY_TOTAL.sub(coinsIssuedCmp));

        // update balances
        balances[_participant] = balances[_participant].add(_coins);
        coinsIssuedCmp = coinsIssuedCmp.add(_coins);
        coinsIssuedTotal = coinsIssuedTotal.add(_coins);

        // log the minting
        Transfer(0x0, _participant, _coins);
        CompanyCoinsGranted(_participant, _coins, balances[_participant]);
    }
}
function grantCompanyCoins(address _participant, uint _coins) public onlyOwner {
    // check amount
    require(_coins <= COIN_SUPPLY_COMPANY_TOTAL.sub(coinsIssuedCmp));

    // update balances
    balances[_participant] = balances[_participant].add(_coins);
    coinsIssuedCmp = coinsIssuedCmp.add(_coins);
    coinsIssuedTotal = coinsIssuedTotal.add(_coins);

    // log the minting
    Transfer(0x0, _participant, _coins);
    CompanyCoinsGranted(_participant, _coins, balances[_participant]);
}

/* Granting / minting of Company bonus coins by owner */