forked from smartexio/smartex-contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SmartexFundManager.sol
173 lines (156 loc) · 4.5 KB
/
SmartexFundManager.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
173
/**
* @notice Smartex Funds Manager
* @author Christopher Moore [email protected] - Smartex.io Ltd. 2016-2017 - https://smartex.io
*/
contract SmartexFundsManager is owned {
mapping(uint => Fund) funds;
/**
* @notice Fund
*/
struct Fund {
mapping(uint => Shareholder) shareholders;
uint balance;
uint totalShares;
uint totalShareholders;
uint sharesLeft;
}
/**
* @notice Shareholder
*/
struct Shareholder {
address payoutAccount;
uint shares;
}
/**
* @notice Incoming transaction Event
*/
event IncomingTx(
uint indexed blockNumber,
address sender,
uint value,
uint timestamp
);
/**
* @notice Outgoing transaction Event
*/
event OutgoingTx(
uint indexed blockNumber,
address recipient,
uint value,
uint timestamp
);
/**
* @notice Dividend error event
*/
event DividendError(
uint id,
uint startOffset,
uint stopOffset,
uint balance,
uint dividend,
uint timestamp
);
/**
* @notice Settlement error event
*/
event NewShareholder(
uint id,
address account,
uint shares,
uint timestamp
);
/**
* @notice Contract constructor
*/
function SmartexFundsManager() {
funds[0] = Fund(0, 1000000, 0, 1000000);
}
/**
* @notice Add a shareholder
* @param payoutAccount (Shareholder payout address)
* @param shares (Shareholder number of shares)
*/
function addShareholder(address payoutAccount, uint shares) onlyOwner {
Fund f = funds[0];
if (shares <= f.sharesLeft) {
f.shareholders[f.totalShareholders] = Shareholder({
payoutAccount: payoutAccount,
shares: shares
});
f.sharesLeft -= shares;
++f.totalShareholders;
NewShareholder(f.totalShareholders, payoutAccount, shares, now);
} else {
//no more shares left
throw;
}
}
/**
* @notice Pay dividends to shareholders
* @param startOffset ()
* @param stopOffset ()
* @param value (value in wei)
*/
function payDividends(uint startOffset, uint stopOffset, uint value) onlyOwner {
Fund f = funds[0];
for (uint i = startOffset; i < stopOffset; i++) {
Shareholder s = f.shareholders[i];
uint dividend = (value * s.shares);
if (this.balance >= dividend) {
if (s.payoutAccount.send(dividend)) {
OutgoingTx(block.number, s.payoutAccount, dividend, now);
} else {
DividendError(i, startOffset, stopOffset, this.balance, dividend, now);
throw;
}
} else {
//not enough funds left
DividendError(i, startOffset, stopOffset, this.balance, dividend, now);
}
}
}
/**
* @notice Pay dividend to shareholder
* @param shareholderId ()
* @param value (value in wei)
*/
function payDividend(uint shareholderId, uint value) onlyOwner {
Fund f = funds[0];
Shareholder s = f.shareholders[shareholderId];
uint dividend = (value * s.shares);
if (this.balance >= dividend) {
if (s.payoutAccount.send(dividend)) {
OutgoingTx(block.number, s.payoutAccount, dividend, now);
} else {
DividendError(shareholderId, 0, 0, this.balance, dividend, now);
throw;
}
} else {
//not enough funds left
DividendError(shareholderId, 0, 0, this.balance, dividend, now);
}
}
/**
* @notice Sweep funds
* @param _to (Funds recipient)
*/
function sweep(address _to) payable onlyOwner {
if (!_to.send(this.balance)) throw;
}
/**
* @notice Advanced send
* @param _to (transaction Recipient)
* @param _value (transaction value)
* @param _data (additional payload)
*/
function advSend(address _to, uint _value, bytes _data) onlyOwner {
_to.call.value(_value)(_data);
}
/**
* @notice anonymous function
* @notice Triggered by invalid function calls and incoming transactions
*/
function() payable {
IncomingTx(block.number, msg.sender, msg.value, now);
}
}