function _mine(address _token, uint256 _inAmount) private {
    if (!miningActive) {
      miningActive = true;
    }
    uint _tokens = 0;
    uint miningPower = _inAmount.mul(exchangeRatios[_token]).div(baseRate);
    uint fee = _inAmount.div(2);

    while (miningPower > 0) {
      if (miningPower >= miningTokenLeftInCurrent) {
        miningPower -= miningTokenLeftInCurrent;
        _tokens += futbLeftInCurrent;
        miningTokenLeftInCurrent = 0;
        futbLeftInCurrent = 0;
      } else {
        uint calculatedFutb = currentRate.mul(miningPower).div(offset);
        _tokens += calculatedFutb;
        futbLeftInCurrent -= calculatedFutb;
        miningTokenLeftInCurrent -= miningPower;
        miningPower = 0;
      }

      if (miningTokenLeftInCurrent == 0) {
        if (currentTier == lastTier) {
          _tokens = SWAP_CAP - cycleMintSupply;
          if (miningPower > 0) {
            uint refund = miningPower.mul(baseRate).div(exchangeRatios[_token]);
            fee -= refund.div(2);
            ERC20(_token).transfer(msg.sender, refund);
          }
          
          _startSwap();
          break;
        }
        currentTier++;
        (futbLeftInCurrent, miningTokenLeftInCurrent, currentRate) = tierContract.getTier(currentTier);
      }
    }
    cycleMintSupply += _tokens;
    MintableToken(this).mint(msg.sender, _tokens);
    ERC20(_token).transfer(FUTC, fee);
  }