contract TokenlessCrowdsale {
  using SafeMath for uint256;

  // Address where funds are collected
  address public wallet;

  // Amount of wei raised
  uint256 public weiRaised;

  /**
   * Event for token purchase logging
   * similar to TokenPurchase without the token amount
   * @param purchaser who paid for the tokens
   * @param beneficiary who got the tokens
   * @param value weis paid for purchase
   */
  event SaleContribution(address indexed purchaser, address indexed beneficiary, uint256 value);

  /**
   * @param _wallet Address where collected funds will be forwarded to
   */
  constructor (address _wallet) public {
    require(_wallet != address(0));
    wallet = _wallet;
  }

  // -----------------------------------------
  // Crowdsale external interface
  // -----------------------------------------

  /**
   * @dev fallback function ***DO NOT OVERRIDE***
   */
  function () external payable {
    buyTokens(msg.sender);
  }

  /**
   * @dev low level token purchase ***DO NOT OVERRIDE***
   * @param _beneficiary Address performing the token purchase
   */
  function buyTokens(address _beneficiary) public payable {

    uint256 weiAmount = msg.value;
    _preValidatePurchase(_beneficiary, weiAmount);

    // update state
    weiRaised = weiRaised.add(weiAmount);

    _processPurchaseInWei(_beneficiary, weiAmount);
    emit SaleContribution(
      msg.sender,
      _beneficiary,
      weiAmount
    );

    _updatePurchasingState(_beneficiary, weiAmount);

    _forwardFunds();
    _postValidatePurchase(_beneficiary, weiAmount);
  }

  // -----------------------------------------
  // Internal interface (extensible)
  // -----------------------------------------

  /**
   * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use super to concatenate validations.
   * @param _beneficiary Address performing the token purchase
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
    require(_beneficiary != address(0));
    require(_weiAmount != 0);
  }

  /**
   * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met.
   * @param _beneficiary Address performing the token purchase
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _postValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
    // optional override
  }

  /**
   * @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends tokens.
   * @param _beneficiary Address receiving the tokens
   * @param _weiAmount Number of wei contributed
   */
  function _processPurchaseInWei(address _beneficiary, uint256 _weiAmount) internal {
    // override with logic on tokens delivery
  }

  /**
   * @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.)
   * @param _beneficiary Address receiving the tokens
   * @param _weiAmount Value in wei involved in the purchase
   */
  function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal {
    // optional override
  }

  /**
   * @dev Determines how ETH is stored/forwarded on purchases.
   */
  function _forwardFunds() internal {
    wallet.transfer(msg.value);
  }
}
/**
 * @title TokenlessCrowdsale
 * @dev Crowdsale based on OpenZeppelin's Crowdsale but without token-related logic
 * @author U-Zyn Chua <uzyn@zynesis.com>
 *
 * Largely similar to OpenZeppelin except the following irrelevant token-related hooks removed:
 * - function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal
 * - function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal
 * - function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256)
 * - event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount)
 *
 * Added hooks:
 * - function _processPurchaseInWei(address _beneficiary, uint256 _weiAmount) internal
 * - event SaleContribution(address indexed purchaser, address indexed beneficiary, uint256 value)
 */
function buyTokens(address _beneficiary) public payable {

  uint256 weiAmount = msg.value;
  _preValidatePurchase(_beneficiary, weiAmount);

  // update state
  weiRaised = weiRaised.add(weiAmount);

  _processPurchaseInWei(_beneficiary, weiAmount);
  emit SaleContribution(
    msg.sender,
    _beneficiary,
    weiAmount
  );

  _updatePurchasingState(_beneficiary, weiAmount);

  _forwardFunds();
  _postValidatePurchase(_beneficiary, weiAmount);
}

/**
 * @dev low level token purchase ***DO NOT OVERRIDE***
 * @param _beneficiary Address performing the token purchase
 */