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

Commit 274c6a5

Browse files
author
Victor Wiebe
committed
feat: 🎸 new example lockUpTM
1 parent 55e9a04 commit 274c6a5

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
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, LockUpTransferManagerEvents } from '@polymathnetwork/abi-wrappers';
6+
7+
// This file acts as a valid sandbox for using a lockup 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.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+
62+
const moduleName = ModuleName.LockUpTransferManager;
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 lockUpTMAddress = (await tickerSecurityTokenInstance.getModulesByName({
101+
moduleName: ModuleName.LockUpTransferManager,
102+
}))[0];
103+
104+
const lockUpTM = await polymathAPI.moduleFactory.getModuleInstance({
105+
name: ModuleName.LockUpTransferManager,
106+
address: lockUpTMAddress,
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 addLockUpToUser
125+
await lockUpTM.subscribeAsync({
126+
eventName: LockUpTransferManagerEvents.AddLockUpToUser,
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+
// Add new lock up to user multi
138+
const startTime = new Date(Date.now() + 10000);
139+
140+
await lockUpTM.addNewLockUpToUserMulti({
141+
userAddresses: [myAddress, randomBeneficiary1, randomBeneficiary2],
142+
startTimes: [startTime, startTime, startTime],
143+
lockUpPeriodSeconds: [new BigNumber(5), new BigNumber(5), new BigNumber(5)],
144+
releaseFrequenciesSeconds: [new BigNumber(1), new BigNumber(1), new BigNumber(1)],
145+
lockupAmounts: [new BigNumber(20), new BigNumber(10), new BigNumber(10)],
146+
lockupNames: ['Lockup1', 'Lockup2', 'Lockup3'],
147+
});
148+
149+
// Try to transfer 50, it is below lockup and will pass
150+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(50) });
151+
console.log('50 tokens transferred to randomBeneficiary2');
152+
153+
// Try out transfer above lockup, will fail
154+
try {
155+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(31) });
156+
} catch (e) {
157+
console.log('Transfer above lockup amount fails as expected');
158+
}
159+
160+
const sleep = (milliseconds: number) => {
161+
console.log(`Sleeping ${milliseconds / 1000} seconds`);
162+
return new Promise(resolve => setTimeout(resolve, milliseconds));
163+
};
164+
await sleep(10000);
165+
166+
// Time has passed, try out same transfer 1 above lockup, will pass
167+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(31) });
168+
console.log('31 more tokens transferred to randomBeneficiary2');
169+
170+
// Try out transfer 10 above lockup, will fail
171+
try {
172+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(10) });
173+
} catch (e) {
174+
console.log('Transfer above lockup amount fails as expected');
175+
}
176+
177+
await sleep(10000);
178+
179+
// Transfer out the rest of tokens now that lockup is over
180+
await tickerSecurityTokenInstance.transfer({ to: randomBeneficiary2, value: new BigNumber(19) });
181+
console.log('19 last tokens transferred to randomBeneficiary2');
182+
183+
tickerSecurityTokenInstance.unsubscribeAll();
184+
});

0 commit comments

Comments
 (0)