RefundEscrow.sol 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. pragma solidity ^0.5.0;
  2. import "./ConditionalEscrow.sol";
  3. /**
  4. * @title RefundEscrow
  5. * @dev Escrow that holds funds for a beneficiary, deposited from multiple
  6. * parties.
  7. * @dev Intended usage: See Escrow.sol. Same usage guidelines apply here.
  8. * @dev The primary account (that is, the contract that instantiates this
  9. * contract) may deposit, close the deposit period, and allow for either
  10. * withdrawal by the beneficiary, or refunds to the depositors. All interactions
  11. * with RefundEscrow will be made through the primary contract. See the
  12. * RefundableCrowdsale contract for an example of RefundEscrow’s use.
  13. */
  14. contract RefundEscrow is ConditionalEscrow {
  15. enum State { Active, Refunding, Closed }
  16. event RefundsClosed();
  17. event RefundsEnabled();
  18. State private _state;
  19. address payable private _beneficiary;
  20. /**
  21. * @dev Constructor.
  22. * @param beneficiary The beneficiary of the deposits.
  23. */
  24. constructor (address payable beneficiary) public {
  25. require(beneficiary != address(0), "RefundEscrow: beneficiary is the zero address");
  26. _beneficiary = beneficiary;
  27. _state = State.Active;
  28. }
  29. /**
  30. * @return The current state of the escrow.
  31. */
  32. function state() public view returns (State) {
  33. return _state;
  34. }
  35. /**
  36. * @return The beneficiary of the escrow.
  37. */
  38. function beneficiary() public view returns (address) {
  39. return _beneficiary;
  40. }
  41. /**
  42. * @dev Stores funds that may later be refunded.
  43. * @param refundee The address funds will be sent to if a refund occurs.
  44. */
  45. function deposit(address refundee) public payable {
  46. require(_state == State.Active, "RefundEscrow: can only deposit while active");
  47. super.deposit(refundee);
  48. }
  49. /**
  50. * @dev Allows for the beneficiary to withdraw their funds, rejecting
  51. * further deposits.
  52. */
  53. function close() public onlyPrimary {
  54. require(_state == State.Active, "RefundEscrow: can only close while active");
  55. _state = State.Closed;
  56. emit RefundsClosed();
  57. }
  58. /**
  59. * @dev Allows for refunds to take place, rejecting further deposits.
  60. */
  61. function enableRefunds() public onlyPrimary {
  62. require(_state == State.Active, "RefundEscrow: can only enable refunds while active");
  63. _state = State.Refunding;
  64. emit RefundsEnabled();
  65. }
  66. /**
  67. * @dev Withdraws the beneficiary's funds.
  68. */
  69. function beneficiaryWithdraw() public {
  70. require(_state == State.Closed, "RefundEscrow: beneficiary can only withdraw while closed");
  71. _beneficiary.transfer(address(this).balance);
  72. }
  73. /**
  74. * @dev Returns whether refundees can withdraw their deposits (be refunded). The overridden function receives a
  75. * 'payee' argument, but we ignore it here since the condition is global, not per-payee.
  76. */
  77. function withdrawalAllowed(address) public view returns (bool) {
  78. return _state == State.Refunding;
  79. }
  80. }