-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathmultisend.sol
More file actions
174 lines (137 loc) · 4.97 KB
/
multisend.sol
File metadata and controls
174 lines (137 loc) · 4.97 KB
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
173
174
pragma solidity 0.4.24;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asserts 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;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
contract Token {
uint8 public decimals;
function transfer(address _to, uint256 _value) public returns (bool success) {}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {}
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {}
}
contract BulkSend {
using SafeMath for uint256;
address public owner;
uint public tokenSendFee; // in wei
uint public ethSendFee; // in wei
constructor() public payable{
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function bulkSendEth(address[] addresses, uint256[] amounts) public payable returns(bool success){
uint total = 0;
for(uint8 i = 0; i < amounts.length; i++){
total = total.add(amounts[i]);
}
//ensure that the ethreum is enough to complete the transaction
uint requiredAmount = total.add(ethSendFee * 1 wei); //.add(total.div(100));
require(msg.value >= (requiredAmount * 1 wei));
//transfer to each address
for (uint8 j = 0; j < addresses.length; j++) {
addresses[j].transfer(amounts[j] * 1 wei);
}
//return change to the sender
if(msg.value * 1 wei > requiredAmount * 1 wei){
uint change = msg.value.sub(requiredAmount);
msg.sender.transfer(change * 1 wei);
}
return true;
}
function getbalance(address addr) public constant returns (uint value){
return addr.balance;
}
function deposit() payable public returns (bool){
return true;
}
function withdrawEther(address addr, uint amount) public onlyOwner returns(bool success){
addr.transfer(amount * 1 wei);
return true;
}
function withdrawToken(Token tokenAddr, address _to, uint _amount) public onlyOwner returns(bool success){
tokenAddr.transfer(_to, _amount );
return true;
}
function bulkSendToken(Token tokenAddr, address[] addresses, uint256[] amounts) public payable returns(bool success){
uint total = 0;
address multisendContractAddress = this;
for(uint8 i = 0; i < amounts.length; i++){
total = total.add(amounts[i]);
}
require(msg.value * 1 wei >= tokenSendFee * 1 wei);
// check if user has enough balance
require(total <= tokenAddr.allowance(msg.sender, multisendContractAddress));
// transfer token to addresses
for (uint8 j = 0; j < addresses.length; j++) {
tokenAddr.transferFrom(msg.sender, addresses[j], amounts[j]);
}
// transfer change back to the sender
if(msg.value * 1 wei > (tokenSendFee * 1 wei)){
uint change = (msg.value).sub(tokenSendFee);
msg.sender.transfer(change * 1 wei);
}
return true;
}
function setTokenFee(uint _tokenSendFee) public onlyOwner returns(bool success){
tokenSendFee = _tokenSendFee;
return true;
}
function setEthFee(uint _ethSendFee) public onlyOwner returns(bool success){
ethSendFee = _ethSendFee;
return true;
}
function destroy (address _to) public onlyOwner {
selfdestruct(_to);
}
}