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

Commit 7df0edd

Browse files
committed
feat: 🎸 add method to validate if an address is a valid module
isValidModule use isModule contract method to verify if an address and module type are valid or not, preventing runtime errors
1 parent 4ee0c97 commit 7df0edd

File tree

3 files changed

+61
-14
lines changed

3 files changed

+61
-14
lines changed

‎src/contract_wrappers/modules/module_factory_wrapper.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export default class ModuleFactoryWrapper extends ContractWrapper {
170170
*/
171171
public getTypes = async (): Promise<ModuleType[]> => {
172172
return (await (await this.contract).getTypes.callAsync()).map(type => {
173-
return parseModuleTypeValue(type);
173+
return parseModuleTypeValue(new BigNumber(type));
174174
});
175175
};
176176

‎src/contract_wrappers/modules/module_wrapper.ts‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import {
55
ERC20DetailedContract,
66
Web3Wrapper,
77
TxData,
8+
BigNumber,
89
} from '@polymathnetwork/abi-wrappers';
910
import ContractWrapper from '../contract_wrapper';
1011
import ContractFactory from '../../factories/contractFactory';
1112
import { TxParams, GenericModuleContract, GetLogs, Subscribe } from '../../types';
12-
import { stringToBytes32 } from '../../utils/convert';
13+
import { stringToBytes32, parseModuleTypeValue } from '../../utils/convert';
1314
import functionsUtils from '../../utils/functions_utils';
1415
import assert from '../../utils/assert';
1516

@@ -97,6 +98,31 @@ export default class ModuleWrapper extends ContractWrapper {
9798
);
9899
};
99100

101+
public isValidModule = async () => {
102+
const moduleFactoryContract = await this.moduleFactoryContract();
103+
const getTypes = await moduleFactoryContract.getTypes.callAsync();
104+
const types = getTypes.filter(type => {
105+
// type '6' is valid but it is not mapped, so we must filter this kind of scenarios
106+
try {
107+
parseModuleTypeValue(new BigNumber(type));
108+
return true;
109+
} catch (e) {
110+
return false;
111+
}
112+
});
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) {
119+
return false;
120+
}
121+
const address = await this.address();
122+
const result = await (await this.securityTokenContract()).isModule.callAsync(address, types[0]);
123+
return result;
124+
};
125+
100126
protected isCallerTheSecurityTokenOwner = async (txData: Partial<TxData> | undefined): Promise<boolean> => {
101127
const from = await this.getCallerAddress(txData);
102128
return functionsUtils.checksumAddressComparision(

‎src/factories/moduleWrapperFactory.ts‎

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,88 +105,109 @@ export default class ModuleWrapperFactory {
105105
// eslint-disable-next-line @typescript-eslint/no-explicit-any
106106
public getModuleInstance: GetModuleInstance = async (params: GetModuleParams): Promise<any> => {
107107
assert.isETHAddressHex('address', params.address);
108+
let moduleWrapper;
108109
switch (params.name) {
109110
// Permission
110111
case ModuleName.GeneralPermissionManager:
111-
return new GeneralPermissionManagerWrapper(
112+
moduleWrapper = new GeneralPermissionManagerWrapper(
112113
this.web3Wrapper,
113114
this.contractFactory.getGeneralPermissionManagerContract(params.address),
114115
this.contractFactory,
115116
);
117+
break;
116118
// TMs
117119
case ModuleName.CountTransferManager:
118-
return new CountTransferManagerWrapper(
120+
moduleWrapper = new CountTransferManagerWrapper(
119121
this.web3Wrapper,
120122
this.contractFactory.getCountTransferManagerContract(params.address),
121123
this.contractFactory,
122124
);
125+
break;
123126
case ModuleName.GeneralTransferManager:
124-
return new GeneralTransferManagerWrapper(
127+
moduleWrapper = new GeneralTransferManagerWrapper(
125128
this.web3Wrapper,
126129
this.contractFactory.getGeneralTransferManagerContract(params.address),
127130
this.contractFactory,
128131
);
132+
break;
129133
case ModuleName.ManualApprovalTransferManager:
130-
return new ManualApprovalTransferManagerWrapper(
134+
moduleWrapper = new ManualApprovalTransferManagerWrapper(
131135
this.web3Wrapper,
132136
this.contractFactory.getManualApprovalTransferManagerContract(params.address),
133137
this.contractFactory,
134138
);
139+
break;
135140
case ModuleName.PercentageTransferManager:
136-
return new PercentageTransferManagerWrapper(
141+
moduleWrapper = new PercentageTransferManagerWrapper(
137142
this.web3Wrapper,
138143
this.contractFactory.getPercentageTransferManagerContract(params.address),
139144
this.contractFactory,
140145
);
146+
break;
141147
case ModuleName.LockUpTransferManager:
142-
return new LockUpTransferManagerWrapper(
148+
moduleWrapper = new LockUpTransferManagerWrapper(
143149
this.web3Wrapper,
144150
this.contractFactory.getLockUpTransferManagerContract(params.address),
145151
this.contractFactory,
146152
);
153+
break;
147154
case ModuleName.VolumeRestrictionTM:
148-
return new VolumeRestrictionTransferManagerWrapper(
155+
moduleWrapper = new VolumeRestrictionTransferManagerWrapper(
149156
this.web3Wrapper,
150157
this.contractFactory.getVolumeRestrictionTMContract(params.address),
151158
this.contractFactory,
152159
);
160+
break;
153161
// STOs
154162
case ModuleName.CappedSTO:
155-
return new CappedSTOWrapper(
163+
moduleWrapper = new CappedSTOWrapper(
156164
this.web3Wrapper,
157165
this.contractFactory.getCappedSTOContract(params.address),
158166
this.contractFactory,
159167
);
168+
break;
160169
case ModuleName.UsdTieredSTO:
161-
return new USDTieredSTOWrapper(
170+
moduleWrapper = new USDTieredSTOWrapper(
162171
this.web3Wrapper,
163172
this.contractFactory.getUSDTieredSTOContract(params.address),
164173
this.contractFactory,
165174
);
175+
break;
166176
// Checkpoint
167177
case ModuleName.ERC20DividendCheckpoint:
168-
return new ERC20DividendCheckpointWrapper(
178+
moduleWrapper = new ERC20DividendCheckpointWrapper(
169179
this.web3Wrapper,
170180
this.contractFactory.getERC20DividendCheckpointContract(params.address),
171181
this.contractFactory,
172182
);
183+
break;
173184
case ModuleName.EtherDividendCheckpoint:
174-
return new EtherDividendCheckpointWrapper(
185+
moduleWrapper = new EtherDividendCheckpointWrapper(
175186
this.web3Wrapper,
176187
this.contractFactory.getEtherDividendCheckpointContract(params.address),
177188
this.contractFactory,
178189
);
190+
break;
179191
// Wallet
180192
case ModuleName.VestingEscrowWallet:
181-
return new VestingEscrowWalletWrapper(
193+
moduleWrapper = new VestingEscrowWalletWrapper(
182194
this.web3Wrapper,
183195
this.contractFactory.getVestingEscrowWalletContract(params.address),
184196
this.contractFactory,
185197
);
198+
break;
186199
// Burn
187200
default:
188201
// TODO: Typed error here
189202
throw new Error();
190203
}
204+
205+
// validate module
206+
if (await moduleWrapper.isValidModule()) {
207+
return moduleWrapper;
208+
}
209+
210+
// TODO: Typed error here
211+
throw new Error('Invalid module');
191212
};
192213
}

0 commit comments

Comments
 (0)