-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmixin.sol
143 lines (116 loc) · 4.43 KB
/
mixin.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
pragma solidity ^0.4.24;
interface TokenERC20 {
function transfer(address _to, uint256 _value) external returns(bool);
function transferFrom(address _from, address _to, uint256 _value) external returns(bool);
}
contract tokenMixin {
using SafeMath for uint256;
mapping(address => uint256) public balanceOf;
address tokenAddress;
TokenERC20 token;
constructor(address _token) public{
tokenAddress = _token;
token = TokenERC20(tokenAddress);
}
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external{
require(msg.sender == tokenAddress);
require(_token == tokenAddress);
_extraData;
require(token.transferFrom(_from,address(this),_value));
balanceOf[_from] = balanceOf[_from].add(_value);
}
function deposit(uint256 _value) public {
address _from = msg.sender;
require(token.transferFrom(_from,address(this),_value));
balanceOf[_from] = balanceOf[_from].add(_value);
}
function withdraw(uint256 _value) public {
address _to = msg.sender;
balanceOf[_to] = balanceOf[_to].sub(_value);
require(token.transfer(_to,_value));
}
function mix (address[] from, address[] to, uint256[] out, uint256[] _in, uint8[] v,bytes32[] r,bytes32[] s) public {
uint256 totalOut;
uint256 totalIn;
require(from.length == out.length);
require(to.length == _in.length);
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 digest = keccak256(abi.encodePacked(from, to, out, _in,address(this)));
bytes32 txHash = keccak256(abi.encodePacked(prefix,digest));
for (uint256 i = 0; i < from.length; i++){
require(ecrecover(txHash,v[i],r[i],s[i]) == from[i]);
}
for (i = 0; i < from.length; i++){
address f = from[i];
balanceOf[f] = balanceOf[f].sub(out[i]);
totalOut = totalOut.add(out[i]);
}
for(i = 0; i < to.length; i++){
address t =to[i];
balanceOf[t] = balanceOf[t].add(_in[i]);
totalIn = totalIn.add(out[i]);
}
require(totalIn == totalOut);
}
}
contract etherMixin {
using SafeMath for uint256;
mapping(address => uint256) public balanceOf;
function deposit() public payable {
address _from = msg.sender;
balanceOf[_from] = balanceOf[_from].add(msg.value);
}
function withdraw(uint256 _value) public {
address _to = msg.sender;
balanceOf[_to] = balanceOf[_to].sub(_value);
_to.transfer(_value);
}
function mix (address[] from, address[] to, uint256[] out, uint256[] _in, uint8[] v,bytes32[] r,bytes32[] s) public {
uint256 totalOut;
uint256 totalIn;
require(from.length == out.length);
require(to.length == _in.length);
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 digest = keccak256(abi.encodePacked(from, to, out, _in,address(this)));
bytes32 txHash = keccak256(abi.encodePacked(prefix,digest));
for (uint256 i = 0; i < from.length; i++){
require(ecrecover(txHash,v[i],r[i],s[i]) == from[i]);
}
for (i = 0; i < from.length; i++){
address f = from[i];
balanceOf[f] = balanceOf[f].sub(out[i]);
totalOut = totalOut.add(out[i]);
}
for(i = 0; i < to.length; i++){
address t = to[i];
balanceOf[t] = balanceOf[t].add(_in[i]);
totalIn = totalIn.add(out[i]);
}
require(totalIn == totalOut);
}
}
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(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;
}
}