-
Notifications
You must be signed in to change notification settings - Fork 0
/
Escrow.sol
117 lines (100 loc) · 4.09 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
pragma solidity 0.4.24;
pragma experimental "v0.5.0";
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
contract SRNTPriceOracleBasic {
uint256 public SRNT_per_ETH;
}
contract Escrow {
using SafeMath for uint256;
address public party_a;
address public party_b;
address constant serenity_wallet = 0x47c8F28e6056374aBA3DF0854306c2556B104601;
address constant burn_address = 0x0000000000000000000000000000000000000001;
ERC20Basic constant SRNT_token = ERC20Basic(0xBC7942054F77b82e8A71aCE170E4B00ebAe67eB6);
SRNTPriceOracleBasic constant SRNT_price_oracle = SRNTPriceOracleBasic(0xae5D95379487d047101C4912BddC6942090E5D17);
uint256 public withdrawal_party_a_gets;
uint256 public withdrawal_party_b_gets;
address public withdrawal_last_voter;
event Deposit(uint256 amount);
event WithdrawalRequest(address requester, uint256 party_a_gets, uint256 party_b_gets);
event Withdrawal(uint256 party_a_gets, uint256 party_b_gets);
constructor (address new_party_a, address new_party_b) public {
party_a = new_party_a;
party_b = new_party_b;
}
function () external payable {
// New deposit - take commission and issue an event
uint256 fee = msg.value.div(100);
uint256 srnt_balance = SRNT_token.balanceOf(address(this));
uint256 fee_paid_by_srnt = srnt_balance.div(SRNT_price_oracle.SRNT_per_ETH());
if (fee_paid_by_srnt < fee) { // Burn all SRNT, deduct from fee
if (fee_paid_by_srnt > 0) {
fee = fee.sub(fee_paid_by_srnt);
SRNT_token.transfer(burn_address, srnt_balance);
}
serenity_wallet.transfer(fee);
emit Deposit(msg.value.sub(fee));
} else { // There's more SRNT available than needed. Burn a part of it.
SRNT_token.transfer(burn_address, fee.mul(SRNT_price_oracle.SRNT_per_ETH()));
emit Deposit(msg.value);
}
}
function request_withdrawal(uint256 party_a_gets, uint256 party_b_gets) external {
require(msg.sender != withdrawal_last_voter); // You can't vote twice
require((msg.sender == party_a) || (msg.sender == party_b) || (msg.sender == serenity_wallet));
require(party_a_gets.add(party_b_gets) <= address(this).balance);
withdrawal_last_voter = msg.sender;
emit WithdrawalRequest(msg.sender, party_a_gets, party_b_gets);
if ((withdrawal_party_a_gets == party_a_gets) && (withdrawal_party_b_gets == party_b_gets)) { // We have consensus
delete withdrawal_party_a_gets;
delete withdrawal_party_b_gets;
delete withdrawal_last_voter;
if (party_a_gets > 0) {
party_a.transfer(party_a_gets);
}
if (party_b_gets > 0) {
party_b.transfer(party_b_gets);
}
emit Withdrawal(party_a_gets, party_b_gets);
} else {
withdrawal_party_a_gets = party_a_gets;
withdrawal_party_b_gets = party_b_gets;
}
}
}