Skip to content
This repository was archived by the owner on Jul 6, 2022. It is now read-only.

Commit 02cf3e8

Browse files
committed
fix: 🐛 manual merge from develop and improve comments
2 parents 7df0edd + 1766780 commit 02cf3e8

14 files changed

+3121
-178
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = {
2121
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
2222
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
2323
'@typescript-eslint/explicit-function-return-type': 'off',
24+
"import/prefer-default-export": 'off',
2425
'jest/expect-expect': 'error',
2526
'jest/no-empty-title': 'warn',
2627
'jest/no-truthy-falsy': 'warn',
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import { RedundantSubprovider, RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders';
2+
import ModuleFactoryWrapper from '../src/contract_wrappers/modules/module_factory_wrapper';
3+
import { ApiConstructorParams, PolymathAPI } from '../src/PolymathAPI';
4+
import { ModuleName, ModuleType } from '../src';
5+
import { BigNumber, ModuleRegistryEvents, BlacklistTransferManagerEvents } from '@polymathnetwork/abi-wrappers';
6+
7+
// This file acts as a valid sandbox for using a blacklist restriction transfer manager module on an unlocked node (like ganache)
8+
window.addEventListener('load', async () => {
9+
// Setup the redundant provider
10+
const providerEngine = new Web3ProviderEngine();
11+
providerEngine.addProvider(new RedundantSubprovider([new RPCSubprovider('http://127.0.0.1:8545')]));
12+
providerEngine.start();
13+
const params: ApiConstructorParams = {
14+
provider: providerEngine,
15+
polymathRegistryAddress: '<Deployed Polymath Registry address>',
16+
};
17+
18+
// Instantiate the API
19+
const polymathAPI = new PolymathAPI(params);
20+
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.tickerAvailable({
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+
62+
const moduleName = ModuleName.BlacklistTransferManager;
63+
64+
const modules = await polymathAPI.moduleRegistry.getModulesByType({
65+
moduleType: ModuleType.TransferManager,
66+
});
67+
68+
const instances: Promise<ModuleFactoryWrapper>[] = [];
69+
modules.map(address => {
70+
instances.push(polymathAPI.moduleFactory.getModuleFactory(address));
71+
});
72+
const resultInstances = await Promise.all(instances);
73+
74+
const names: Promise<string>[] = [];
75+
resultInstances.map(instanceFactory => {
76+
names.push(instanceFactory.name());
77+
});
78+
const resultNames = await Promise.all(names);
79+
80+
const index = resultNames.indexOf(moduleName);
81+
82+
// Create a Security Token Instance
83+
const tickerSecurityTokenInstance = await polymathAPI.tokenFactory.getSecurityTokenInstanceFromTicker(ticker!);
84+
85+
// Get General TM Address to whitelist transfers
86+
const generalTMAddress = (await tickerSecurityTokenInstance.getModulesByName({
87+
moduleName: ModuleName.GeneralTransferManager,
88+
}))[0];
89+
const generalTM = await polymathAPI.moduleFactory.getModuleInstance({
90+
name: ModuleName.GeneralTransferManager,
91+
address: generalTMAddress,
92+
});
93+
94+
await tickerSecurityTokenInstance.addModule({
95+
moduleName,
96+
address: modules[index],
97+
archived: false,
98+
});
99+
100+
const blacklistTMAddress = (await tickerSecurityTokenInstance.getModulesByName({
101+
moduleName: ModuleName.BlacklistTransferManager,
102+
}))[0];
103+
104+
const blacklistTM = await polymathAPI.moduleFactory.getModuleInstance({
105+
name: ModuleName.BlacklistTransferManager,
106+
address: blacklistTMAddress,
107+
});
108+
109+
const randomBeneficiary1 = '0x2222222222222222222222222222222222222222';
110+
const randomBeneficiary2 = '0x3333333333333333333333333333333333333333';
111+
112+
await generalTM.modifyKYCDataMulti({
113+
investors: [myAddress, randomBeneficiary1, randomBeneficiary2],
114+
canReceiveAfter: [new Date(), new Date(), new Date()],
115+
canSendAfter: [new Date(), new Date(), new Date()],
116+
expiryTime: [new Date(2035, 1), new Date(2035, 1), new Date(2035, 1)],
117+
});
118+
119+
await tickerSecurityTokenInstance.issueMulti({
120+
investors: [myAddress, randomBeneficiary1, randomBeneficiary2],
121+
values: [new BigNumber(100), new BigNumber(100), new BigNumber(100)],
122+
});
123+
124+
// Subscribe to event of addblacklisttype
125+
await blacklistTM.subscribeAsync({
126+
eventName: BlacklistTransferManagerEvents.AddBlacklistType,
127+
indexFilterValues: {},
128+
callback: async (error, log) => {
129+
if (error) {
130+
console.log(error);
131+
} else {
132+
console.log('New Lock Up added to user', log);
133+
}
134+
},
135+
});
136+
137+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
138+
console.log(' No blacklist, 10 tokens transferred to randomBeneficiary2');
139+
140+
const startTime = new Date(Date.now() + 10000);
141+
const endTime = new Date(Date.now() + 20000);
142+
await blacklistTM.addInvestorToNewBlacklist({
143+
investor: myAddress,
144+
startTime,
145+
endTime,
146+
repeatPeriodTime: 1,
147+
blacklistName: 'ExampleBlacklist',
148+
});
149+
150+
console.log('Blacklist starts in 10 seconds');
151+
const sleep = (milliseconds: number) => {
152+
console.log(`Sleeping ${milliseconds / 1000} seconds`);
153+
return new Promise(resolve => setTimeout(resolve, milliseconds));
154+
};
155+
await sleep(15000);
156+
157+
// Try out transfer 10 above lockup, will fail
158+
try {
159+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
160+
} catch (e) {
161+
console.log('Transfer of 10 tokens during blacklist period amount fails as expected');
162+
}
163+
164+
console.log('Blacklist ends in 5 seconds');
165+
await sleep(10000);
166+
167+
// Blacklist now over
168+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
169+
console.log('10 more tokens transferred to randomBeneficiary2');
170+
171+
const newStartTime = new Date(Date.now() + 10000);
172+
const newEndTime = new Date(Date.now() + 3600000);
173+
const testBlacklistNames = ['TestBlacklist1', 'TestBlacklist2', 'TestBlacklist3'];
174+
await blacklistTM.addNewBlacklistTypeMulti({
175+
blacklistNames: testBlacklistNames,
176+
startTimes: [newStartTime, newStartTime, newStartTime],
177+
endTimes: [newEndTime, newEndTime, newEndTime],
178+
repeatPeriodTimes: [1, 2, 3]
179+
});
180+
console.log('Many more example blacklists created');
181+
182+
await blacklistTM.addMultiInvestorToBlacklistMulti({blacklistNames: testBlacklistNames, userAddresses: [myAddress, randomBeneficiary1, randomBeneficiary2]});
183+
console.log('Multi investors added to multi blacklists');
184+
185+
await sleep(15000);
186+
187+
// Try out transfer 10 during blacklist, will fail
188+
try {
189+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
190+
} catch (e) {
191+
console.log('Transfer of 10 tokens during new blacklist period amount fails as expected');
192+
}
193+
194+
await blacklistTM.deleteInvestorFromAllBlacklistMulti({investors: [myAddress, randomBeneficiary1, randomBeneficiary2]});
195+
console.log('Multi investors deleted from all blacklists they are part of');
196+
197+
// Transfer out more tokens now that the investor has been removed from the new blacklist
198+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
199+
console.log('10 more tokens were successfully transferred to randomBeneficiary2');
200+
201+
tickerSecurityTokenInstance.unsubscribeAll();
202+
});

examples/lockUpTransferManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ window.addEventListener('load', async () => {
141141
await lockUpTM.addNewLockUpToUserMulti({
142142
userAddresses: [myAddress, randomBeneficiary1, randomBeneficiary2],
143143
startTimes: [new Date(2030, 1, 1), new Date(2030, 1, 1), new Date(2030, 1, 1)],
144-
lockUpPeriodSeconds: [new BigNumber(5), new BigNumber(5), new BigNumber(5)],
145-
releaseFrequenciesSeconds: [new BigNumber(1), new BigNumber(1), new BigNumber(1)],
144+
lockUpPeriodSeconds: [5, 5, 5],
145+
releaseFrequenciesSeconds: [1, 1, 1],
146146
lockupAmounts: [new BigNumber(100), new BigNumber(100), new BigNumber(100)],
147147
lockupNames: [firstLockUpName, secondLockUpName, thirdLockUpName],
148148
});
@@ -171,8 +171,8 @@ window.addEventListener('load', async () => {
171171
// Modify the lockup types so that we can test in real time
172172
await lockUpTM.modifyLockUpTypeMulti({
173173
startTimes: [startTime, startTime, startTime],
174-
lockUpPeriodSeconds: [new BigNumber(5), new BigNumber(5), new BigNumber(5)],
175-
releaseFrequenciesSeconds: [new BigNumber(1), new BigNumber(1), new BigNumber(1)],
174+
lockUpPeriodSeconds: [5, 5, 5],
175+
releaseFrequenciesSeconds: [1, 1, 1],
176176
lockupAmounts: [new BigNumber(20), new BigNumber(10), new BigNumber(10)],
177177
lockupNames: [firstLockUpName, secondLockUpName, thirdLockUpName],
178178
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@polymathnetwork/contract-wrappers",
3-
"version": "2.0.0-beta.31",
3+
"version": "2.0.0-beta.32",
44
"description": "Smart TS wrappers for Polymath smart contracts",
55
"keywords": [
66
"polymath",

src/PolymathAPI.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,27 @@ import {
44
BigNumber,
55
providerUtils,
66
Provider,
7-
FeatureRegistryContract,
8-
ModuleRegistryContract,
9-
PolymathRegistryContract,
10-
ISecurityTokenRegistryContract,
11-
ModuleFactoryContract,
12-
ModuleContract,
7+
BlacklistTransferManagerContract,
8+
CappedSTOContract,
9+
CountTransferManagerContract,
10+
ERC20DetailedContract,
1311
ERC20DividendCheckpointContract,
1412
EtherDividendCheckpointContract,
13+
FeatureRegistryContract,
1514
GeneralPermissionManagerContract,
16-
CappedSTOContract,
17-
USDTieredSTOContract,
18-
CountTransferManagerContract,
1915
GeneralTransferManagerContract,
16+
ISecurityTokenContract,
17+
ISecurityTokenRegistryContract,
18+
LockUpTransferManagerContract,
2019
ManualApprovalTransferManagerContract,
20+
ModuleContract,
21+
ModuleFactoryContract,
22+
ModuleRegistryContract,
2123
PercentageTransferManagerContract,
22-
LockUpTransferManagerContract,
23-
ERC20DetailedContract,
24+
PolymathRegistryContract,
2425
PolyTokenContract,
2526
PolyTokenFaucetContract,
26-
ISecurityTokenContract,
27+
USDTieredSTOContract,
2728
VolumeRestrictionTMContract,
2829
VestingEscrowWalletContract,
2930
} from '@polymathnetwork/abi-wrappers';
@@ -158,6 +159,7 @@ export class PolymathAPI {
158159
ManualApprovalTransferManagerContract.ABI(),
159160
PercentageTransferManagerContract.ABI(),
160161
LockUpTransferManagerContract.ABI(),
162+
BlacklistTransferManagerContract.ABI(),
161163
VolumeRestrictionTMContract.ABI(),
162164
// Tokens
163165
ERC20DetailedContract.ABI(),

src/contract_wrappers/modules/module_wrapper.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,16 @@ export default class ModuleWrapper extends ContractWrapper {
102102
const moduleFactoryContract = await this.moduleFactoryContract();
103103
const getTypes = await moduleFactoryContract.getTypes.callAsync();
104104
const types = getTypes.filter(type => {
105-
// type '6' is valid but it is not mapped, so we must filter this kind of scenarios
105+
// type '6' and '8' are valid but they are not mapped, so we must filter them
106106
try {
107107
parseModuleTypeValue(new BigNumber(type));
108108
return true;
109109
} catch (e) {
110110
return false;
111111
}
112112
});
113-
// if empty, module type is invalid
114-
if (!types.length) {
115-
return false;
116-
// if types has more than one element, prevent further errors
117-
}
118-
if (types.length > 1) {
113+
// prevent invalid scenarios
114+
if (!types.length || types.length > 1) {
119115
return false;
120116
}
121117
const address = await this.address();

0 commit comments

Comments
 (0)