function buyTokens(address _beneficiary) public whenNotPaused payable {
    require((state == SaleState.PRESALE && block.timestamp >= startPreSaleDate && block.timestamp <= endPreSaleDate) || (state == SaleState.SALE && block.timestamp >= startSaleDate && block.timestamp <= endSaleDate));
    require(_beneficiary != address(0));
    require(msg.value > 0);
    uint usdAmount = currencyContract.getUsdFromETH(msg.value);

    assert(usdAmount >= minimalContributionUSD);

    uint bonusPercent = 0;

    if (state == SaleState.SALE) {
      bonusPercent = bonusContract.getCurrentDayBonus(startSaleDate, (state == SaleState.SALE));
    }

    (uint totalToken, uint tokenWithoutBonus, uint tokenBonus) = calcToken(usdAmount, bonusPercent);

    assert((totalToken > 0 && totalToken <= calculateMaxCoinIssued()));

    uint usdRate = currencyContract.getCurrencyRate("ETH");

    assert(storageContract.addPayment(_beneficiary, "ETH", msg.value, usdAmount, usdRate, tokenWithoutBonus, tokenBonus, bonusPercent, 0));
    assert(currencyContract.addPay("ETH", msg.value, usdAmount, totalToken, tokenBonus));

    emit AddPay(_beneficiary);
  }