forked from pacifics/PassDao
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPassTokenManager
763 lines (604 loc) · 26.9 KB
/
PassTokenManager
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
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
import "PassDao.sol";
pragma solidity ^0.4.8;
/*
*
* This file is part of Pass DAO.
*
* The Manager smart contract is used for the management of shares and tokens.
*
*/
/// @title Token Manager smart contract of the Pass Decentralized Autonomous Organisation
contract PassTokenManagerInterface {
// The Pass Dao smart contract
PassDao public passDao;
// The adress of the creator of this smart contract
address creator;
// The token name for display purpose
string public name;
// The token symbol for display purpose
string public symbol;
// The quantity of decimals for display purpose
uint8 public decimals;
// Total amount of tokens
uint256 totalTokenSupply;
// True if tokens, false if Dao shares
bool token;
// If true, the shares or tokens can be transferred
bool transferable;
// The address of the last Manager before cloning
address public clonedFrom;
// True if the initial token supply is over
bool initialTokenSupplyDone;
// Array of token or share holders (used for cloning)
address[] holders;
// Map with the indexes of the holders (used for cloning)
mapping (address => uint) holderID;
// Array with all balances
mapping (address => uint256) balances;
// Array with all allowances
mapping (address => mapping (address => uint256)) allowed;
struct funding {
// The address which sets partners and manages the funding (not mandatory)
address moderator;
// The amount (in wei) of the funding
uint amountToFund;
// The funded amount (in wei)
uint fundedAmount;
// A unix timestamp, denoting the start time of the funding
uint startTime;
// A unix timestamp, denoting the closing time of the funding
uint closingTime;
// The price multiplier for a share or a token without considering the inflation rate
uint initialPriceMultiplier;
// Rate per year in percentage applied to the share or token price
uint inflationRate;
// The total amount of wei given
uint totalWeiGiven;
}
// Map with the fundings rules for each Dao proposal
mapping (uint => funding) public fundings;
// The index of the last funding and proposal
uint lastProposalID;
// The index of the last fueled funding and proposal
uint public lastFueledFundingID;
struct amountsGiven {
uint weiAmount;
uint tokenAmount;
}
// Map with the amounts given for each proposal
mapping (uint => mapping (address => amountsGiven)) public Given;
// Map of blocked Dao share accounts. Points to the date when the share holder can transfer shares
mapping (address => uint) public blockedDeadLine;
// @return The client of this manager
function Client() constant returns (address);
/// @return The total supply of shares or tokens
function totalSupply() constant external returns (uint256);
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant external returns (uint256 balance);
/// @return True if tokens can be transferred
function Transferable() constant external returns (bool);
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Quantity of remaining tokens of _owner that _spender is allowed to spend
function allowance(address _owner, address _spender) constant external returns (uint256 remaining);
/// @param _proposalID Index of the funding or proposal
/// @return The result (in wei) of the funding
function FundedAmount(uint _proposalID) constant external returns (uint);
/// @param _proposalID Index of the funding or proposal
/// @return The amount to fund
function AmountToFund(uint _proposalID) constant external returns (uint);
/// @param _proposalID Index of the funding or proposal
/// @return the token price multiplier
function priceMultiplier(uint _proposalID) constant internal returns (uint);
/// @param _proposalID Index of the funding or proposal
/// @param _saleDate in case of presale, the date of the presale
/// @return the share or token price divisor condidering the sale date and the inflation rate
function priceDivisor(
uint _proposalID,
uint _saleDate) constant internal returns (uint);
/// @param _proposalID Index of the funding or proposal
/// @return the actual price divisor of a share or token
function actualPriceDivisor(uint _proposalID) constant internal returns (uint);
/// @dev Internal function to calculate the amount in tokens according to a price
/// @param _weiAmount The amount (in wei)
/// @param _priceMultiplier The price multiplier
/// @param _priceDivisor The price divisor
/// @return the amount in tokens
function TokenAmount(
uint _weiAmount,
uint _priceMultiplier,
uint _priceDivisor) constant internal returns (uint);
/// @dev Internal function to calculate the amount in wei according to a price
/// @param _tokenAmount The amount (in wei)
/// @param _priceMultiplier The price multiplier
/// @param _priceDivisor The price divisor
/// @return the amount in wei
function weiAmount(
uint _tokenAmount,
uint _priceMultiplier,
uint _priceDivisor) constant internal returns (uint);
/// @param _tokenAmount The amount in tokens
/// @param _proposalID Index of the client proposal. 0 if not linked to a proposal.
/// @return the actual token price in wei
function TokenPriceInWei(uint _tokenAmount, uint _proposalID) constant returns (uint);
/// @return The index of the last funding and client's proposal
function LastProposalID() constant returns (uint);
/// @return The number of share or token holders (used for cloning)
function numberOfHolders() constant returns (uint);
/// @param _index The index of the holder
/// @return the address of the holder
function HolderAddress(uint _index) constant external returns (address);
/// @dev The constructor function
/// @param _passDao Address of the pass Dao smart contract
/// @param _clonedFrom The address of the last Manager before cloning
/// @param _tokenName The token name for display purpose
/// @param _tokenSymbol The token symbol for display purpose
/// @param _tokenDecimals The quantity of decimals for display purpose
/// @param _token True if tokens, false if shares
/// @param _transferable True if tokens can be transferred
/// @param _initialPriceMultiplier Price multiplier without considering any inflation rate
/// @param _inflationRate If 0, the token price doesn't change during the funding
//function PassTokenManager(
// address _passDao,
// address _clonedFrom,
// string _tokenName,
// string _tokenSymbol,
// uint8 _tokenDecimals,
// bool _token,
// bool _transferable,
// uint _initialPriceMultiplier,
// uint _inflationRate);
/// @dev Function to create initial tokens
/// @param _recipient The beneficiary of the created tokens
/// @param _quantity The quantity of tokens to create
/// @param _last True if the initial token suppy is over
/// @return Whether the function was successful or not
function initialTokenSupply(
address _recipient,
uint _quantity,
bool _last) returns (bool success);
/// @notice Function to clone tokens before upgrading
/// @param _from The index of the first holder
/// @param _to The index of the last holder
/// @return Whether the function was successful or not
function cloneTokens(
uint _from,
uint _to) returns (bool success);
/// @dev Internal function to add a new token or share holder
/// @param _holder The address of the token or share holder
function addHolder(address _holder) internal;
/// @dev Internal function to create initial tokens
/// @param _holder The beneficiary of the created tokens
/// @param _tokenAmount The amount in tokens to create
function createTokens(
address _holder,
uint _tokenAmount) internal;
/// @notice Function used by the client to pay with shares or tokens
/// @param _recipient The address of the recipient of shares or tokens
/// @param _amount The amount (in Wei) to calculate the quantity of shares or tokens to create
/// @return the rewarded amount in tokens or shares
function rewardTokensForClient(
address _recipient,
uint _amount) external returns (uint);
/// @notice Function to set a funding
/// @param _moderator The address of the smart contract to manage a private funding
/// @param _initialPriceMultiplier Price multiplier without considering any inflation rate
/// @param _amountToFund The amount (in wei) of the funding
/// @param _minutesFundingPeriod Period in minutes of the funding
/// @param _inflationRate If 0, the token price doesn't change during the funding
/// @param _proposalID Index of the client proposal
function setFundingRules(
address _moderator,
uint _initialPriceMultiplier,
uint _amountToFund,
uint _minutesFundingPeriod,
uint _inflationRate,
uint _proposalID) external;
/// @dev Internal function for the sale of shares or tokens
/// @param _proposalID Index of the client proposal
/// @param _recipient The recipient address of shares or tokens
/// @param _amount The funded amount (in wei)
/// @param _saleDate In case of presale, the date of the presale
/// @param _presale True if presale
/// @return Whether the creation was successful or not
function sale(
uint _proposalID,
address _recipient,
uint _amount,
uint _saleDate,
bool _presale
) internal returns (bool success);
/// @dev Internal function to close the actual funding
/// @param _proposalID Index of the client proposal
function closeFunding(uint _proposalID) internal;
/// @notice Function to send tokens or refund after the closing time of the funding proposals
/// @param _from The first proposal. 0 if not linked to a proposal
/// @param _to The last proposal
/// @param _buyer The address of the buyer
/// @return Whether the function was successful or not
function sendPendingAmounts(
uint _from,
uint _to,
address _buyer) returns (bool);
/// @notice Function to get fees, shares or refund after the closing time of the funding proposals
/// @return Whether the function was successful or not
function withdrawPendingAmounts() returns (bool);
/// @notice Function used by the main partner to set the start time of the funding
/// @param _proposalID Index of the client proposal
/// @param _startTime The unix start date of the funding
function setFundingStartTime(
uint _proposalID,
uint _startTime) external;
/// @notice Function used by the main partner to set the funding fueled
/// @param _proposalID Index of the client proposal
function setFundingFueled(uint _proposalID) external;
/// @notice Function to able the transfer of Dao shares or contractor tokens
function ableTransfer();
/// @notice Function to disable the transfer of Dao shares
function disableTransfer();
/// @notice Function used by the client to block the transfer of shares from and to a share holder
/// @param _shareHolder The address of the share holder
/// @param _deadLine When the account will be unblocked
function blockTransfer(
address _shareHolder,
uint _deadLine) external;
/// @dev Internal function to send `_value` token to `_to` from `_From`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The quantity of shares or tokens to be transferred
/// @return Whether the function was successful or not
function transferFromTo(
address _from,
address _to,
uint256 _value
) internal returns (bool success);
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The quantity of shares or tokens to be transferred
/// @return Whether the function was successful or not
function transfer(address _to, uint256 _value) returns (bool success);
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The quantity of shares or tokens to be transferred
function transferFrom(
address _from,
address _to,
uint256 _value
) returns (bool success);
/// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on its behalf
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of tokens to be approved for transfer
/// @return Whether the approval was successful or not
function approve(
address _spender,
uint256 _value) returns (bool success);
event TokensCreated(address indexed Sender, address indexed TokenHolder, uint TokenAmount);
event FundingRulesSet(address indexed Moderator, uint indexed ProposalId, uint AmountToFund, uint indexed StartTime, uint ClosingTime);
event FundingFueled(uint indexed ProposalID, uint FundedAmount);
event TransferAble();
event TransferDisable();
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Refund(address indexed Buyer, uint Amount);
}
contract PassTokenManager is PassTokenManagerInterface {
// Constant functions
function Client() constant returns (address) {
return passDao.ActualCommitteeRoom();
}
function totalSupply() constant external returns (uint256) {
return totalTokenSupply;
}
function balanceOf(address _owner) constant external returns (uint256 balance) {
return balances[_owner];
}
function Transferable() constant external returns (bool) {
return transferable;
}
function allowance(
address _owner,
address _spender) constant external returns (uint256 remaining) {
return allowed[_owner][_spender];
}
function FundedAmount(uint _proposalID) constant external returns (uint) {
return fundings[_proposalID].fundedAmount;
}
function AmountToFund(uint _proposalID) constant external returns (uint) {
if (now > fundings[_proposalID].closingTime
|| now < fundings[_proposalID].startTime) {
return 0;
} else return fundings[_proposalID].amountToFund;
}
function priceMultiplier(uint _proposalID) constant internal returns (uint) {
return fundings[_proposalID].initialPriceMultiplier;
}
function priceDivisor(uint _proposalID, uint _saleDate) constant internal returns (uint) {
uint _date = _saleDate;
if (_saleDate > fundings[_proposalID].closingTime) _date = fundings[_proposalID].closingTime;
if (_saleDate < fundings[_proposalID].startTime) _date = fundings[_proposalID].startTime;
return 100 + 100*fundings[_proposalID].inflationRate*(_date - fundings[_proposalID].startTime)/(100*365 days);
}
function actualPriceDivisor(uint _proposalID) constant internal returns (uint) {
return priceDivisor(_proposalID, now);
}
function TokenAmount(
uint _weiAmount,
uint _priceMultiplier,
uint _priceDivisor) constant internal returns (uint) {
uint _a = _weiAmount*_priceMultiplier;
uint _multiplier = 100*_a;
uint _amount = _multiplier/_priceDivisor;
if (_a/_weiAmount != _priceMultiplier
|| _multiplier/100 != _a) return 0;
return _amount;
}
function weiAmount(
uint _tokenAmount,
uint _priceMultiplier,
uint _priceDivisor) constant internal returns (uint) {
uint _multiplier = _tokenAmount*_priceDivisor;
uint _divisor = 100*_priceMultiplier;
uint _amount = _multiplier/_divisor;
if (_multiplier/_tokenAmount != _priceDivisor
|| _divisor/100 != _priceMultiplier) return 0;
return _amount;
}
function TokenPriceInWei(uint _tokenAmount, uint _proposalID) constant returns (uint) {
return weiAmount(_tokenAmount, priceMultiplier(_proposalID), actualPriceDivisor(_proposalID));
}
function LastProposalID() constant returns (uint) {
return lastProposalID;
}
function numberOfHolders() constant returns (uint) {
return holders.length - 1;
}
function HolderAddress(uint _index) constant external returns (address) {
return holders[_index];
}
// Modifiers
// Modifier that allows only the client ..
modifier onlyClient {if (msg.sender != Client()) throw; _;}
// Modifier for share Manager functions
modifier onlyShareManager {if (token) throw; _;}
// Modifier for token Manager functions
modifier onlyTokenManager {if (!token) throw; _;}
// Constructor function
function PassTokenManager(
PassDao _passDao,
address _clonedFrom,
string _tokenName,
string _tokenSymbol,
uint8 _tokenDecimals,
bool _token,
bool _transferable,
uint _initialPriceMultiplier,
uint _inflationRate) {
passDao = _passDao;
creator = msg.sender;
clonedFrom = _clonedFrom;
name = _tokenName;
symbol = _tokenSymbol;
decimals = _tokenDecimals;
token = _token;
transferable = _transferable;
fundings[0].initialPriceMultiplier = _initialPriceMultiplier;
fundings[0].inflationRate = _inflationRate;
holders.length = 1;
}
// Setting functions
function initialTokenSupply(
address _recipient,
uint _quantity,
bool _last) returns (bool success) {
if (initialTokenSupplyDone) throw;
addHolder(_recipient);
if (_recipient != 0 && _quantity != 0) createTokens(_recipient, _quantity);
if (_last) initialTokenSupplyDone = true;
return true;
}
function cloneTokens(
uint _from,
uint _to) returns (bool success) {
initialTokenSupplyDone = true;
if (_from == 0) _from = 1;
PassTokenManager _clonedFrom = PassTokenManager(clonedFrom);
uint _numberOfHolders = _clonedFrom.numberOfHolders();
if (_to == 0 || _to > _numberOfHolders) _to = _numberOfHolders;
address _holder;
uint _balance;
for (uint i = _from; i <= _to; i++) {
_holder = _clonedFrom.HolderAddress(i);
_balance = _clonedFrom.balanceOf(_holder);
if (balances[_holder] == 0 && _balance != 0) {
addHolder(_holder);
createTokens(_holder, _balance);
}
}
}
// Token creation
function addHolder(address _holder) internal {
if (holderID[_holder] == 0) {
uint _holderID = holders.length++;
holders[_holderID] = _holder;
holderID[_holder] = _holderID;
}
}
function createTokens(
address _holder,
uint _tokenAmount) internal {
balances[_holder] += _tokenAmount;
totalTokenSupply += _tokenAmount;
TokensCreated(msg.sender, _holder, _tokenAmount);
}
function rewardTokensForClient(
address _recipient,
uint _amount
) external onlyClient returns (uint) {
uint _tokenAmount = TokenAmount(_amount, priceMultiplier(0), actualPriceDivisor(0));
if (_tokenAmount == 0) throw;
addHolder(_recipient);
createTokens(_recipient, _tokenAmount);
return _tokenAmount;
}
function setFundingRules(
address _moderator,
uint _initialPriceMultiplier,
uint _amountToFund,
uint _minutesFundingPeriod,
uint _inflationRate,
uint _proposalID
) external onlyClient {
if (_moderator == address(this)
|| _moderator == Client()
|| _amountToFund == 0
|| _minutesFundingPeriod == 0
|| fundings[_proposalID].totalWeiGiven != 0
) throw;
fundings[_proposalID].moderator = _moderator;
fundings[_proposalID].amountToFund = _amountToFund;
fundings[_proposalID].fundedAmount = 0;
if (_initialPriceMultiplier == 0) {
if (now < fundings[0].closingTime) {
fundings[_proposalID].initialPriceMultiplier = 100*priceMultiplier(lastProposalID)/actualPriceDivisor(lastProposalID);
} else {
fundings[_proposalID].initialPriceMultiplier = 100*priceMultiplier(lastFueledFundingID)/actualPriceDivisor(lastFueledFundingID);
}
fundings[0].initialPriceMultiplier = fundings[_proposalID].initialPriceMultiplier;
}
else {
fundings[_proposalID].initialPriceMultiplier = _initialPriceMultiplier;
fundings[0].initialPriceMultiplier = _initialPriceMultiplier;
}
if (_inflationRate == 0) fundings[_proposalID].inflationRate = fundings[0].inflationRate;
else {
fundings[_proposalID].inflationRate = _inflationRate;
fundings[0].inflationRate = _inflationRate;
}
fundings[_proposalID].startTime = now;
fundings[0].startTime = now;
fundings[_proposalID].closingTime = now + _minutesFundingPeriod * 1 minutes;
fundings[0].closingTime = fundings[_proposalID].closingTime;
fundings[_proposalID].totalWeiGiven = 0;
lastProposalID = _proposalID;
FundingRulesSet(_moderator, _proposalID, _amountToFund, fundings[_proposalID].startTime, fundings[_proposalID].closingTime);
}
function sale(
uint _proposalID,
address _recipient,
uint _amount,
uint _saleDate,
bool _presale) internal returns (bool success) {
if (_saleDate == 0) _saleDate = now;
if (_saleDate > fundings[_proposalID].closingTime
|| _saleDate < fundings[_proposalID].startTime
|| fundings[_proposalID].totalWeiGiven + _amount > fundings[_proposalID].amountToFund) return;
uint _tokenAmount = TokenAmount(_amount, priceMultiplier(_proposalID), priceDivisor(_proposalID, _saleDate));
if (_tokenAmount == 0) return;
addHolder(_recipient);
if (_presale) {
Given[_proposalID][_recipient].tokenAmount += _tokenAmount;
}
else createTokens(_recipient, _tokenAmount);
return true;
}
function closeFunding(uint _proposalID) internal {
fundings[_proposalID].fundedAmount = fundings[_proposalID].totalWeiGiven;
lastFueledFundingID = _proposalID;
fundings[_proposalID].closingTime = now;
FundingFueled(_proposalID, fundings[_proposalID].fundedAmount);
}
function sendPendingAmounts(
uint _from,
uint _to,
address _buyer) returns (bool) {
if (_from == 0) _from = 1;
if (_to == 0) _to = lastProposalID;
if (_buyer == 0) _buyer = msg.sender;
uint _amount;
uint _tokenAmount;
for (uint i = _from; i <= _to; i++) {
if (now > fundings[i].closingTime && Given[i][_buyer].weiAmount != 0) {
if (fundings[i].fundedAmount == 0) _amount += Given[i][_buyer].weiAmount;
else _tokenAmount += Given[i][_buyer].tokenAmount;
fundings[i].totalWeiGiven -= Given[i][_buyer].weiAmount;
Given[i][_buyer].tokenAmount = 0;
Given[i][_buyer].weiAmount = 0;
}
}
if (_tokenAmount > 0) {
createTokens(_buyer, _tokenAmount);
return true;
}
if (_amount > 0) {
if (!_buyer.send(_amount)) throw;
Refund(_buyer, _amount);
} else return true;
}
function withdrawPendingAmounts() returns (bool) {
return sendPendingAmounts(0, 0, msg.sender);
}
// Funding Moderator functions
function setFundingStartTime(uint _proposalID, uint _startTime) external {
if ((msg.sender != fundings[_proposalID].moderator) || now > fundings[_proposalID].closingTime) throw;
fundings[_proposalID].startTime = _startTime;
}
function setFundingFueled(uint _proposalID) external {
if ((msg.sender != fundings[_proposalID].moderator) || now > fundings[_proposalID].closingTime) throw;
closeFunding(_proposalID);
}
// Tokens transfer management
function ableTransfer() onlyClient {
if (!transferable) {
transferable = true;
TransferAble();
}
}
function disableTransfer() onlyClient {
if (transferable) {
transferable = false;
TransferDisable();
}
}
function blockTransfer(address _shareHolder, uint _deadLine) external onlyClient onlyShareManager {
if (_deadLine > blockedDeadLine[_shareHolder]) {
blockedDeadLine[_shareHolder] = _deadLine;
}
}
function transferFromTo(
address _from,
address _to,
uint256 _value
) internal returns (bool success) {
if ((transferable)
&& now > blockedDeadLine[_from]
&& now > blockedDeadLine[_to]
&& _to != address(this)
&& balances[_from] >= _value
&& balances[_to] + _value > balances[_to]) {
addHolder(_to);
balances[_from] -= _value;
balances[_to] += _value;
Transfer(_from, _to, _value);
return true;
} else return false;
}
function transfer(address _to, uint256 _value) returns (bool success) {
if (!transferFromTo(msg.sender, _to, _value)) throw;
return true;
}
function transferFrom(
address _from,
address _to,
uint256 _value
) returns (bool success) {
if (allowed[_from][msg.sender] < _value
|| !transferFromTo(_from, _to, _value)) throw;
allowed[_from][msg.sender] -= _value;
return true;
}
function approve(address _spender, uint256 _value) returns (bool success) {
allowed[msg.sender][_spender] = _value;
return true;
}
}