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

Commit 761c7ea

Browse files
author
Victor Wiebe
committed
feat: 🎸 addInvestorToBlacklist(Multi) methods and tests
1 parent a11bf22 commit 761c7ea

File tree

2 files changed

+275
-9
lines changed

2 files changed

+275
-9
lines changed

‎src/contract_wrappers/modules/transfer_manager/__tests__/blacklist_transfer_manager_wrapper.test.ts‎

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,210 @@ describe('BlacklistTransferManagerWrapper', () => {
872872
});
873873
});
874874

875+
describe('addInvestorToBlacklist', () => {
876+
test('should call addInvestorToBlacklist', async () => {
877+
const expectedOwnerResult = '0x8888888888888888888888888888888888888888';
878+
const expectedBlacklistInvestorAddress = '0x4444444444444444444444444444444444444444';
879+
const blacklistName = 'Blacklist1';
880+
const expectedStartTime = dateToBigNumber(new Date(2030, 1));
881+
const expectedEndTime = dateToBigNumber(new Date(2031, 1));
882+
const expectedRepeatPeriodTime = new BigNumber(366);
883+
const expectedGetBlacklistResult = [expectedStartTime, expectedEndTime, expectedRepeatPeriodTime];
884+
885+
// Security Token Address expected
886+
const expectedSecurityTokenAddress = '0x3333333333333333333333333333333333333333';
887+
// Setup get Security Token Address
888+
const mockedGetSecurityTokenAddressMethod = mock(MockedCallMethod);
889+
when(mockedContract.securityToken).thenReturn(instance(mockedGetSecurityTokenAddressMethod));
890+
when(mockedGetSecurityTokenAddressMethod.callAsync()).thenResolve(expectedSecurityTokenAddress);
891+
when(mockedContractFactory.getSecurityTokenContract(expectedSecurityTokenAddress)).thenResolve(
892+
instance(mockedSecurityTokenContract),
893+
);
894+
895+
const mockedSecurityTokenOwnerMethod = mock(MockedCallMethod);
896+
when(mockedSecurityTokenOwnerMethod.callAsync()).thenResolve(expectedOwnerResult);
897+
when(mockedSecurityTokenContract.owner).thenReturn(instance(mockedSecurityTokenOwnerMethod));
898+
899+
// Mock web3 wrapper owner
900+
when(mockedWrapper.getAvailableAddressesAsync()).thenResolve([expectedOwnerResult]);
901+
902+
// Mocked method
903+
const mockedBlacklistsMethod = mock(MockedCallMethod);
904+
// Stub the method
905+
when(mockedContract.blacklists).thenReturn(instance(mockedBlacklistsMethod));
906+
// Stub the request
907+
when(mockedBlacklistsMethod.callAsync(objectContaining(stringToBytes32(blacklistName)))).thenResolve(
908+
expectedGetBlacklistResult,
909+
);
910+
911+
const expectedGetBlacklistNamesToUserResult = stringArrayToBytes32Array(['Blacklist2', 'Blacklist3']);
912+
const mockedGetBlacklistNamesToUserParams = {
913+
user: expectedBlacklistInvestorAddress,
914+
};
915+
// Mocked method
916+
const mockedGetBlacklistNamesToUserMethod = mock(MockedCallMethod);
917+
// Stub the method
918+
when(mockedContract.getBlacklistNamesToUser).thenReturn(instance(mockedGetBlacklistNamesToUserMethod));
919+
// Stub the request
920+
when(mockedGetBlacklistNamesToUserMethod.callAsync(mockedGetBlacklistNamesToUserParams.user)).thenResolve(
921+
expectedGetBlacklistNamesToUserResult,
922+
);
923+
924+
const mockedParams = {
925+
userAddress: expectedBlacklistInvestorAddress,
926+
blacklistName,
927+
txData: {},
928+
safetyFactor: 10,
929+
};
930+
const expectedResult = getMockedPolyResponse();
931+
// Mocked method
932+
const mockedMethod = mock(MockedSendMethod);
933+
// Stub the method
934+
when(mockedContract.addInvestorToBlacklist).thenReturn(instance(mockedMethod));
935+
// Stub the request
936+
when(
937+
mockedMethod.sendTransactionAsync(
938+
mockedParams.userAddress,
939+
objectContaining(stringToBytes32(mockedParams.blacklistName)),
940+
mockedParams.txData,
941+
mockedParams.safetyFactor,
942+
),
943+
).thenResolve(expectedResult);
944+
945+
// Real call
946+
const result = await target.addInvestorToBlacklist(mockedParams);
947+
948+
// Result expectation
949+
expect(result).toBe(expectedResult);
950+
// Verifications
951+
verify(mockedContract.addInvestorToBlacklist).once();
952+
verify(
953+
mockedMethod.sendTransactionAsync(
954+
mockedParams.userAddress,
955+
objectContaining(stringToBytes32(mockedParams.blacklistName)),
956+
mockedParams.txData,
957+
mockedParams.safetyFactor,
958+
),
959+
).once();
960+
verify(mockedSecurityTokenOwnerMethod.callAsync()).once();
961+
verify(mockedSecurityTokenContract.owner).once();
962+
verify(mockedContract.securityToken).once();
963+
verify(mockedGetSecurityTokenAddressMethod.callAsync()).once();
964+
verify(mockedContractFactory.getSecurityTokenContract(expectedSecurityTokenAddress)).once();
965+
verify(mockedWrapper.getAvailableAddressesAsync()).once();
966+
verify(mockedContract.blacklists).once();
967+
verify(mockedBlacklistsMethod.callAsync(objectContaining(stringToBytes32(blacklistName)))).once();
968+
verify(mockedContract.getBlacklistNamesToUser).once();
969+
verify(mockedGetBlacklistNamesToUserMethod.callAsync(mockedGetBlacklistNamesToUserParams.user)).once();
970+
});
971+
});
972+
973+
describe('addInvestorToBlacklistMulti', () => {
974+
test('should call addInvestorToBlacklistMulti', async () => {
975+
const expectedOwnerResult = '0x8888888888888888888888888888888888888888';
976+
const expectedBlacklistInvestorAddresses = [
977+
'0x0123456789012345678901234567890123456789',
978+
'0x2222222222222222222222222222222222222222',
979+
'0x9999999999999999999999999999999999999999',
980+
];
981+
const blacklistName = 'Blacklist1';
982+
const expectedStartTime = dateToBigNumber(new Date(2030, 1));
983+
const expectedEndTime = dateToBigNumber(new Date(2031, 1));
984+
const expectedRepeatPeriodTime = new BigNumber(366);
985+
const expectedGetBlacklistResult = [expectedStartTime, expectedEndTime, expectedRepeatPeriodTime];
986+
987+
// Security Token Address expected
988+
const expectedSecurityTokenAddress = '0x3333333333333333333333333333333333333333';
989+
// Setup get Security Token Address
990+
const mockedGetSecurityTokenAddressMethod = mock(MockedCallMethod);
991+
when(mockedContract.securityToken).thenReturn(instance(mockedGetSecurityTokenAddressMethod));
992+
when(mockedGetSecurityTokenAddressMethod.callAsync()).thenResolve(expectedSecurityTokenAddress);
993+
when(mockedContractFactory.getSecurityTokenContract(expectedSecurityTokenAddress)).thenResolve(
994+
instance(mockedSecurityTokenContract),
995+
);
996+
997+
const mockedSecurityTokenOwnerMethod = mock(MockedCallMethod);
998+
when(mockedSecurityTokenOwnerMethod.callAsync()).thenResolve(expectedOwnerResult);
999+
when(mockedSecurityTokenContract.owner).thenReturn(instance(mockedSecurityTokenOwnerMethod));
1000+
1001+
// Mock web3 wrapper owner
1002+
when(mockedWrapper.getAvailableAddressesAsync()).thenResolve([expectedOwnerResult]);
1003+
1004+
// Mocked method
1005+
const mockedBlacklistsMethod = mock(MockedCallMethod);
1006+
// Stub the method
1007+
when(mockedContract.blacklists).thenReturn(instance(mockedBlacklistsMethod));
1008+
1009+
when(mockedBlacklistsMethod.callAsync(objectContaining(stringToBytes32(blacklistName)))).thenResolve(
1010+
expectedGetBlacklistResult,
1011+
);
1012+
1013+
const expectedGetBlacklistNamesToUserResult = stringArrayToBytes32Array(['Blacklist2', 'Blacklist3']);
1014+
// Mocked method
1015+
const mockedGetBlacklistNamesToUserMethod = mock(MockedCallMethod);
1016+
// Stub the method
1017+
when(mockedContract.getBlacklistNamesToUser).thenReturn(instance(mockedGetBlacklistNamesToUserMethod));
1018+
// Stub the request
1019+
1020+
for (let i = 0; i < expectedBlacklistInvestorAddresses.length; i += 1) {
1021+
when(mockedGetBlacklistNamesToUserMethod.callAsync(expectedBlacklistInvestorAddresses[i])).thenResolve(
1022+
expectedGetBlacklistNamesToUserResult,
1023+
);
1024+
}
1025+
1026+
const mockedParams = {
1027+
userAddresses: expectedBlacklistInvestorAddresses,
1028+
blacklistName,
1029+
txData: {},
1030+
safetyFactor: 10,
1031+
};
1032+
const expectedResult = getMockedPolyResponse();
1033+
// Mocked method
1034+
const mockedMethod = mock(MockedSendMethod);
1035+
// Stub the method
1036+
when(mockedContract.addInvestorToBlacklistMulti).thenReturn(instance(mockedMethod));
1037+
// Stub the request
1038+
when(
1039+
mockedMethod.sendTransactionAsync(
1040+
mockedParams.userAddresses,
1041+
objectContaining(stringToBytes32(mockedParams.blacklistName)),
1042+
mockedParams.txData,
1043+
mockedParams.safetyFactor,
1044+
),
1045+
).thenResolve(expectedResult);
1046+
1047+
// Real call
1048+
const result = await target.addInvestorToBlacklistMulti(mockedParams);
1049+
1050+
// Result expectation
1051+
expect(result).toBe(expectedResult);
1052+
// Verifications
1053+
verify(mockedContract.addInvestorToBlacklistMulti).once();
1054+
verify(
1055+
mockedMethod.sendTransactionAsync(
1056+
mockedParams.userAddresses,
1057+
objectContaining(stringToBytes32(mockedParams.blacklistName)),
1058+
mockedParams.txData,
1059+
mockedParams.safetyFactor,
1060+
),
1061+
).once();
1062+
verify(mockedSecurityTokenOwnerMethod.callAsync()).once();
1063+
verify(mockedSecurityTokenContract.owner).once();
1064+
verify(mockedContract.securityToken).once();
1065+
verify(mockedGetSecurityTokenAddressMethod.callAsync()).once();
1066+
verify(mockedContractFactory.getSecurityTokenContract(expectedSecurityTokenAddress)).once();
1067+
verify(mockedWrapper.getAvailableAddressesAsync()).once();
1068+
verify(mockedContract.blacklists).times(expectedBlacklistInvestorAddresses.length);
1069+
verify(mockedBlacklistsMethod.callAsync(objectContaining(stringToBytes32(blacklistName)))).times(
1070+
expectedBlacklistInvestorAddresses.length,
1071+
);
1072+
verify(mockedContract.getBlacklistNamesToUser).times(expectedBlacklistInvestorAddresses.length);
1073+
for (let i = 0; i < expectedBlacklistInvestorAddresses.length; i += 1) {
1074+
verify(mockedGetBlacklistNamesToUserMethod.callAsync(expectedBlacklistInvestorAddresses[i])).once();
1075+
}
1076+
});
1077+
});
1078+
8751079
describe('getListOfAddresses', () => {
8761080
test.todo('should fail as blacklist name is an empty string');
8771081

‎src/contract_wrappers/modules/transfer_manager/blacklist_transfer_manager_wrapper.ts‎

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ interface DeleteBlacklistTypeMultiParams extends TxParams {
180180
blacklistNames: string[];
181181
}
182182

183+
interface InvestorAndBlacklistParams extends TxParams {
184+
userAddress: string;
185+
blacklistName: string;
186+
}
187+
188+
interface InvestorAndBlacklistMultiParams extends TxParams {
189+
userAddresses: string[];
190+
blacklistName: string;
191+
}
192+
183193
// Return Types
184194

185195
interface VerifyTransfer {
@@ -235,7 +245,7 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
235245
* Return the blacklists
236246
*/
237247
public blacklists = async (params: BlacklistParams): Promise<BlacklistsDetails> => {
238-
assert.assert(params.blacklistName.length > 0, 'LockUp Details must not be an empty string');
248+
assert.assert(params.blacklistName.length > 0, 'Blacklist Details must not be an empty string');
239249
const result = await (await this.contract).blacklists.callAsync(stringToBytes32(params.blacklistName));
240250
return {
241251
startTime: bigNumberToDate(result[0]),
@@ -268,7 +278,7 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
268278
[params.startTimes, params.endTimes, params.blacklistNames, params.repeatPeriodTimes],
269279
'Argument arrays length mismatch',
270280
);
271-
assert.assert(params.startTimes.length > 0, 'Empty lockup information');
281+
assert.assert(params.startTimes.length > 0, 'Empty blacklist information');
272282
assert.assert(await this.isCallerAllowed(params.txData, Perm.Admin), 'Caller is not allowed');
273283
const results = [];
274284
for (let i = 0; i < params.startTimes.length; i += 1) {
@@ -316,7 +326,7 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
316326
[params.startTimes, params.endTimes, params.blacklistNames, params.repeatPeriodTimes],
317327
'Argument arrays length mismatch',
318328
);
319-
assert.assert(params.startTimes.length > 0, 'Empty lockup information');
329+
assert.assert(params.startTimes.length > 0, 'Empty blacklist information');
320330
assert.assert(await this.isCallerAllowed(params.txData, Perm.Admin), 'Caller is not allowed');
321331
const results = [];
322332
for (let i = 0; i < params.startTimes.length; i += 1) {
@@ -358,7 +368,7 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
358368
* deleteBlacklistTypeMulti
359369
*/
360370
public deleteBlacklistTypeMulti = async (params: DeleteBlacklistTypeMultiParams) => {
361-
assert.assert(params.blacklistNames.length > 0, 'Empty lockup information');
371+
assert.assert(params.blacklistNames.length > 0, 'Empty blacklist information');
362372
assert.assert(await this.isCallerAllowed(params.txData, Perm.Admin), 'Caller is not allowed');
363373
const results = [];
364374
for (let i = 0; i < params.blacklistNames.length; i += 1) {
@@ -372,11 +382,50 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
372382
);
373383
};
374384

385+
386+
/*
387+
* addInvestorToBlacklist
388+
*/
389+
public addInvestorToBlacklist = async (params: InvestorAndBlacklistParams) => {
390+
assert.assert(await this.isCallerAllowed(params.txData, Perm.Admin), 'Caller is not allowed');
391+
await this.checkAddInvestorToBlacklist(params);
392+
return (await this.contract).addInvestorToBlacklist.sendTransactionAsync(
393+
params.userAddress,
394+
stringToBytes32(params.blacklistName),
395+
params.txData,
396+
params.safetyFactor,
397+
);
398+
};
399+
400+
/*
401+
* addInvestorToBlacklistMulti
402+
*/
403+
public addInvestorToBlacklistMulti = async (params: InvestorAndBlacklistMultiParams) => {
404+
assert.assert(await this.isCallerAllowed(params.txData, Perm.Admin), 'Caller is not allowed');
405+
assert.assert(params.userAddresses.length > 0, 'Empty user address information');
406+
const results = [];
407+
for (let i = 0; i < params.userAddresses.length; i += 1) {
408+
results.push(
409+
this.checkAddInvestorToBlacklist({
410+
userAddress: params.userAddresses[i],
411+
blacklistName: params.blacklistName,
412+
}),
413+
);
414+
}
415+
await Promise.all(results);
416+
return (await this.contract).addInvestorToBlacklistMulti.sendTransactionAsync(
417+
params.userAddresses,
418+
stringToBytes32(params.blacklistName),
419+
params.txData,
420+
params.safetyFactor,
421+
);
422+
};
423+
375424
/**
376425
* getListOfAddresses
377426
*/
378427
public getListOfAddresses = async (params: BlacklistParams): Promise<string[]> => {
379-
assert.assert(params.blacklistName.length > 0, 'LockUp Details must not be an empty string');
428+
assert.assert(params.blacklistName.length > 0, 'Blacklist details must not be an empty string');
380429
return (await this.contract).getListOfAddresses.callAsync(stringToBytes32(params.blacklistName));
381430
};
382431

@@ -499,7 +548,7 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
499548
};
500549

501550
private checkBlacklistTypeDetails = async (params: BlacklistTypeParams) => {
502-
assert.assert(params.blacklistName.length > 0, 'Lockup Name cannot be empty string');
551+
assert.assert(params.blacklistName.length > 0, 'Blacklist Name cannot be empty string');
503552
assert.isFutureDate(params.startTime, 'Start time must be in the future');
504553
assert.assert(params.startTime < params.endTime, 'Start time must be before the end time');
505554
if (params.repeatPeriodTime !== 0) {
@@ -512,13 +561,26 @@ export default class BlacklistTransferManagerWrapper extends ModuleWrapper {
512561
};
513562

514563
private checkDeleteBlacklistType = async (blacklistName: string) => {
515-
assert.assert(blacklistName.length > 0, 'Lockup Name cannot be empty string');
564+
assert.assert(blacklistName.length > 0, 'Blacklist Name cannot be empty string');
516565
const blacklistsDetails = await this.blacklists({ blacklistName });
517-
assert.isNotDateZero(blacklistsDetails.endTime, 'Lockup does not exist');
566+
assert.isNotDateZero(blacklistsDetails.endTime, 'Blacklist does not exist');
518567
const lookupListOfAddresses = await this.getListOfAddresses({ blacklistName });
519568
assert.assert(
520569
lookupListOfAddresses.length === 0,
521-
'There are users attached to the lockup that must be removed before removing the lockup type',
570+
'There are users attached to the blacklist that must be removed before removing the blacklist type',
522571
);
523572
};
573+
574+
private checkBlacklistToModifyInvestors = async (params: InvestorAndBlacklistParams) => {
575+
assert.assert(params.blacklistName.length > 0, 'Blacklist name cannot be empty string');
576+
assert.isNonZeroETHAddressHex('User Address', params.userAddress);
577+
const blacklistsDetails = await this.blacklists({ blacklistName: params.blacklistName });
578+
assert.isNotDateZero(blacklistsDetails.endTime, 'Lockup does not exist');
579+
};
580+
581+
private checkAddInvestorToBlacklist = async (params: InvestorAndBlacklistParams) => {
582+
await this.checkBlacklistToModifyInvestors(params);
583+
const currentBlacklistNames = await this.getBlacklistNamesToUser({ user: params.userAddress });
584+
assert.assert(!currentBlacklistNames.includes(params.blacklistName), 'User already added to this blacklist name');
585+
};
524586
}

0 commit comments

Comments
 (0)