-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathEscrow.sol
152 lines (126 loc) · 4.49 KB
/
Escrow.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
pragma solidity ^0.4.21;
import "./Ownable.sol";
/**
* Escrow smart contract serves 3 parties.
*
* Judge = is able to move funds to flexiana or customer.
* Customer = Flexiana's client
* Flexiana = we
*
* After creating contract, setAddressesOnce() have to be called.
*
* @author Jiri Knesl <jiri@flexiana.com>
*/
contract Escrow is Ownable
{
/*** SECTION: Internal state & modifiers */
enum Statuses {DoNothing, ShouldTransferToCustomer, ShouldTransferToFlexiana}
bool public addressChanged = false;
address public customer;
address public flexiana;
// address public owner; // owner = independent judge
Escrow.Statuses public customerStatus = Statuses.DoNothing;
Escrow.Statuses public flexianaStatus = Statuses.DoNothing;
modifier onlyCustomer() {
require(msg.sender == customer);
_;
}
modifier onlyFlexiana() {
require(msg.sender == flexiana);
_;
}
/*** SECTION: Initialization */
/**
* After intitialization setAddressesOnce is called with all members addresses.
* This method can be called only once and only by contract creator.
*/
function setAddressesOnce(address judge, address newFlexiana, address newCustomer) public onlyOwner {
require(! addressChanged);
addressChanged = true;
owner = judge;
flexiana = newFlexiana;
customer = newCustomer;
}
/*** SECTION: Changing customer status */
function changeCustomerStatus(Escrow.Statuses newStatus) internal onlyCustomer {
customerStatus = newStatus;
}
/**
* Called when customer wants funds to stay in the Escrow
*/
function changeCustomerStatusToDoNothing() public onlyCustomer {
changeCustomerStatus(Statuses.DoNothing);
}
/**
* Called when customer wants to return funds back.
*/
function changeCustomerStatusToShouldTransferToCustomer() public onlyCustomer {
changeCustomerStatus(Statuses.ShouldTransferToCustomer);
}
/**
* Called when customer wants to transfer funds to flexiana.
*/
function changeCustomerStatusToShouldTransferToFlexiana() public onlyCustomer {
changeCustomerStatus(Statuses.ShouldTransferToFlexiana);
}
/*** SECTION: Changing Flexiana status */
function changeFlexianaStatus(Escrow.Statuses newStatus) internal onlyFlexiana {
flexianaStatus = newStatus;
}
/**
* Flexiana wants to hold funds in the escrow.
*/
function changeFlexianaStatusToDoNothing() public onlyFlexiana {
changeFlexianaStatus(Statuses.DoNothing);
}
/**
* Flexiana wants to send funds back to customer.
*/
function changeFlexianaStatusToShouldTransferToCustomer() public onlyFlexiana {
changeFlexianaStatus(Statuses.ShouldTransferToCustomer);
}
/**
* Client wants to return money.
*/
function changeFlexianaStatusToShouldTransferToFlexiana() public onlyFlexiana {
changeFlexianaStatus(Statuses.ShouldTransferToFlexiana);
}
/*** SECTION: Deposits */
/**
* Let's save amount in smart contract.
*/
function deposit() public payable {
}
/**
* Safer way how to store funds. It requires only customer to deposit funds.
*/
function customerDeposit() public payable onlyCustomer {
}
/*** SECTION: Transfers */
/**
* If Flexiana agrees or if judge decides, funds are transfered do customer.
*/
function transferToCustomer() public {
require(flexianaStatus == Statuses.ShouldTransferToCustomer || msg.sender == owner);
customer.transfer(address(this).balance);
}
/**
* If client agrees or if judge decides, funds are transfered to flexiana.
*/
function transferToFlexiana() public {
require(customerStatus == Statuses.ShouldTransferToCustomer || msg.sender == owner);
flexiana.transfer(address(this).balance);
}
/**
* Withdraw funds to party that should have funds.
*/
function withdraw() public {
require(flexianaStatus != Statuses.DoNothing && flexianaStatus == customerStatus);
require(msg.sender == owner || msg.sender == flexiana || msg.sender == customer);
if (flexianaStatus == Statuses.ShouldTransferToCustomer) {
customer.transfer(address(this).balance);
} else if (flexianaStatus == Statuses.ShouldTransferToFlexiana) {
flexiana.transfer(address(this).balance);
}
}
}