pragma solidity ^0.4.23; import "./ConditionalEscrow.sol"; import "../ownership/Ownable.sol"; /** * @title RefundEscrow * @dev Escrow that holds funds for a beneficiary, deposited from multiple parties. * The contract owner may close the deposit period, and allow for either withdrawal * by the beneficiary, or refunds to the depositors. */ contract RefundEscrow is Ownable, ConditionalEscrow { enum State { Active, Refunding, Closed } event Closed(); event RefundsEnabled(); State public state; address public beneficiary; /** * @dev Constructor. * @param _beneficiary The beneficiary of the deposits. */ constructor(address _beneficiary) public { require(_beneficiary != address(0)); beneficiary = _beneficiary; state = State.Active; } /** * @dev Stores funds that may later be refunded. * @param _refundee The address funds will be sent to if a refund occurs. */ function deposit(address _refundee) public payable { require(state == State.Active); super.deposit(_refundee); } /** * @dev Allows for the beneficiary to withdraw their funds, rejecting * further deposits. */ function close() public onlyOwner { require(state == State.Active); state = State.Closed; emit Closed(); } /** * @dev Allows for refunds to take place, rejecting further deposits. */ function enableRefunds() public onlyOwner { require(state == State.Active); state = State.Refunding; emit RefundsEnabled(); } /** * @dev Withdraws the beneficiary's funds. */ function beneficiaryWithdraw() public { require(state == State.Closed); beneficiary.transfer(address(this).balance); } /** * @dev Returns whether refundees can withdraw their deposits (be refunded). */ function withdrawalAllowed(address _payee) public view returns (bool) { return state == State.Refunding; } }