1
1
import { RedundantSubprovider , RPCSubprovider , Web3ProviderEngine } from '@0x/subproviders' ;
2
- import { BigNumber } from '@polymathnetwork/abi-wrappers' ;
2
+ import { BigNumber , ModuleRegistryEvents , PercentageTransferManagerEvents } from '@polymathnetwork/abi-wrappers' ;
3
3
import ModuleFactoryWrapper from '../src/contract_wrappers/modules/module_factory_wrapper' ;
4
4
import { ApiConstructorParams , PolymathAPI } from '../src/PolymathAPI' ;
5
- import { bytes32ToString } from '../src/utils/convert' ;
6
5
import { ModuleName , ModuleType } from '../src' ;
7
6
8
7
// This file acts as a valid sandbox for using a percentage restriction transfer manager module on an unlocked node (like ganache)
@@ -19,12 +18,49 @@ window.addEventListener('load', async () => {
19
18
// Instantiate the API
20
19
const polymathAPI = new PolymathAPI ( params ) ;
21
20
22
- const ticker = 'TEST' ;
23
- const tickerSecurityTokenInstance = await polymathAPI . tokenFactory . getSecurityTokenInstanceFromTicker ( ticker ) ;
24
- const moduleStringName = 'PercentageTransferManager' ;
21
+ // Get some poly tokens in your account and the security token
22
+ const myAddress = await polymathAPI . getAccount ( ) ;
23
+ await polymathAPI . getPolyTokens ( { amount : new BigNumber ( 1000000 ) , address : myAddress } ) ;
24
+
25
+ // Prompt to setup your ticker and token name
26
+ const ticker = prompt ( 'Ticker' , '' ) ;
27
+ const tokenName = prompt ( 'Token Name' , '' ) ;
28
+
29
+ // Double check available
30
+ await polymathAPI . securityTokenRegistry . isTickerAvailable ( {
31
+ ticker : ticker ! ,
32
+ } ) ;
33
+ // Get the ticker fee and approve the security token registry to spend
34
+ const tickerFee = await polymathAPI . securityTokenRegistry . getTickerRegistrationFee ( ) ;
35
+ await polymathAPI . polyToken . approve ( {
36
+ spender : await polymathAPI . securityTokenRegistry . address ( ) ,
37
+ value : tickerFee ,
38
+ } ) ;
39
+ // Register a ticker
40
+ await polymathAPI . securityTokenRegistry . registerTicker ( {
41
+ ticker : ticker ! ,
42
+ tokenName : tokenName ! ,
43
+ } ) ;
44
+ // Get the st launch fee and approve the security token registry to spend
45
+ const securityTokenLaunchFee = await polymathAPI . securityTokenRegistry . getSecurityTokenLaunchFee ( ) ;
46
+ await polymathAPI . polyToken . approve ( {
47
+ spender : await polymathAPI . securityTokenRegistry . address ( ) ,
48
+ value : securityTokenLaunchFee ,
49
+ } ) ;
50
+
51
+ await polymathAPI . securityTokenRegistry . generateNewSecurityToken ( {
52
+ name : tokenName ! ,
53
+ ticker : ticker ! ,
54
+ tokenDetails : 'details' ,
55
+ divisible : true ,
56
+ treasuryWallet : myAddress ,
57
+ protocolVersion : '0' ,
58
+ } ) ;
59
+
60
+ console . log ( 'Security Token Generated' ) ;
61
+
25
62
const moduleName = ModuleName . PercentageTransferManager ;
26
63
27
- // Get permission manager factory address
28
64
const modules = await polymathAPI . moduleRegistry . getModulesByType ( {
29
65
moduleType : ModuleType . TransferManager ,
30
66
} ) ;
@@ -40,16 +76,109 @@ window.addEventListener('load', async () => {
40
76
names . push ( instanceFactory . name ( ) ) ;
41
77
} ) ;
42
78
const resultNames = await Promise . all ( names ) ;
43
- const index = resultNames . indexOf ( moduleStringName ) ;
44
79
45
- // Call to add module
80
+ const index = resultNames . indexOf ( moduleName ) ;
81
+
82
+ // Create a Security Token Instance
83
+ const tickerSecurityTokenInstance = await polymathAPI . tokenFactory . getSecurityTokenInstanceFromTicker ( ticker ! ) ;
84
+
85
+ await polymathAPI . moduleRegistry . subscribeAsync ( {
86
+ eventName : ModuleRegistryEvents . ModuleRegistered ,
87
+ indexFilterValues : { } ,
88
+ callback : async ( error , log ) => {
89
+ if ( error ) {
90
+ console . log ( error ) ;
91
+ } else {
92
+ console . log ( 'Module added!' , log ) ;
93
+ }
94
+ } ,
95
+ } ) ;
96
+
97
+ // Get General TM Address to whitelist transfers
98
+ const generalTMAddress = ( await tickerSecurityTokenInstance . getModulesByName ( {
99
+ moduleName : ModuleName . GeneralTransferManager ,
100
+ } ) ) [ 0 ] ;
101
+ const generalTM = await polymathAPI . moduleFactory . getModuleInstance ( {
102
+ name : ModuleName . GeneralTransferManager ,
103
+ address : generalTMAddress ,
104
+ } ) ;
105
+
106
+ await generalTM . modifyKYCData ( {
107
+ investor : myAddress ,
108
+ canSendAfter : new Date ( ) ,
109
+ canReceiveAfter : new Date ( ) ,
110
+ expiryTime : new Date ( 2020 , 0 ) ,
111
+ txData : {
112
+ from : await polymathAPI . getAccount ( ) ,
113
+ } ,
114
+ } ) ;
115
+
46
116
await tickerSecurityTokenInstance . addModule ( {
47
117
moduleName,
48
118
address : modules [ index ] ,
49
119
data : {
50
- maxHolderPercentage : new BigNumber ( 10 ) ,
120
+ maxHolderPercentage : new BigNumber ( 25 ) ,
51
121
allowPrimaryIssuance : true ,
52
122
} ,
53
123
archived : false ,
54
124
} ) ;
125
+
126
+ const percentageTMAddress = ( await tickerSecurityTokenInstance . getModulesByName ( {
127
+ moduleName : ModuleName . PercentageTransferManager ,
128
+ } ) ) [ 0 ] ;
129
+
130
+ const percentageTM = await polymathAPI . moduleFactory . getModuleInstance ( {
131
+ name : ModuleName . PercentageTransferManager ,
132
+ address : percentageTMAddress ,
133
+ } ) ;
134
+
135
+ // Subscribe to event of setAllowPrimaryIssuance
136
+ await percentageTM . subscribeAsync ( {
137
+ eventName : PercentageTransferManagerEvents . SetAllowPrimaryIssuance ,
138
+ indexFilterValues : { } ,
139
+ callback : async ( error , log ) => {
140
+ if ( error ) {
141
+ console . log ( error ) ;
142
+ } else {
143
+ console . log ( 'AllowPrimaryIssuance has been set' , log ) ;
144
+ }
145
+ } ,
146
+ } ) ;
147
+
148
+ const randomBeneficiary1 = '0x0123456789012345678901234567890123456789' ;
149
+ const randomBeneficiary2 = '0x9123456789012345678901234567890123456789' ;
150
+
151
+ await generalTM . modifyKYCDataMulti ( {
152
+ investors : [ myAddress , randomBeneficiary1 , randomBeneficiary2 ] ,
153
+ canReceiveAfter : [ new Date ( ) , new Date ( ) , new Date ( ) ] ,
154
+ canSendAfter : [ new Date ( ) , new Date ( ) , new Date ( ) ] ,
155
+ expiryTime : [ new Date ( 2035 , 1 ) , new Date ( 2035 , 1 ) , new Date ( 2035 , 1 ) ] ,
156
+ } ) ;
157
+
158
+ await tickerSecurityTokenInstance . issueMulti ( {
159
+ investors : [ myAddress , randomBeneficiary1 ] ,
160
+ values : [ new BigNumber ( 10 ) , new BigNumber ( 10 ) ] ,
161
+ } ) ;
162
+
163
+ await percentageTM . setAllowPrimaryIssuance ( { allowPrimaryIssuance : false } ) ;
164
+ console . log ( 'SetAllowPrimaryIssuance has been called' ) ;
165
+
166
+ // Primary Issuance now invalid
167
+ // Percentage transfer manager whitelist beneficiary 1 so they can receive more tokens
168
+ await percentageTM . modifyWhitelist ( { investor : randomBeneficiary1 , valid : true } ) ;
169
+ await tickerSecurityTokenInstance . transfer ( { to : randomBeneficiary1 , value : new BigNumber ( 1 ) } ) ;
170
+
171
+ // Try out transfer above 25% to beneficiary 2, should fail
172
+ try {
173
+ await tickerSecurityTokenInstance . transfer ( { to : randomBeneficiary2 , value : new BigNumber ( 6 ) } ) ;
174
+ } catch ( e ) {
175
+ console . log ( 'Transfer above 25% to non-whitelisted address fails as expected' ) ;
176
+ }
177
+
178
+ // Try out transfer below 25% to beneficiary 2, should pass
179
+ await tickerSecurityTokenInstance . transfer ( { to : randomBeneficiary2 , value : new BigNumber ( 5 ) } ) ;
180
+
181
+ console . log ( 'Tokens transferred to beneficiaries' ) ;
182
+
183
+ tickerSecurityTokenInstance . unsubscribeAll ( ) ;
55
184
} ) ;
0 commit comments