In the implementation, many uses of the type address could be made more specific.
Example:
contract CountdownGriefing_Factory is Factory {
constructor(address instanceRegistry, address templateContract) public {
CountdownGriefing template;
// set instance type
bytes4 instanceType = bytes4(keccak256(bytes('Agreement')));
// set initSelector
bytes4 initSelector = template.initialize.selector;
// initialize factory params
Factory._initialize(instanceRegistry, templateContract, instanceType, initSelector);
}
}
could become:
contract CountdownGriefing_Factory is Factory {
constructor(iRegistry instanceRegistry, CountdownGriefing templateContract) public {
// set instance type
bytes4 instanceType = bytes4(keccak256(bytes('Agreement')));
// set initSelector
bytes4 initSelector = templateContract.initialize.selector;
// initialize factory params
Factory._initialize(instanceRegistry, templateContract, instanceType, initSelector);
}
}
Type safety improves the ability of static analyzers to help you code, removes the necessity of type casting, and are a best practice.
Recommendation: review every parameter and variable of type address and use a more specific class if it represents a contract address.
Recommendation: update Factory to inherit from iFactory.
Recommendation: update iNMR to inherit from IERC20.
In the implementation, many uses of the type
addresscould be made more specific.Example:
could become:
Type safety improves the ability of static analyzers to help you code, removes the necessity of type casting, and are a best practice.
Recommendation: review every parameter and variable of type
addressand use a more specific class if it represents a contract address.Recommendation: update
Factoryto inherit fromiFactory.Recommendation: update
iNMRto inherit fromIERC20.