contract AllstocksToken is StandardToken {
    string public version = "1.0";

    // contracts
    address public ethFundDeposit;        // deposit address for ETH for Allstocks Fund

    // crowdsale parameters
    bool public isActive;                 // switched to true in after setup
    uint256 public fundingStartTime = 0;
    uint256 public fundingEndTime = 0;
    uint256 public allstocksFund = 25 * (10**6) * 10**decimals;     // 25m reserved for Allstocks use
    uint256 public tokenExchangeRate = 625;                         // 625 Allstocks tokens per 1 ETH
    uint256 public tokenCreationCap =  50 * (10**6) * 10**decimals; // 50m hard cap
    
    //this is for production
    uint256 public tokenCreationMin =  25 * (10**5) * 10**decimals; // 2.5m minimum


    // events
    event LogRefund(address indexed _to, uint256 _value);
    event CreateAllstocksToken(address indexed _to, uint256 _value);

    // constructor
    function AllstocksToken() public {
      isFinalized = false;                         //controls pre through crowdsale state
      owner = msg.sender;
      _totalSupply = allstocksFund;
      balances[owner] = allstocksFund;             // Deposit Allstocks share
      CreateAllstocksToken(owner, allstocksFund);  // logs Allstocks fund
    }

    function setup (
        uint256 _fundingStartTime,
        uint256 _fundingEndTime) onlyOwner external
    {
      require (isActive == false); 
      require (isFinalized == false); 			        	   
      require (msg.sender == owner);                 // locks finalize to the ultimate ETH owner
      require (fundingStartTime == 0);              //run once
      require (fundingEndTime == 0);                //first time 
      require(_fundingStartTime > 0);
      require(_fundingEndTime > 0 && _fundingEndTime > _fundingStartTime);

      isFinalized = false;                          //controls pre through crowdsale state
      isActive = true;
      ethFundDeposit = owner;                       // set ETH wallet owner 
      fundingStartTime = _fundingStartTime;
      fundingEndTime = _fundingEndTime;
    }

    function () public payable {       
      createTokens(msg.value);
    }

    /// @dev Accepts ether and creates new Allstocks tokens.
    function createTokens(uint256 _value)  internal {
      require(isFinalized == false);    
      require(now >= fundingStartTime);
      require(now < fundingEndTime); 
      require(msg.value > 0);         

      uint256 tokens = _value.mul(tokenExchangeRate); // check that we're not over totals
      uint256 checkedSupply = _totalSupply.add(tokens);

      require(checkedSupply <= tokenCreationCap);

      _totalSupply = checkedSupply;
      balances[msg.sender] += tokens;  // safeAdd not needed

      //add sent eth to refunds list
      refunds[msg.sender] = _value.add(refunds[msg.sender]);  // safeAdd 

      CreateAllstocksToken(msg.sender, tokens);  // logs token creation
      Transfer(address(0), owner, _totalSupply);
    }
	
	//method for manageing bonus phases 
	function setRate(uint256 _value) external onlyOwner {
      require (isFinalized == false);
      require (isActive == true);
      require (_value > 0);
      require(msg.sender == owner); // Allstocks double chack 
      tokenExchangeRate = _value;

    }

    /// @dev Ends the funding period and sends the ETH home
    function finalize() external onlyOwner {
      require (isFinalized == false);
      require(msg.sender == owner); // Allstocks double chack  
      require(_totalSupply >= tokenCreationMin + allstocksFund);  // have to sell minimum to move to operational
      require(_totalSupply > 0);

      if (now < fundingEndTime) {    //if try to close before end time, check that we reach target
        require(_totalSupply >= tokenCreationCap);
      }
      else 
        require(now >= fundingEndTime);
      
	    // move to operational
      isFinalized = true;
      ethFundDeposit.transfer(this.balance);  // send the eth to Allstocks
    }

    /// @dev send funding to safe wallet if minimum is reached 
    function vaultFunds() external onlyOwner {
      require(msg.sender == owner);            // Allstocks double chack
      require(_totalSupply >= tokenCreationMin + allstocksFund); // have to sell minimum to move to operational
      ethFundDeposit.transfer(this.balance);  // send the eth to Allstocks
    }

    /// @dev Allows contributors to recover their ether in the case of a failed funding campaign.
    function refund() external {
      require (isFinalized == false);  // prevents refund if operational
      require (isActive == true);
      require (now > fundingEndTime); // prevents refund until sale period is over
     
      require(_totalSupply < tokenCreationMin + allstocksFund);  // no refunds if we sold enough
      require(msg.sender != owner); // Allstocks not entitled to a refund
      
      uint256 allstocksVal = balances[msg.sender];
      uint256 ethValRefund = refunds[msg.sender];
     
      require(allstocksVal > 0);   
      require(ethValRefund > 0);  
     
      balances[msg.sender] = 0;
      refunds[msg.sender] = 0;
      
      _totalSupply = _totalSupply.sub(allstocksVal); // extra safe
      
      uint256 ethValToken = allstocksVal / tokenExchangeRate;     // should be safe; previous throws covers edges

      require(ethValRefund <= ethValToken);
      msg.sender.transfer(ethValRefund);                 // if you're using a contract; make sure it works with .send gas limits
      LogRefund(msg.sender, ethValRefund);               // log it
    }
}
// note introduced onlyPayloadSize in StandardToken.sol to protect against short address attacks
function refund() external {
  require (isFinalized == false);  // prevents refund if operational
  require (isActive == true);
  require (now > fundingEndTime); // prevents refund until sale period is over
     
  require(_totalSupply < tokenCreationMin + allstocksFund);  // no refunds if we sold enough
  require(msg.sender != owner); // Allstocks not entitled to a refund
      
  uint256 allstocksVal = balances[msg.sender];
  uint256 ethValRefund = refunds[msg.sender];
     
  require(allstocksVal > 0);   
  require(ethValRefund > 0);  
     
  balances[msg.sender] = 0;
  refunds[msg.sender] = 0;
      
  _totalSupply = _totalSupply.sub(allstocksVal); // extra safe
      
  uint256 ethValToken = allstocksVal / tokenExchangeRate;     // should be safe; previous throws covers edges

  require(ethValRefund <= ethValToken);
  msg.sender.transfer(ethValRefund);                 // if you're using a contract; make sure it works with .send gas limits
  LogRefund(msg.sender, ethValRefund);               // log it
}

/// @dev Allows contributors to recover their ether in the case of a failed funding campaign.