function doInvest(address referrerAddr) public payable notFromContract balanceChanged {
        uint investment = msg.value;
        uint receivedEther = msg.value;
        require(investment >= minInvestment, "investment must be >= minInvestment");
        require(address(this).balance <= maxBalance, "the contract eth balance limit");

        if (receivedEther > investment) {
            uint excess = receivedEther - investment;
            msg.sender.transfer(excess);
            receivedEther = investment;
            emit LogSendExcessOfEther(msg.sender, now, msg.value, investment, excess);
        }

        advertisingAddress.send(m_advertisingPercent.mul(receivedEther));
        adminsAddress.send(m_adminsPercent.mul(receivedEther));

        bool senderIsInvestor = m_investors.isInvestor(msg.sender);

        if (referrerAddr.notZero() && !senderIsInvestor  &&
        referrerAddr != msg.sender && m_investors.isInvestor(referrerAddr)) {
            uint referrerBonus = m_referrer_percent.mmul(investment);
            uint referalBonus = m_referal_percent.mmul(investment);
            assert(m_investors.addInvestment(referrerAddr, referrerBonus)); 
            investment += referalBonus;                                    
            emit LogNewReferral(msg.sender, referrerAddr, now, referalBonus);
        }

        uint dividends = calcDividends(msg.sender);
        if (senderIsInvestor && dividends.notZero()) {
            investment += dividends;
            emit LogAutomaticReinvest(msg.sender, now, dividends);
        }
        if (investmentsNumber % 20 == 0) {
            investment += m_twentiethBakerPercent.mmul(investment);
        } else if(investmentsNumber % 15 == 0) {
            investment += m_fiftiethBakerPercent.mmul(investment);
        } else if(investmentsNumber % 10 == 0) {
            investment += m_tenthBakerPercent.mmul(investment);
        }
        if (senderIsInvestor) {
            assert(m_investors.addInvestment(msg.sender, investment));
            assert(m_investors.setPaymentTime(msg.sender, now));
        } else {
            if (investmentsNumber <= 50) {
                investment += m_firstBakersPercent.mmul(investment);
            }
            assert(m_investors.newInvestor(msg.sender, investment, now));
            emit LogNewInvestor(msg.sender, now);
        }

        investmentsNumber++;
        emit LogNewInvestment(msg.sender, now, investment, receivedEther);
    }