/
LCX_CIF.sol
334 lines (231 loc) · 9.6 KB
/
LCX_CIF.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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
pragma solidity ^0.4.19;
/*
Copyright 2018, Vicent Nos, Enrique Santos & Mireia Puig
License:
https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
*/
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;
}
}
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function Ownable() internal {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
//////////////////////////////////////////////////////////////
// //
// Lescovex, Open End Crypto Fund ERC20 //
// //
//////////////////////////////////////////////////////////////
contract LescovexERC20 is Ownable {
using SafeMath for uint256;
mapping (address => uint256) public balances;
mapping (address => uint256) public requestWithdraws;
mapping (address => mapping (address => uint256)) internal allowed;
mapping (address => timeHold) holded;
struct timeHold{
uint256[] amount;
uint256[] time;
uint256 length;
}
/* Public variables for the ERC20 token */
string public constant standard = "ERC20 Lescovex CIF";
uint8 public constant decimals = 8; // hardcoded to be a constant
uint256 public totalSupply;
string public name;
string public symbol;
uint256 public holdTime;
uint256 public holdMax;
uint256 public maxSupply;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
function holdedOf(address _owner, uint256 n) public view returns (uint256) {
return holded[_owner].amount[n];
}
function hold(address _to, uint256 _value) internal {
holded[_to].amount.push(_value);
holded[_to].time.push(block.number);
holded[_to].length++;
}
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
delete holded[msg.sender];
hold(msg.sender, balances[msg.sender]);
hold(_to,_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
delete holded[_from];
hold(_from, balances[_from]);
hold(_to,_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(_from, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/* Approve and then communicate the approved contract in a single tx */
function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
}
}
interface tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external ;
}
contract Lescovex_CIF is LescovexERC20 {
// Contract variables and constants
uint256 public tokenPrice = 0;
// constant to simplify conversion of token amounts into integer form
uint256 public tokenUnit = uint256(10)**decimals;
//Declare logging events
event LogDeposit(address sender, uint amount);
/* Initializes contract with initial supply tokens to the creator of the contract */
function Lescovex_CIF(
uint256 initialSupply,
string contractName,
string tokenSymbol,
uint256 contractHoldTime,
uint256 contractHoldMax,
uint256 contractMaxSupply,
address contractOwner
) public {
totalSupply = initialSupply; // Update total supply
name = contractName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
holdTime=contractHoldTime;
holdMax=contractHoldMax;
maxSupply=contractMaxSupply;
owner=contractOwner;
balances[contractOwner]= balances[contractOwner].add(totalSupply);
}
function () public payable {
buy(); // Allow to buy tokens sending ether directly to contract
}
uint256 public contractBalance=0;
function deposit() external payable onlyOwner returns(bool success) {
// Check for overflows;
assert (this.balance + msg.value >= this.balance); // Check for overflows
contractBalance=this.balance;
//executes event to reflect the changes
LogDeposit(msg.sender, msg.value);
return true;
}
function withdrawReward() external {
uint i = 0;
uint256 ethAmount = 0;
uint256 len = holded[msg.sender].length;
while (i <= len - 1){
if (block.number - holded[msg.sender].time[i] > holdTime && block.number - holded[msg.sender].time[i] < holdMax){
ethAmount += tokenPrice * holded[msg.sender].amount[i];
}
i++;
}
require(ethAmount > 0);
require(ethAmount>=(tokenPrice*requestWithdraws[msg.sender]));
LogWithdrawal(msg.sender, ethAmount);
totalSupply = totalSupply.sub(requestWithdraws[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(requestWithdraws[msg.sender]);
Transfer(msg.sender, this, requestWithdraws[msg.sender]);
delete holded[msg.sender];
hold(msg.sender,balances[msg.sender]);
msg.sender.transfer(tokenPrice*requestWithdraws[msg.sender]/tokenUnit);
}
function setPrice(uint256 _value) public onlyOwner{
tokenPrice=_value;
delete holded;
}
event LogWithdrawal(address receiver, uint amount);
function requestWithdraw(uint value) public {
require(value <= balances[msg.sender]);
delete holded[msg.sender];
hold(msg.sender, value);
requestWithdraws[msg.sender]=value;
//executes event ro register the changes
}
function buy() public payable {
require(totalSupply <= maxSupply);
uint256 tokenAmount = (msg.value * tokenUnit) / tokenPrice ; // calculates the amount
transferBuy(msg.sender, tokenAmount);
owner.transfer(msg.value);
}
function transferBuy(address _to, uint256 _value) internal returns (bool) {
require(_to != address(0));
// SafeMath.add will throw if there is not enough balance.
totalSupply = totalSupply.add(_value);
hold(_to,_value);
balances[_to] = balances[_to].add(_value);
Transfer(this, _to, _value);
return true;
}
}