-
Notifications
You must be signed in to change notification settings - Fork 4
/
AtomicSwapEther.sol
139 lines (118 loc) · 4.36 KB
/
AtomicSwapEther.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
pragma solidity ^0.4.24;
contract AtomicSwapEther {
struct Swap {
uint256 timelock;
uint256 value;
address ethTrader;
address withdrawTrader;
bytes32 secretLock;
string secretKey;
}
enum States {
INVALID,
INITIATE,
OPEN,
CLOSED,
EXPIRED
}
mapping (bytes32 => Swap) private swaps;
mapping (bytes32 => States) private swapStates;
event Participate(bytes32 _swapID, address _withdrawTrader,bytes32 _secretLock);
event Initiate(bytes32 _swapID, bytes32 _secretLock);
event Expire(bytes32 _swapID);
event Close(bytes32 _swapID, string _secretKey);
modifier onlyInvalidSwaps(bytes32 _swapID) {
require (swapStates[_swapID] == States.INVALID, "modifier throws : onlyInvalid");
_;
}
modifier onlyInitiateSwaps(bytes32 _swapID) {
require (swapStates[_swapID] == States.INITIATE, "modifier throws : onlyInitiate");
_;
}
modifier onlyOpenSwaps(bytes32 _swapID) {
require (swapStates[_swapID] == States.OPEN, "modifier throws : onlyOpen");
_;
}
modifier onlyClosedSwaps(bytes32 _swapID) {
require (swapStates[_swapID] == States.CLOSED, "modifier throws : onlyClosed");
_;
}
modifier onlyExpirableSwaps(bytes32 _swapID) {
require (now >= swaps[_swapID].timelock, "modifier throws : onlyExpirable");
_;
}
modifier onlyWithSecretKey(bytes32 _swapID, string _secretKey) {
require(swaps[_swapID].secretLock == sha256(abi.encodePacked(_secretKey)), "modifier throws : onlyWithSecretKey");
_;
}
modifier onlyInitiator(bytes32 _swapID) {
require(swaps[_swapID].ethTrader == msg.sender, "modifier throws : onlyInitiator");
_;
}
modifier onlywithdrawTrader(bytes32 _swapID) {
require(swaps[_swapID].withdrawTrader == msg.sender, "modifier throws : onlyWithdrawer");
_;
}
function participate(bytes32 _swapID,address _withdrawTrader,bytes32 _secretLock,uint256 _timelock)
public onlyInvalidSwaps(_swapID) payable {
// Store the details of the swap.
Swap memory swap = Swap({
timelock: _timelock + now,
value: msg.value,
ethTrader: msg.sender,
withdrawTrader: _withdrawTrader,
secretLock: _secretLock,
secretKey: ""
});
swaps[_swapID] = swap;
swapStates[_swapID] = States.OPEN;
// Trigger open event.
emit Participate(_swapID, _withdrawTrader, _secretLock);
}
function initiate(bytes32 _swapID, bytes32 _secretLock, uint256 _timelock) public onlyInvalidSwaps(_swapID) payable {
// Store the details of the swap.
Swap memory swap = Swap({
timelock: _timelock + now,
value: msg.value,
ethTrader: msg.sender,
withdrawTrader: msg.sender,
secretLock: _secretLock,
secretKey: ""
});
swaps[_swapID] = swap;
swapStates[_swapID] = States.INITIATE;
// Trigger open event.
emit Initiate(_swapID, _secretLock);
}
function setWithdrawTrader(bytes32 _swapID, address _withdrawTrader) public onlyInitiator(_swapID) onlyInitiateSwaps(_swapID){
swaps[_swapID].withdrawTrader = _withdrawTrader;
swapStates[_swapID] = States.OPEN;
}
function close(bytes32 _swapID, string _secretKey) public onlyOpenSwaps(_swapID) onlyWithSecretKey(_swapID, _secretKey) onlywithdrawTrader(_swapID){
// Close the swap.
Swap memory swap = swaps[_swapID];
swaps[_swapID].secretKey = _secretKey;
swapStates[_swapID] = States.CLOSED;
// Transfer the ETH funds from this contract to the withdrawing trader.
swap.withdrawTrader.transfer(swap.value);
// Trigger close event.
emit Close(_swapID, _secretKey);
}
function expire(bytes32 _swapID) public onlyOpenSwaps(_swapID) onlyExpirableSwaps(_swapID) onlyInitiator(_swapID) {
// Expire the swap.
Swap memory swap = swaps[_swapID];
swapStates[_swapID] = States.EXPIRED;
// Transfer the ETH value from this contract back to the ETH trader.
swap.ethTrader.transfer(swap.value);
// Trigger expire event.
emit Expire(_swapID);
}
function check(bytes32 _swapID) public view returns (uint256 timelock, uint256 value, address withdrawTrader, bytes32 secretLock) {
Swap memory swap = swaps[_swapID];
return (swap.timelock, swap.value, swap.withdrawTrader, swap.secretLock);
}
function checkSecretKey(bytes32 _swapID) public view onlyClosedSwaps(_swapID) returns (string secretKey) {
Swap memory swap = swaps[_swapID];
return swap.secretKey;
}
}