-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathSysEscrow_0x903643251aF408A3C5269c836B9A2A4a1F04d1CF.sol
172 lines (131 loc) · 5.41 KB
/
SysEscrow_0x903643251aF408A3C5269c836B9A2A4a1F04d1CF.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
*Submitted for verification at Etherscan.io on 2018-02-04
*/
pragma solidity ^0.4.18;
contract SysEscrow {
address public owner;
address arbitrator;
uint public MinDeposit = 600000000000000000; // 0.6 Ether
uint constant ARBITRATOR_PERCENT = 1; //1%
struct Escrow {
// Set so we know the trade has already been created
bool exists;
address seller;
address buyer;
uint summ;
uint buyerCanCancelAfter;
bool buyerApprovedTheTransaction;
bool arbitratorStopTransaction;
}
// Mapping of active trades. Key is a hash of the trade data
mapping (bytes32 => Escrow) public escrows;
modifier onlyOwner() {
require(tx.origin == owner);
_;
}
function SysEscrow() {
owner = msg.sender;
arbitrator = msg.sender;
}
function createEscrow(
/**
* Create a new escrow and add it to `escrows`.
* _tradeHash is created by hashing _tradeID, _seller, _buyer, _value and _fee variables. These variables must be supplied on future contract calls.
* v, r and s is the signature data supplied from the api. The sig is keccak256(_tradeHash, _paymentWindowInSeconds, _expiry).
*/
bytes16 _tradeID, // The unique ID of the trade
address _seller, // The selling party of the trade
address _buyer, // The buying party of the trade
uint _paymentWindowInSeconds // The time in seconds from Escrow creation that the buyer can return money
) payable external {
uint256 _value = msg.value;
require(_value>=MinDeposit);
bytes32 _tradeHash = keccak256(_tradeID, _seller, _buyer, _value);
require(!escrows[_tradeHash].exists); // Require that trade does not already exist
uint _buyerCanCancelAfter = now + _paymentWindowInSeconds;
escrows[_tradeHash] = Escrow(true, _seller, _buyer, _value, _buyerCanCancelAfter, false, false);
}
function setArbitrator( address _newArbitrator ) onlyOwner {
/**
* Set the arbitrator to a new address. Only the owner can call this.
* @param address _newArbitrator
*/
arbitrator = _newArbitrator;
}
function setOwner(address _newOwner) onlyOwner external {
/**
* Change the owner to a new address. Only the owner can call this.
* @param address _newOwner
*/
owner = _newOwner;
}
function cancelEscrow(
/**
* Cancel escrow. Return money to buyer
*/
bytes16 _tradeID, // The unique ID of the trade
address _seller, // The selling party of the trade
address _buyer, // The buying party of the trade
uint256 _value //
) external {
bytes32 _tradeHash = keccak256(_tradeID, _seller, _buyer, _value);
require(escrows[_tradeHash].exists);
require(escrows[_tradeHash].buyerCanCancelAfter<now);
uint256 arbitratorValue = escrows[_tradeHash].summ*ARBITRATOR_PERCENT/100;
uint256 buyerValue = escrows[_tradeHash].summ - arbitratorValue;
bool buyerReceivedMoney = escrows[_tradeHash].buyer.call.value(buyerValue)();
bool arbitratorReceivedMoney = arbitrator.call.value(arbitratorValue)();
if ( buyerReceivedMoney && arbitratorReceivedMoney )
{
delete escrows[_tradeHash];
} else {
throw;
}
}
function approveEscrow(
/**
* Approve escrow.
*/
bytes16 _tradeID, // The unique ID of the trade
address _seller, // The selling party of the trade
address _buyer, // The buying party of the trade
uint256 _value // Trade value
) external {
bytes32 _tradeHash = keccak256(_tradeID, _seller, _buyer, _value);
require(escrows[_tradeHash].exists);
require(escrows[_tradeHash].buyer==msg.sender);
escrows[_tradeHash].buyerApprovedTheTransaction = true;
}
function releaseEscrow(
/**
* Release escrow. Send money to seller
*/
bytes16 _tradeID, // The unique ID of the trade
address _seller, // The selling party of the trade
address _buyer, // The buying party of the trade
uint256 _value // Trade value
) external {
bytes32 _tradeHash = keccak256(_tradeID, _seller, _buyer, _value);
require(escrows[_tradeHash].exists);
require(escrows[_tradeHash].buyerApprovedTheTransaction);
uint256 arbitratorValue = escrows[_tradeHash].summ*ARBITRATOR_PERCENT/100;
uint256 buyerValue = escrows[_tradeHash].summ - arbitratorValue;
bool sellerReceivedMoney = escrows[_tradeHash].seller.call.value(buyerValue)();
bool arbitratorReceivedMoney = arbitrator.call.value(arbitratorValue)();
if ( sellerReceivedMoney && arbitratorReceivedMoney )
{
delete escrows[_tradeHash];
} else {
throw;
}
}
function isExistsEscrow(
bytes16 _tradeID, // The unique ID of the trade
address _seller, // The selling party of the trade
address _buyer, // The buying party of the trade
uint256 _value // Trade value
) constant returns (bool es) {
bytes32 _tradeHash = keccak256(_tradeID, _seller, _buyer, _value);
return escrows[_tradeHash].exists;
}
}