@@ -33,8 +33,18 @@ import {
33
33
GetLogs ,
34
34
TransferResult ,
35
35
Perm ,
36
+ TransferStatusCode ,
36
37
} from '../../../types' ;
37
- import { numberToBigNumber , valueToWei , dateToBigNumber } from '../../../utils/convert' ;
38
+ import {
39
+ numberToBigNumber ,
40
+ valueToWei ,
41
+ weiToValue ,
42
+ dateToBigNumber ,
43
+ bytes32ToString ,
44
+ bytes32ArrayToStringArray ,
45
+ } from '../../../utils/convert' ;
46
+
47
+ const TRANSFER_SUCCESS = '0x51' ;
38
48
39
49
interface AddScheduleSubscribeAsyncParams extends SubscribeAsyncParams {
40
50
eventName : VestingEscrowWalletEvents . AddSchedule ;
@@ -439,6 +449,7 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
439
449
* Used to change the treasury wallet address
440
450
*/
441
451
public changeTreasuryWallet = async ( params : ChangeTreasuryWalletParams ) => {
452
+ assert . assert ( await this . isCallerTheSecurityTokenOwner ( params . txData ) , 'The caller must be the ST owner' ) ;
442
453
return ( await this . contract ) . changeTreasuryWallet . sendTransactionAsync (
443
454
params . newTreasuryWallet ,
444
455
params . txData ,
@@ -450,6 +461,18 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
450
461
* Used to deposit tokens from treasury wallet to the vesting escrow wallet
451
462
*/
452
463
public depositTokens = async ( params : DepositTokensParams ) => {
464
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Admin ) , 'Caller is not allowed' ) ;
465
+
466
+ assert . assert ( params . numberOfTokens > 0 , 'Number of tokens should be > 0' ) ;
467
+
468
+ const canTransferFromResult = await ( await this . securityTokenContract ( ) ) . canTransferFrom . callAsync (
469
+ await this . getCallerAddress ( params . txData ) ,
470
+ await this . address ( ) ,
471
+ numberToBigNumber ( params . numberOfTokens ) ,
472
+ '0x00' ,
473
+ ) ;
474
+ assert . assert ( canTransferFromResult [ 0 ] === TRANSFER_SUCCESS , 'Failed transferFrom' ) ;
475
+
453
476
return ( await this . contract ) . depositTokens . sendTransactionAsync (
454
477
numberToBigNumber ( params . numberOfTokens ) ,
455
478
params . txData ,
@@ -461,6 +484,19 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
461
484
* Sends unassigned tokens to the treasury wallet
462
485
*/
463
486
public sendToTreasury = async ( params : SendToTreasuryParams ) => {
487
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Operator ) , 'Caller is not allowed' ) ;
488
+ assert . assert ( params . amount > 0 , 'Amount cannot be zero' ) ;
489
+
490
+ const unassignedTokens = ( await this . unassignedTokens ( ) ) . toNumber ( ) ;
491
+ assert . assert ( params . amount <= unassignedTokens , 'Amount is greater than unassigned tokens' ) ;
492
+
493
+ const canTransferResult = await ( await this . securityTokenContract ( ) ) . canTransfer . callAsync (
494
+ await this . getTreasuryWallet ( ) ,
495
+ numberToBigNumber ( params . amount ) ,
496
+ '0x00' ,
497
+ ) ;
498
+ assert . assert ( canTransferResult [ 0 ] === TRANSFER_SUCCESS , 'Transfer failed' ) ;
499
+
464
500
return ( await this . contract ) . sendToTreasury . sendTransactionAsync (
465
501
numberToBigNumber ( params . amount ) ,
466
502
params . txData ,
@@ -479,6 +515,8 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
479
515
* Pushes available tokens to the beneficiary's address
480
516
*/
481
517
public pushAvailableTokens = async ( params : PushAvailableTokensParams ) => {
518
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Operator ) , 'Caller is not allowed' ) ;
519
+
482
520
return ( await this . contract ) . pushAvailableTokens . sendTransactionAsync (
483
521
params . beneficiary ,
484
522
params . txData ,
@@ -490,13 +528,18 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
490
528
* Used to withdraw available tokens by beneficiary
491
529
*/
492
530
public pullAvailableTokens = async ( params : TxParams ) => {
531
+ assert . assert ( ! ( await this . paused ( ) ) , 'Contract currently paused' ) ;
493
532
return ( await this . contract ) . pullAvailableTokens . sendTransactionAsync ( params . txData , params . safetyFactor ) ;
494
533
} ;
495
534
496
535
/**
497
536
* Adds template that can be used for creating schedule
498
537
*/
499
538
public addTemplate = async ( params : AddTemplateParams ) => {
539
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Admin ) , 'Caller is not allowed' ) ;
540
+ assert . assert ( params . name !== '' , 'Invalid name' ) ;
541
+ assert . assert ( ! ( await this . getAllTemplateNames ( ) ) . includes ( params . name ) , 'Template name already exists' ) ;
542
+ await this . validateTemplate ( params . numberOfTokens , params . duration , params . frequency ) ;
500
543
return ( await this . contract ) . addTemplate . sendTransactionAsync (
501
544
params . name ,
502
545
numberToBigNumber ( params . numberOfTokens ) ,
@@ -511,6 +554,10 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
511
554
* Removes template with a given name
512
555
*/
513
556
public removeTemplate = async ( params : RemoveTemplateParams ) => {
557
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Admin ) , 'Caller is not allowed' ) ;
558
+ assert . assert ( params . name !== '' , 'Invalid name' ) ;
559
+ assert . assert ( ( await this . getAllTemplateNames ( ) ) . includes ( params . name ) , 'Template not found' ) ;
560
+ // TODO 3.1: require(templateToUsers[_name].length == 0, "Template is used");
514
561
return ( await this . contract ) . removeTemplate . sendTransactionAsync ( params . name , params . txData , params . safetyFactor ) ;
515
562
} ;
516
563
@@ -519,21 +566,28 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
519
566
* @return Count of the templates
520
567
*/
521
568
public getTemplateCount = async ( ) => {
522
- return ( await this . contract ) . getTreasuryWallet . callAsync ( ) ;
569
+ const result = await ( await this . contract ) . getTemplateCount . callAsync ( ) ;
570
+ return result . toNumber ( ) ;
523
571
} ;
524
572
525
573
/**
526
574
* Gets the list of the template names those can be used for creating schedule
527
- * @return bytes32 Array of all template names were created
575
+ * @return Array of all template names were created
528
576
*/
529
577
public getAllTemplateNames = async ( ) => {
530
- return ( await this . contract ) . getTreasuryWallet . callAsync ( ) ;
578
+ const results = await ( await this . contract ) . getAllTemplateNames . callAsync ( ) ;
579
+ return bytes32ArrayToStringArray ( results ) ;
531
580
} ;
532
581
533
582
/**
534
583
* Adds vesting schedules for each of the beneficiary's address
535
584
*/
536
585
public addSchedule = async ( params : AddScheduleParams ) => {
586
+ assert . assert ( await this . isCallerAllowed ( params . txData , Perm . Admin ) , 'Caller is not allowed' ) ;
587
+ assert . assert ( params . templateName !== '' , 'Invalid name' ) ;
588
+ assert . assert ( ! ( await this . getAllTemplateNames ( ) ) . includes ( params . templateName ) , 'Template name already exists' ) ;
589
+ await this . validateTemplate ( params . numberOfTokens , params . duration , params . frequency ) ;
590
+ // TODO: _addScheduleFromTemplate assertion
537
591
let startTime = new BigNumber ( 0 ) ;
538
592
if ( params . startTime ) {
539
593
startTime = dateToBigNumber ( params . startTime ) ;
@@ -709,6 +763,16 @@ export default class VestingEscrowWalletWrapper extends ModuleWrapper {
709
763
) ;
710
764
} ;
711
765
766
+ private validateTemplate = async ( numberOfTokens : number , duration : number , frequency : number ) => {
767
+ assert . assert ( numberOfTokens > 0 , 'Zero amount' ) ;
768
+ assert . assert ( duration % frequency === 0 , 'Invalid frequency' ) ;
769
+ const periodCount = duration / frequency ;
770
+ assert . assert ( numberOfTokens % periodCount === 0 , 'Invalid period count' ) ;
771
+ const amountPerPeriod = numberOfTokens / periodCount ;
772
+ const granularity = await ( await this . securityTokenContract ( ) ) . granularity . callAsync ( ) ;
773
+ assert . assert ( amountPerPeriod % granularity . toNumber ( ) === 0 , 'Invalid granularity' ) ;
774
+ } ;
775
+
712
776
/**
713
777
* Subscribe to an event type emitted by the contract.
714
778
* @return Subscription token used later to unsubscribe
0 commit comments