|
|
|
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 private state_;
|
|
|
|
address private beneficiary_;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dev Constructor.
|
|
|
|
* @param _beneficiary The beneficiary of the deposits.
|
|
|
|
*/
|
|
|
|
constructor(address _beneficiary) public {
|
|
|
|
require(_beneficiary != address(0));
|
|
|
|
beneficiary_ = _beneficiary;
|
|
|
|
state_ = State.Active;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the current state of the escrow.
|
|
|
|
*/
|
|
|
|
function state() public view returns(State) {
|
|
|
|
return state_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the beneficiary of the escrow.
|
|
|
|
*/
|
|
|
|
function beneficiary() public view returns(address) {
|
|
|
|
return beneficiary_;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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;
|
|
|
|
}
|
|
|
|
}
|