diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 841443126..ec204914a 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -48,7 +48,9 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { // Emit when the Module Factory gets registered on the ModuleRegistry contract event ModuleRegistered(address indexed _moduleFactory, address indexed _owner); // Emit when the module gets verified by Polymath - event ModuleVerified(address indexed _moduleFactory, bool _verified); + event ModuleVerified(address indexed _moduleFactory); + // Emit when the module gets unverified by Polymath or the factory owner + event ModuleUnverified(address indexed _moduleFactory); // Emit when a ModuleFactory is removed by Polymath event ModuleRemoved(address indexed _moduleFactory, address indexed _decisionMaker); // Emit when ownership gets transferred @@ -117,30 +119,40 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @dev Any module can be added during token creation without being registered if it is defined in the token proxy deployment contract * @dev The feature switch for custom modules is labelled "customModulesAllowed" * @param _moduleFactory is the address of the relevant module factory + * @param _isUpgrade whether or not the function is being called as a result of an upgrade */ - function useModule(address _moduleFactory) external { - // This if statement is required to be able to add modules from the token proxy contract during deployment + function useModule(address _moduleFactory, bool _isUpgrade) external { + if (IFeatureRegistry(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { + require( + getBoolValue(Encoder.getKey("verified", _moduleFactory)) || IOwnable(_moduleFactory).owner() == IOwnable(msg.sender).owner(), + "ModuleFactory must be verified or SecurityToken owner must be ModuleFactory owner" + ); + } else { + require(getBoolValue(Encoder.getKey("verified", _moduleFactory)), "ModuleFactory must be verified"); + } + // This if statement is required to be able to add modules from the STFactory contract during deployment + // before the token has been registered to the STR. if (ISecurityTokenRegistry(getAddressValue(Encoder.getKey("securityTokenRegistry"))).isSecurityToken(msg.sender)) { - if (IFeatureRegistry(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { - require( - getBoolValue(Encoder.getKey("verified", _moduleFactory)) || IOwnable(_moduleFactory).owner() == IOwnable(msg.sender).owner(), - "ModuleFactory must be verified or SecurityToken owner must be ModuleFactory owner" - ); - } else { - require(getBoolValue(Encoder.getKey("verified", _moduleFactory)), "ModuleFactory must be verified"); + require(isCompatibleModule(_moduleFactory, msg.sender), "Incompatible versions"); + if (!_isUpgrade) { + pushArray(Encoder.getKey("reputation", _moduleFactory), msg.sender); + emit ModuleUsed(_moduleFactory, msg.sender); } - require(_isCompatibleModule(_moduleFactory, msg.sender), "Version should within the compatible range of ST"); - pushArray(Encoder.getKey("reputation", _moduleFactory), msg.sender); - emit ModuleUsed(_moduleFactory, msg.sender); } } - function _isCompatibleModule(address _moduleFactory, address _securityToken) internal view returns(bool) { + /** + * @notice Check that a module and its factory are compatible + * @param _moduleFactory is the address of the relevant module factory + * @param _securityToken is the address of the relevant security token + * @return bool whether module and token are compatible + */ + function isCompatibleModule(address _moduleFactory, address _securityToken) public view returns(bool) { uint8[] memory _latestVersion = ISecurityToken(_securityToken).getVersion(); uint8[] memory _lowerBound = IModuleFactory(_moduleFactory).lowerSTVersionBounds(); uint8[] memory _upperBound = IModuleFactory(_moduleFactory).upperSTVersionBounds(); - bool _isLowerAllowed = VersionUtils.compareLowerBound(_lowerBound, _latestVersion); - bool _isUpperAllowed = VersionUtils.compareUpperBound(_upperBound, _latestVersion); + bool _isLowerAllowed = VersionUtils.lessThanOrEqual(_lowerBound, _latestVersion); + bool _isUpperAllowed = VersionUtils.greaterThanOrEqual(_upperBound, _latestVersion); return (_isLowerAllowed && _isUpperAllowed); } @@ -221,12 +233,29 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @notice (The only exception to this is that the author of the module is the owner of the ST) * @notice -> Only if Polymath enabled the feature. * @param _moduleFactory is the address of the module factory to be verified - * @return bool */ - function verifyModule(address _moduleFactory, bool _verified) external onlyOwner { + function verifyModule(address _moduleFactory) external onlyOwner { require(getUintValue(Encoder.getKey("registry", _moduleFactory)) != uint256(0), "Module factory must be registered"); - set(Encoder.getKey("verified", _moduleFactory), _verified); - emit ModuleVerified(_moduleFactory, _verified); + set(Encoder.getKey("verified", _moduleFactory), true); + emit ModuleVerified(_moduleFactory); + } + + /** + * @notice Called by Polymath to verify Module Factories for SecurityTokens to use. + * @notice A module can not be used by an ST unless first approved/verified by Polymath + * @notice (The only exception to this is that the author of the module is the owner of the ST) + * @notice -> Only if Polymath enabled the feature. + * @param _moduleFactory is the address of the module factory to be verified + */ + function unverifyModule(address _moduleFactory) external { + // Can be called by the registry owner, the module factory, or the module factory owner + bool isOwner = msg.sender == owner(); + bool isFactoryOwner = msg.sender == IOwnable(_moduleFactory).owner(); + bool isFactory = msg.sender == _moduleFactory; + require(isOwner || isFactoryOwner || isFactory, "Not authorised"); + require(getUintValue(Encoder.getKey("registry", _moduleFactory)) != uint256(0), "Module factory must be registered"); + set(Encoder.getKey("verified", _moduleFactory), false); + emit ModuleUnverified(_moduleFactory); } /** @@ -281,12 +310,13 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } /** - * @notice Returns the reputation of the entered Module Factory + * @notice Returns the verified status, and reputation of the entered Module Factory * @param _factoryAddress is the address of the module factory + * @return bool indicating whether module factory is verified * @return address array which contains the list of securityTokens that use that module factory */ - function getReputationByFactory(address _factoryAddress) external view returns(address[] memory) { - return getArrayAddress(Encoder.getKey("reputation", _factoryAddress)); + function getFactoryDetails(address _factoryAddress) external view returns(bool, address[] memory) { + return (getBoolValue(Encoder.getKey("verified", _factoryAddress)), getArrayAddress(Encoder.getKey("reputation", _factoryAddress))); } /** @@ -305,8 +335,8 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return address array that contains the list of available addresses of module factory contracts. */ function getModulesByTypeAndToken(uint8 _moduleType, address _securityToken) public view returns(address[] memory) { - uint256 _len = getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))).length; address[] memory _addressList = getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))); + uint256 _len = _addressList.length; bool _isCustomModuleAllowed = IFeatureRegistry(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus( "customModulesAllowed" ); @@ -315,9 +345,9 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { if (_isCustomModuleAllowed) { if (IOwnable(_addressList[i]).owner() == IOwnable(_securityToken).owner() || getBoolValue( Encoder.getKey("verified", _addressList[i]) - )) if (_isCompatibleModule(_addressList[i], _securityToken)) counter++; + )) if (isCompatibleModule(_addressList[i], _securityToken)) counter++; } else if (getBoolValue(Encoder.getKey("verified", _addressList[i]))) { - if (_isCompatibleModule(_addressList[i], _securityToken)) counter++; + if (isCompatibleModule(_addressList[i], _securityToken)) counter++; } } address[] memory _tempArray = new address[](counter); @@ -327,13 +357,13 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { if (IOwnable(_addressList[j]).owner() == IOwnable(_securityToken).owner() || getBoolValue( Encoder.getKey("verified", _addressList[j]) )) { - if (_isCompatibleModule(_addressList[j], _securityToken)) { + if (isCompatibleModule(_addressList[j], _securityToken)) { _tempArray[counter] = _addressList[j]; counter++; } } } else if (getBoolValue(Encoder.getKey("verified", _addressList[j]))) { - if (_isCompatibleModule(_addressList[j], _securityToken)) { + if (isCompatibleModule(_addressList[j], _securityToken)) { _tempArray[counter] = _addressList[j]; counter++; } diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index 0b03ac6c8..7f2250ee0 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -121,7 +121,9 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { uint256 _usdFee, uint256 _polyFee ); - + event ProtocolFactorySet(address indexed _STFactory, uint8 _major, uint8 _minor, uint8 _patch); + event LatestVersionSet(uint8 _major, uint8 _minor, uint8 _patch); + event ProtocolFactoryRemoved(address indexed _STFactory, uint8 _major, uint8 _minor, uint8 _patch); ///////////////////////////// // Modifiers ///////////////////////////// @@ -168,7 +170,6 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { /** * @notice Initializes instance of STR * @param _polymathRegistry is the address of the Polymath Registry - * @param _STFactory is the address of the Proxy contract for Security Tokens * @param _stLaunchFee is the fee in USD required to launch a token * @param _tickerRegFee is the fee in USD required to register a ticker * @param _owner is the owner of the STR, @@ -176,7 +177,6 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { */ function initialize( address _polymathRegistry, - address _STFactory, uint256 _stLaunchFee, uint256 _tickerRegFee, address _owner, @@ -187,17 +187,15 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { { require(!getBoolValue(INITIALIZE),"Initialized"); require( - _STFactory != address(0) && _owner != address(0) && _polymathRegistry != address(0) && _getterContract != address(0), + _owner != address(0) && _polymathRegistry != address(0) && _getterContract != address(0), "Invalid address" ); - require(_stLaunchFee != 0 && _tickerRegFee != 0, "Bad fee"); set(STLAUNCHFEE, _stLaunchFee); set(TICKERREGFEE, _tickerRegFee); set(EXPIRYLIMIT, uint256(60 * 1 days)); set(PAUSED, false); set(OWNER, _owner); set(POLYMATHREGISTRY, _polymathRegistry); - _setProtocolVersion(_STFactory, uint8(2), uint8(0), uint8(0)); set(INITIALIZE, true); set(STRGETTER, _getterContract); _updateFromRegistry(); @@ -716,7 +714,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { } /** - * @notice Changes the protocol version and the SecurityToken contract + * @notice Changes the SecurityToken contract for a particular factory version * @notice Used only by Polymath to upgrade the SecurityToken contract and add more functionalities to future versions * @notice Changing versions does not affect existing tokens. * @param _STFactoryAddress is the address of the proxy. @@ -724,26 +722,48 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { * @param _minor Minor version of the proxy. * @param _patch Patch version of the proxy */ - function setProtocolVersion(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { + function setProtocolFactory(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { + _setProtocolFactory(_STFactoryAddress, _major, _minor, _patch); + } + + function _setProtocolFactory(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) internal { require(_STFactoryAddress != address(0), "Bad address"); - _setProtocolVersion(_STFactoryAddress, _major, _minor, _patch); + uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); + //set(Encoder.getKey("latestVersion"), uint256(_packedVersion)); + set(Encoder.getKey("protocolVersionST", uint256(_packedVersion)), _STFactoryAddress); + emit ProtocolFactorySet(_STFactoryAddress, _major, _minor, _patch); } /** - * @notice Internal - Changes the protocol version and the SecurityToken contract + * @notice Removes a STFactory + * @param _major Major version of the proxy. + * @param _minor Minor version of the proxy. + * @param _patch Patch version of the proxy */ - function _setProtocolVersion(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) internal { - uint8[] memory _version = new uint8[](3); - _version[0] = _major; - _version[1] = _minor; - _version[2] = _patch; + function removeProtocolFactory(uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); - require( - VersionUtils.isValidVersion(VersionUtils.unpack(uint24(getUintValue(Encoder.getKey("latestVersion")))), _version), - "Bad version" - ); + require(getUintValue(Encoder.getKey("latestVersion")) != _packedVersion, "Cannot remove latestVersion"); + emit ProtocolFactoryRemoved(getAddressValue(Encoder.getKey("protocolVersionST", _packedVersion)), _major, _minor, _patch); + set(Encoder.getKey("protocolVersionST", uint256(_packedVersion)), address(0)); + } + + /** + * @notice Changes the default protocol version + * @notice Used only by Polymath to upgrade the SecurityToken contract and add more functionalities to future versions + * @notice Changing versions does not affect existing tokens. + * @param _major Major version of the proxy. + * @param _minor Minor version of the proxy. + * @param _patch Patch version of the proxy + */ + function setLatestVersion(uint8 _major, uint8 _minor, uint8 _patch) external onlyOwner { + _setLatestVersion(_major, _minor, _patch); + } + + function _setLatestVersion(uint8 _major, uint8 _minor, uint8 _patch) internal { + uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); + require(getAddressValue(Encoder.getKey("protocolVersionST", _packedVersion)) != address(0), "No factory"); set(Encoder.getKey("latestVersion"), uint256(_packedVersion)); - set(Encoder.getKey("protocolVersionST", getUintValue(Encoder.getKey("latestVersion"))), _STFactoryAddress); + emit LatestVersionSet(_major, _minor, _patch); } /** diff --git a/contracts/interfaces/IModuleRegistry.sol b/contracts/interfaces/IModuleRegistry.sol index 0d4af763e..a1bff3dcb 100644 --- a/contracts/interfaces/IModuleRegistry.sol +++ b/contracts/interfaces/IModuleRegistry.sol @@ -7,8 +7,9 @@ interface IModuleRegistry { /** * @notice Called by a security token to notify the registry it is using a module * @param _moduleFactory is the address of the relevant module factory + * @param _isUpgrade whether the use is part of an existing module upgrade */ - function useModule(address _moduleFactory) external; + function useModule(address _moduleFactory, bool _isUpgrade) external; /** * @notice Called by the ModuleFactory owner to register new modules for SecurityToken to use @@ -22,20 +23,37 @@ interface IModuleRegistry { */ function removeModule(address _moduleFactory) external; + /** + * @notice Check that a module and its factory are compatible + * @param _moduleFactory is the address of the relevant module factory + * @param _securityToken is the address of the relevant security token + * @return bool whether module and token are compatible + */ + function isCompatibleModule(address _moduleFactory, address _securityToken) external view returns(bool); + /** * @notice Called by Polymath to verify modules for SecurityToken to use. * @notice A module can not be used by an ST unless first approved/verified by Polymath * @notice (The only exception to this is that the author of the module is the owner of the ST - Only if enabled by the FeatureRegistry) * @param _moduleFactory is the address of the module factory to be registered */ - function verifyModule(address _moduleFactory, bool _verified) external; + function verifyModule(address _moduleFactory) external; + + /** + * @notice Called by Polymath to unverify modules for SecurityToken to use. + * @notice A module can not be used by an ST unless first approved/verified by Polymath + * @notice (The only exception to this is that the author of the module is the owner of the ST - Only if enabled by the FeatureRegistry) + * @param _moduleFactory is the address of the module factory to be registered + */ + function unverifyModule(address _moduleFactory) external; /** - * @notice Used to get the reputation of a Module Factory - * @param _factoryAddress address of the Module Factory - * @return address array which has the list of securityToken's uses that module factory + * @notice Returns the verified status, and reputation of the entered Module Factory + * @param _factoryAddress is the address of the module factory + * @return bool indicating whether module factory is verified + * @return address array which contains the list of securityTokens that use that module factory */ - function getReputationByFactory(address _factoryAddress) external view returns(address[] memory); + function getFactoryDetails(address _factoryAddress) external view returns(bool, address[] memory); /** * @notice Returns all the tags related to the a module type which are valid for the given token @@ -82,7 +100,7 @@ interface IModuleRegistry { /** * @notice Check whether the contract operations is paused or not - * @return bool + * @return bool */ function isPaused() external view returns(bool); diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index a91f72c42..3406a6bbe 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -30,6 +30,13 @@ interface ISecurityToken { */ function canTransfer(address _to, uint256 _value, bytes calldata _data) external view returns (bool, byte, bytes32); + /** + * @notice Initialization function + * @dev Expected to be called atomically with the proxy being created, by the owner of the token + * @dev Can only be called once + */ + function initialize() external; + /** * @notice Transfers of securities may fail for a number of reasons. So this function will used to understand the * cause of failure by getting the byte value. Which will be the ESC that follows the EIP 1066. ESC can be mapped @@ -247,12 +254,19 @@ interface ISecurityToken { */ function changeDataStore(address _dataStore) external; - /** - * @notice Allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token. - * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee. - * @param _tokenContract Address of the ERC20Basic compliance token - * @param _value Amount of POLY to withdraw - */ + + /** + * @notice Allows to change the treasury wallet address + * @param _wallet Ethereum address of the treasury wallet + */ + function changeTreasuryWallet(address _wallet) external; + + /** + * @notice Allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token. + * @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee. + * @param _tokenContract Address of the ERC20Basic compliance token + * @param _value Amount of POLY to withdraw + */ function withdrawERC20(address _tokenContract, uint256 _value) external; /** @@ -305,13 +319,15 @@ interface ISecurityToken { * @param _maxCost max amount of POLY willing to pay to the module. * @param _budget max amount of ongoing POLY willing to assign to the module. * @param _label custom module label. + * @param _archived whether to add the module as an archived module */ function addModuleWithLabel( address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget, - bytes32 _label + bytes32 _label, + bool _archived ) external; /** @@ -325,8 +341,9 @@ interface ISecurityToken { * @param _data is data packed into bytes used to further configure the module (See STO usage) * @param _maxCost max amount of POLY willing to pay to module. (WIP) * @param _budget max amount of ongoing POLY willing to assign to the module. + * @param _archived whether to add the module as an archived module */ - function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget) external; + function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget, bool _archived) external; /** * @notice Archives a module attached to the SecurityToken @@ -427,6 +444,17 @@ interface ISecurityToken { */ function granularity() external view returns(uint256); + /** + * @notice Upgrades a module attached to the SecurityToken + * @param _module address of module to archive + */ + function upgradeModule(address _module) external; + + /** + * @notice Upgrades security token + */ + function upgradeToken() external; + /** * @notice A security token issuer can specify that issuance has finished for the token * (i.e. no new tokens can be minted or issued). diff --git a/contracts/interfaces/IUpgradableTokenFactory.sol b/contracts/interfaces/IUpgradableTokenFactory.sol new file mode 100644 index 000000000..b5bfe3156 --- /dev/null +++ b/contracts/interfaces/IUpgradableTokenFactory.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.5.0; + +/** + * @title Interface to be implemented by upgradable token factories + */ +interface IUpgradableTokenFactory { + + /** + * @notice Used to upgrade a token + * @param _maxModuleType maximum module type enumeration + */ + function upgradeToken(uint8 _maxModuleType) external; + +} diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index a181b7e52..6ec57ae06 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -134,9 +134,11 @@ library TokenLib { * @notice Unarchives a module attached to the SecurityToken * @param _moduleData Storage data */ - function unarchiveModule(SecurityTokenStorage.ModuleData storage _moduleData) public { + function unarchiveModule(address _moduleRegistry, SecurityTokenStorage.ModuleData storage _moduleData) public { require(_moduleData.isArchived, "Module unarchived"); /*solium-disable-next-line security/no-block-members*/ + // Check the version is still valid - can only be false if token was upgraded between unarchive / archive + IModuleRegistry(_moduleRegistry).useModule(_moduleData.moduleFactory, true); emit ModuleUnarchived(_moduleData.moduleTypes, _moduleData.module); _moduleData.isArchived = false; } @@ -145,8 +147,10 @@ library TokenLib { * @notice Upgrades a module attached to the SecurityToken * @param _moduleData Storage data */ - function upgradeModule(SecurityTokenStorage.ModuleData storage _moduleData) public { + function upgradeModule(address _moduleRegistry, SecurityTokenStorage.ModuleData storage _moduleData) public { require(_moduleData.module != address(0), "Module missing"); + //Check module is verified and within version bounds + IModuleRegistry(_moduleRegistry).useModule(_moduleData.moduleFactory, true); // Will revert if module isn't upgradable UpgradableModuleFactory(_moduleData.moduleFactory).upgrade(_moduleData.module); emit ModuleUpgraded(_moduleData.moduleTypes, _moduleData.module); diff --git a/contracts/libraries/VersionUtils.sol b/contracts/libraries/VersionUtils.sol index 4b1ba2698..fa4fc5c56 100644 --- a/contracts/libraries/VersionUtils.sol +++ b/contracts/libraries/VersionUtils.sol @@ -5,83 +5,29 @@ pragma solidity ^0.5.0; */ library VersionUtils { - /** - * @notice This function is used to validate the version submitted - * @param _current Array holds the present version of ST - * @param _new Array holds the latest version of the ST - * @return bool - */ - function isValidVersion(uint8[] memory _current, uint8[] memory _new) internal pure returns(bool) { - bool[] memory _temp = new bool[](_current.length); - uint8 counter = 0; - uint8 i = 0; - for (i = 0; i < _current.length; i++) { - if (_current[i] < _new[i]) _temp[i] = true; - else _temp[i] = false; - } + function lessThanOrEqual(uint8[] memory _current, uint8[] memory _new) internal pure returns(bool) { + require(_current.length == 3); + require(_new.length == 3); + uint8 i = 0; for (i = 0; i < _current.length; i++) { - if (i == 0) { - if (_current[i] <= _new[i]) if (_temp[0]) { - counter = counter + 3; - break; - } else counter++; - else return false; - } else { - if (_temp[i - 1]) counter++; - else if (_current[i] <= _new[i]) counter++; - else return false; - } + if (_current[i] == _new[i]) continue; + if (_current[i] < _new[i]) return true; + if (_current[i] > _new[i]) return false; } - if (counter == _current.length) return true; + return true; } - /** - * @notice Used to compare the lower bound with the latest version - * @param _version1 Array holds the lower bound of the version - * @param _version2 Array holds the latest version of the ST - * @return bool - */ - function compareLowerBound(uint8[] memory _version1, uint8[] memory _version2) internal pure returns(bool) { - require(_version1.length == _version2.length, "Input length mismatch"); - uint counter = 0; - for (uint8 j = 0; j < _version1.length; j++) { - if (_version1[j] == 0) counter++; - } - if (counter != _version1.length) { - counter = 0; - for (uint8 i = 0; i < _version1.length; i++) { - if (_version2[i] > _version1[i]) return true; - else if (_version2[i] < _version1[i]) return false; - else counter++; - } - if (counter == _version1.length - 1) return true; - else return false; - } else return true; - } - - /** - * @notice Used to compare the upper bound with the latest version - * @param _version1 Array holds the upper bound of the version - * @param _version2 Array holds the latest version of the ST - * @return bool - */ - function compareUpperBound(uint8[] memory _version1, uint8[] memory _version2) internal pure returns(bool) { - require(_version1.length == _version2.length, "Input length mismatch"); - uint counter = 0; - for (uint8 j = 0; j < _version1.length; j++) { - if (_version1[j] == 0) counter++; + function greaterThanOrEqual(uint8[] memory _current, uint8[] memory _new) internal pure returns(bool) { + require(_current.length == 3); + require(_new.length == 3); + uint8 i = 0; + for (i = 0; i < _current.length; i++) { + if (_current[i] == _new[i]) continue; + if (_current[i] > _new[i]) return true; + if (_current[i] < _new[i]) return false; } - if (counter != _version1.length) { - counter = 0; - for (uint8 i = 0; i < _version1.length; i++) { - if (_version1[i] > _version2[i]) return true; - else if (_version1[i] < _version2[i]) return false; - else counter++; - } - if (counter == _version1.length - 1) return true; - else return false; - } else return true; + return true; } /** diff --git a/contracts/mocks/Dummy/DummySTOFactory.sol b/contracts/mocks/Dummy/DummySTOFactory.sol index 1e8816890..640d0a7d7 100644 --- a/contracts/mocks/Dummy/DummySTOFactory.sol +++ b/contracts/mocks/Dummy/DummySTOFactory.sol @@ -35,8 +35,8 @@ contract DummySTOFactory is UpgradableModuleFactory { tagsData.push("Dummy"); tagsData.push("ETH"); tagsData.push("STO"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -45,7 +45,7 @@ contract DummySTOFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address dummySTO = address(new DummySTOProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address dummySTO = address(new DummySTOProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(dummySTO, _data); return dummySTO; } diff --git a/contracts/mocks/MockSTGetter.sol b/contracts/mocks/MockSTGetter.sol new file mode 100644 index 000000000..4e7acdedb --- /dev/null +++ b/contracts/mocks/MockSTGetter.sol @@ -0,0 +1,24 @@ +pragma solidity ^0.5.0; + +import "../tokens/STGetter.sol"; + +/** + * @title Security Token contract (mock) + * @notice SecurityToken is an ERC1400 token with added capabilities: + * @notice - Implements the ERC1400 Interface + * @notice - Transfers are restricted + * @notice - Modules can be attached to it to control its behaviour + * @notice - ST should not be deployed directly, but rather the SecurityTokenRegistry should be used + * @notice - ST does not inherit from ISecurityToken due to: + * @notice - https://github.com/ethereum/solidity/issues/4847 + */ +contract MockSTGetter is STGetter { + using SafeMath for uint256; + + event UpgradeEvent(uint256 _upgrade); + + function newGetter(uint256 _upgrade) public { + emit UpgradeEvent(_upgrade); + } + +} diff --git a/contracts/mocks/MockSecurityTokenLogic.sol b/contracts/mocks/MockSecurityTokenLogic.sol new file mode 100644 index 000000000..aad797f34 --- /dev/null +++ b/contracts/mocks/MockSecurityTokenLogic.sol @@ -0,0 +1,37 @@ +pragma solidity ^0.5.0; + +import "../tokens/SecurityToken.sol"; + +/** + * @title Security Token contract (mock) + * @notice SecurityToken is an ERC1400 token with added capabilities: + * @notice - Implements the ERC1400 Interface + * @notice - Transfers are restricted + * @notice - Modules can be attached to it to control its behaviour + * @notice - ST should not be deployed directly, but rather the SecurityTokenRegistry should be used + * @notice - ST does not inherit from ISecurityToken due to: + * @notice - https://github.com/ethereum/solidity/issues/4847 + */ +contract MockSecurityTokenLogic is SecurityToken { + using SafeMath for uint256; + + event UpgradeEvent(uint256 _upgrade); + + /** + * @notice Initialization function + * @dev Expected to be called atomically with the proxy being created, by the owner of the token + * @dev Can only be called once + */ + function upgrade(address _getterDelegate, uint256 _upgrade) external { + require(msg.sender == address(this), "Incorrect caller"); + //Expected to be called atomically with the proxy being created + getterDelegate = _getterDelegate; + //securityTokenVersion = SemanticVersion(3, 1, 0); + emit UpgradeEvent(_upgrade); + } + + function newFunction(uint256 _upgrade) public { + emit UpgradeEvent(_upgrade); + } + +} diff --git a/contracts/mocks/STFactoryMock.sol b/contracts/mocks/STFactoryMock.sol index 78aeecf74..b117fcebd 100644 --- a/contracts/mocks/STFactoryMock.sol +++ b/contracts/mocks/STFactoryMock.sol @@ -29,11 +29,11 @@ contract STFactoryMock is ISTFactory { string calldata _tokenDetails, address _issuer, bool _divisible, - address _treasuryWallet, + address /* _treasuryWallet */, address _polymathRegistry - ) - external - returns(address) + ) + external + returns(address) { SecurityTokenMock newSecurityToken = new SecurityTokenMock( _name, @@ -45,9 +45,7 @@ contract STFactoryMock is ISTFactory { stDelegate ); //NB When dataStore is generated, the security token address is automatically set via the constructor in DataStoreProxy. - newSecurityToken.changeDataStore(dataStoreFactory.generateDataStore(address(newSecurityToken))); - newSecurityToken.changeTreasuryWallet(_treasuryWallet); - newSecurityToken.addModule(transferManagerFactory, "", 0, 0); + newSecurityToken.addModule(transferManagerFactory, "", 0, 0, false); newSecurityToken.transferOwnership(_issuer); return address(newSecurityToken); } diff --git a/contracts/mocks/SecurityTokenMock.sol b/contracts/mocks/SecurityTokenMock.sol index 3dd60d645..a8a7d7cd6 100644 --- a/contracts/mocks/SecurityTokenMock.sol +++ b/contracts/mocks/SecurityTokenMock.sol @@ -13,31 +13,31 @@ import "../tokens/SecurityToken.sol"; * @notice - https://github.com/ethereum/solidity/issues/4847 */ contract SecurityTokenMock is SecurityToken { - + /** - * @notice constructor + * @notice constructor * @param _name Name of the SecurityToken * @param _symbol Symbol of the Token * @param _decimals Decimals for the securityToken - * @param _granularity granular level of the token - * @param _tokenDetails Details of the token that are stored off-chain - * @param _polymathRegistry Contract address of the polymath registry - * @param _delegate Contract address of the delegate */ constructor( string memory _name, string memory _symbol, uint8 _decimals, - uint256 _granularity, - string memory _tokenDetails, + uint256 /* _granularity */, + string memory /* _tokenDetails */, address _polymathRegistry, address _delegate - ) - public - SecurityToken(_name, _symbol, _decimals, _granularity, _tokenDetails, _polymathRegistry,_delegate) + ) + public { + _owner = msg.sender; + polymathRegistry = _polymathRegistry; + //When it is created, the owner is the STR + updateFromRegistry(); + getterDelegate = _delegate; securityTokenVersion = SemanticVersion(2, 2, 0); } - + } diff --git a/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpointFactory.sol b/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpointFactory.sol index 45e25cd3d..30b88f1b9 100644 --- a/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpointFactory.sol @@ -35,8 +35,8 @@ contract ERC20DividendCheckpointFactory is UpgradableModuleFactory { tagsData.push("ERC20"); tagsData.push("Dividend"); tagsData.push("Checkpoint"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -44,7 +44,7 @@ contract ERC20DividendCheckpointFactory is UpgradableModuleFactory { * @return Address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address erc20DividendCheckpoint = address(new ERC20DividendCheckpointProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address erc20DividendCheckpoint = address(new ERC20DividendCheckpointProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(erc20DividendCheckpoint, _data); return erc20DividendCheckpoint; } diff --git a/contracts/modules/Checkpoint/Ether/EtherDividendCheckpointFactory.sol b/contracts/modules/Checkpoint/Ether/EtherDividendCheckpointFactory.sol index 839981ef5..7cd20074e 100644 --- a/contracts/modules/Checkpoint/Ether/EtherDividendCheckpointFactory.sol +++ b/contracts/modules/Checkpoint/Ether/EtherDividendCheckpointFactory.sol @@ -35,8 +35,8 @@ contract EtherDividendCheckpointFactory is UpgradableModuleFactory { tagsData.push("Ether"); tagsData.push("Dividend"); tagsData.push("Checkpoint"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -44,7 +44,7 @@ contract EtherDividendCheckpointFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address ethDividendCheckpoint = address(new EtherDividendCheckpointProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address ethDividendCheckpoint = address(new EtherDividendCheckpointProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(ethDividendCheckpoint, _data); return ethDividendCheckpoint; } diff --git a/contracts/modules/Experimental/Burn/TrackedRedemptionFactory.sol b/contracts/modules/Experimental/Burn/TrackedRedemptionFactory.sol index a8f487afe..db7da70ef 100644 --- a/contracts/modules/Experimental/Burn/TrackedRedemptionFactory.sol +++ b/contracts/modules/Experimental/Burn/TrackedRedemptionFactory.sol @@ -29,8 +29,8 @@ contract TrackedRedemptionFactory is ModuleFactory { typesData.push(5); tagsData.push("Tracked"); tagsData.push("Redemption"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** diff --git a/contracts/modules/Experimental/Mixed/ScheduledCheckpointFactory.sol b/contracts/modules/Experimental/Mixed/ScheduledCheckpointFactory.sol index 44decf02d..99ddf7b8e 100644 --- a/contracts/modules/Experimental/Mixed/ScheduledCheckpointFactory.sol +++ b/contracts/modules/Experimental/Mixed/ScheduledCheckpointFactory.sol @@ -30,8 +30,8 @@ contract ScheduledCheckpointFactory is ModuleFactory { typesData.push(2); tagsData.push("Scheduled"); tagsData.push("Checkpoint"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** diff --git a/contracts/modules/Experimental/TransferManager/BlacklistTransferManagerFactory.sol b/contracts/modules/Experimental/TransferManager/BlacklistTransferManagerFactory.sol index 32b91105b..4aae8b4cc 100644 --- a/contracts/modules/Experimental/TransferManager/BlacklistTransferManagerFactory.sol +++ b/contracts/modules/Experimental/TransferManager/BlacklistTransferManagerFactory.sol @@ -31,8 +31,8 @@ contract BlacklistTransferManagerFactory is ModuleFactory { typesData.push(2); tagsData.push("Blacklist"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** diff --git a/contracts/modules/Experimental/TransferManager/KYCTransferManagerFactory.sol b/contracts/modules/Experimental/TransferManager/KYCTransferManagerFactory.sol index f21b95454..a0c0912cb 100644 --- a/contracts/modules/Experimental/TransferManager/KYCTransferManagerFactory.sol +++ b/contracts/modules/Experimental/TransferManager/KYCTransferManagerFactory.sol @@ -25,8 +25,8 @@ contract KYCTransferManagerFactory is ModuleFactory { typesData.push(6); tagsData.push("KYC"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } diff --git a/contracts/modules/Experimental/TransferManager/LTM/LockUpTransferManagerFactory.sol b/contracts/modules/Experimental/TransferManager/LTM/LockUpTransferManagerFactory.sol index 7bd81fc4d..ddeb53b4a 100644 --- a/contracts/modules/Experimental/TransferManager/LTM/LockUpTransferManagerFactory.sol +++ b/contracts/modules/Experimental/TransferManager/LTM/LockUpTransferManagerFactory.sol @@ -32,8 +32,8 @@ contract LockUpTransferManagerFactory is UpgradableModuleFactory { typesData.push(2); tagsData.push("LockUp"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -46,7 +46,7 @@ contract LockUpTransferManagerFactory is UpgradableModuleFactory { external returns(address) { - address lockUpTransferManager = address(new LockUpTransferManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address lockUpTransferManager = address(new LockUpTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(lockUpTransferManager, _data); return lockUpTransferManager; } diff --git a/contracts/modules/Experimental/TransferManager/SignedTransferManagerFactory.sol b/contracts/modules/Experimental/TransferManager/SignedTransferManagerFactory.sol index 2f04e9030..74826a9d9 100644 --- a/contracts/modules/Experimental/TransferManager/SignedTransferManagerFactory.sol +++ b/contracts/modules/Experimental/TransferManager/SignedTransferManagerFactory.sol @@ -27,8 +27,8 @@ contract SignedTransferManagerFactory is ModuleFactory { typesData.push(6); tagsData.push("Signed"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } diff --git a/contracts/modules/Experimental/Wallet/VestingEscrowWalletFactory.sol b/contracts/modules/Experimental/Wallet/VestingEscrowWalletFactory.sol index c5354e58e..d755e151a 100644 --- a/contracts/modules/Experimental/Wallet/VestingEscrowWalletFactory.sol +++ b/contracts/modules/Experimental/Wallet/VestingEscrowWalletFactory.sol @@ -30,8 +30,8 @@ contract VestingEscrowWalletFactory is UpgradableModuleFactory { tagsData.push("Vesting"); tagsData.push("Escrow"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -40,7 +40,7 @@ contract VestingEscrowWalletFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address vestingEscrowWallet = address(new VestingEscrowWalletProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address vestingEscrowWallet = address(new VestingEscrowWalletProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(vestingEscrowWallet, _data); return vestingEscrowWallet; } diff --git a/contracts/modules/ModuleFactory.sol b/contracts/modules/ModuleFactory.sol index 0b0a467bb..676d9773f 100644 --- a/contracts/modules/ModuleFactory.sol +++ b/contracts/modules/ModuleFactory.sol @@ -149,12 +149,16 @@ contract ModuleFactory is IModuleFactory, Ownable { keccak256(abi.encodePacked(_boundType)) == keccak256(abi.encodePacked("lowerBound")) || keccak256( abi.encodePacked(_boundType) ) == keccak256(abi.encodePacked("upperBound")), - "Must be a valid bound type" + "Invalid bound type" ); - require(_newVersion.length == 3); + require(_newVersion.length == 3, "Invalid version"); if (compatibleSTVersionRange[_boundType] != uint24(0)) { uint8[] memory _currentVersion = VersionUtils.unpack(compatibleSTVersionRange[_boundType]); - require(VersionUtils.isValidVersion(_currentVersion, _newVersion), "Failed because of in-valid version"); + if (keccak256(abi.encodePacked(_boundType)) == keccak256(abi.encodePacked("lowerBound"))) { + require(VersionUtils.lessThanOrEqual(_newVersion, _currentVersion), "Invalid version"); + } else { + require(VersionUtils.greaterThanOrEqual(_newVersion, _currentVersion), "Invalid version"); + } } compatibleSTVersionRange[_boundType] = VersionUtils.pack(_newVersion[0], _newVersion[1], _newVersion[2]); emit ChangeSTVersionBound(_boundType, _newVersion[0], _newVersion[1], _newVersion[2]); diff --git a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol index d7578a1b1..6a95b2473 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManagerFactory.sol @@ -31,8 +31,8 @@ contract GeneralPermissionManagerFactory is UpgradableModuleFactory { description = "Manage permissions within the Security Token and attached modules"; typesData.push(1); tagsData.push("Permission Management"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -45,7 +45,7 @@ contract GeneralPermissionManagerFactory is UpgradableModuleFactory { external returns(address) { - address permissionManager = address(new GeneralPermissionManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address permissionManager = address(new GeneralPermissionManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(permissionManager, _data); return permissionManager; } diff --git a/contracts/modules/STO/Capped/CappedSTOFactory.sol b/contracts/modules/STO/Capped/CappedSTOFactory.sol index 9b2fd6535..a724c60d3 100644 --- a/contracts/modules/STO/Capped/CappedSTOFactory.sol +++ b/contracts/modules/STO/Capped/CappedSTOFactory.sol @@ -36,8 +36,8 @@ contract CappedSTOFactory is UpgradableModuleFactory { tagsData.push("ETH"); tagsData.push("POLY"); tagsData.push("STO"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -46,7 +46,7 @@ contract CappedSTOFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address cappedSTO = address(new CappedSTOProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address cappedSTO = address(new CappedSTOProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(cappedSTO, _data); return cappedSTO; } diff --git a/contracts/modules/STO/PreSale/PreSaleSTOFactory.sol b/contracts/modules/STO/PreSale/PreSaleSTOFactory.sol index 1555f9f00..cee2e5409 100644 --- a/contracts/modules/STO/PreSale/PreSaleSTOFactory.sol +++ b/contracts/modules/STO/PreSale/PreSaleSTOFactory.sol @@ -34,8 +34,8 @@ contract PreSaleSTOFactory is UpgradableModuleFactory { typesData.push(3); tagsData.push("PreSale"); tagsData.push("STO"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -44,7 +44,7 @@ contract PreSaleSTOFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address preSaleSTO = address(new PreSaleSTOProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address preSaleSTO = address(new PreSaleSTOProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(preSaleSTO, _data); return preSaleSTO; } diff --git a/contracts/modules/STO/USDTiered/USDTieredSTOFactory.sol b/contracts/modules/STO/USDTiered/USDTieredSTOFactory.sol index b3fcd091d..f0810a677 100644 --- a/contracts/modules/STO/USDTiered/USDTieredSTOFactory.sol +++ b/contracts/modules/STO/USDTiered/USDTieredSTOFactory.sol @@ -38,8 +38,8 @@ contract USDTieredSTOFactory is UpgradableModuleFactory { tagsData.push("POLY"); tagsData.push("USD"); tagsData.push("STO"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -47,7 +47,7 @@ contract USDTieredSTOFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address usdTieredSTO = address(new USDTieredSTOProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address usdTieredSTO = address(new USDTieredSTOProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(usdTieredSTO, _data); return usdTieredSTO; } diff --git a/contracts/modules/TransferManager/CTM/CountTransferManagerFactory.sol b/contracts/modules/TransferManager/CTM/CountTransferManagerFactory.sol index 13ec55efe..397aca56a 100644 --- a/contracts/modules/TransferManager/CTM/CountTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/CTM/CountTransferManagerFactory.sol @@ -32,8 +32,8 @@ contract CountTransferManagerFactory is UpgradableModuleFactory { typesData.push(2); tagsData.push("Count"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -42,7 +42,7 @@ contract CountTransferManagerFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address countTransferManager = address(new CountTransferManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address countTransferManager = address(new CountTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(countTransferManager, _data); return countTransferManager; } diff --git a/contracts/modules/TransferManager/GTM/GeneralTransferManagerFactory.sol b/contracts/modules/TransferManager/GTM/GeneralTransferManagerFactory.sol index 4487c37f6..3d4e15b85 100644 --- a/contracts/modules/TransferManager/GTM/GeneralTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/GTM/GeneralTransferManagerFactory.sol @@ -33,8 +33,8 @@ contract GeneralTransferManagerFactory is UpgradableModuleFactory { typesData.push(6); tagsData.push("General"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -47,7 +47,7 @@ contract GeneralTransferManagerFactory is UpgradableModuleFactory { external returns(address) { - address generalTransferManager = address(new GeneralTransferManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address generalTransferManager = address(new GeneralTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(generalTransferManager, _data); return generalTransferManager; } diff --git a/contracts/modules/TransferManager/MATM/ManualApprovalTransferManagerFactory.sol b/contracts/modules/TransferManager/MATM/ManualApprovalTransferManagerFactory.sol index fce05a095..0d671a388 100644 --- a/contracts/modules/TransferManager/MATM/ManualApprovalTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/MATM/ManualApprovalTransferManagerFactory.sol @@ -32,8 +32,8 @@ contract ManualApprovalTransferManagerFactory is UpgradableModuleFactory { typesData.push(2); tagsData.push("Manual Approval"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -46,7 +46,7 @@ contract ManualApprovalTransferManagerFactory is UpgradableModuleFactory { external returns(address) { - address manualTransferManager = address(new ManualApprovalTransferManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address manualTransferManager = address(new ManualApprovalTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(manualTransferManager, _data); return manualTransferManager; } diff --git a/contracts/modules/TransferManager/PTM/PercentageTransferManagerFactory.sol b/contracts/modules/TransferManager/PTM/PercentageTransferManagerFactory.sol index f1ad4bd87..b9c782b09 100644 --- a/contracts/modules/TransferManager/PTM/PercentageTransferManagerFactory.sol +++ b/contracts/modules/TransferManager/PTM/PercentageTransferManagerFactory.sol @@ -34,8 +34,8 @@ contract PercentageTransferManagerFactory is UpgradableModuleFactory { typesData.push(2); tagsData.push("Percentage"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -44,7 +44,7 @@ contract PercentageTransferManagerFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address percentageTransferManager = address(new PercentageTransferManagerProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address percentageTransferManager = address(new PercentageTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(percentageTransferManager, _data); return percentageTransferManager; } diff --git a/contracts/modules/TransferManager/VRTM/VolumeRestrictionTMFactory.sol b/contracts/modules/TransferManager/VRTM/VolumeRestrictionTMFactory.sol index a55c36702..a9f3c3939 100644 --- a/contracts/modules/TransferManager/VRTM/VolumeRestrictionTMFactory.sol +++ b/contracts/modules/TransferManager/VRTM/VolumeRestrictionTMFactory.sol @@ -34,8 +34,8 @@ contract VolumeRestrictionTMFactory is UpgradableModuleFactory { tagsData.push("Rolling Period"); tagsData.push("Volume"); tagsData.push("Transfer Restriction"); - compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); - compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(0), uint8(0), uint8(0)); + compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); + compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0)); } /** @@ -43,7 +43,7 @@ contract VolumeRestrictionTMFactory is UpgradableModuleFactory { * @return address Contract address of the Module */ function deploy(bytes calldata _data) external returns(address) { - address volumeRestrictionTransferManager = address(new VolumeRestrictionTMProxy(logicContracts[latestVersion].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestVersion].logicContract)); + address volumeRestrictionTransferManager = address(new VolumeRestrictionTMProxy(logicContracts[latestUpgrade].version, msg.sender, IPolymathRegistry(polymathRegistry).getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract)); _initializeModule(volumeRestrictionTransferManager, _data); return volumeRestrictionTransferManager; } diff --git a/contracts/modules/UpgradableModuleFactory.sol b/contracts/modules/UpgradableModuleFactory.sol index a28e4d58e..01dab6430 100644 --- a/contracts/modules/UpgradableModuleFactory.sol +++ b/contracts/modules/UpgradableModuleFactory.sol @@ -1,30 +1,32 @@ pragma solidity ^0.5.0; import "./ModuleFactory.sol"; +import "../interfaces/IModuleRegistry.sol"; import "../proxy/OwnedUpgradeabilityProxy.sol"; + /** * @title Factory for deploying upgradable modules */ contract UpgradableModuleFactory is ModuleFactory { - event LogicContractSet(string _version, address _logicContract, bytes _logicData); + event LogicContractSet(string _version, address _logicContract, bytes _upgradeData); + + event ModuleUpgraded( + address indexed _module, + address indexed _securityToken, + uint256 indexed _version + ); struct LogicContract { string version; address logicContract; - bytes logicData; + bytes upgradeData; } // Mapping from version to logic contract mapping (uint256 => LogicContract) logicContracts; - // Mapping from Security Token address to module version - /* mapping (address => uint256) moduleVersions; */ - - // Mapping from Security Token address to module address - /* mapping (address => address) modules; */ - // Mapping from Security Token address, to deployed proxy module address, to module version mapping (address => mapping (address => uint256)) modules; @@ -32,7 +34,7 @@ contract UpgradableModuleFactory is ModuleFactory { mapping (address => address) moduleToSecurityToken; // Current version - uint256 public latestVersion; + uint256 public latestUpgrade; /** * @notice Constructor @@ -53,25 +55,27 @@ contract UpgradableModuleFactory is ModuleFactory { public ModuleFactory(_setupCost, _usageCost, _polymathRegistry, _isCostInPoly) { require(_logicContract != address(0), "Invalid address"); - logicContracts[latestVersion].logicContract = _logicContract; - logicContracts[latestVersion].version = _version; + logicContracts[latestUpgrade].logicContract = _logicContract; + logicContracts[latestUpgrade].version = _version; } /** * @notice Used to upgrade the module factory * @param _version Version of upgraded module * @param _logicContract Address of deployed module logic contract referenced from proxy - * @param _logicData Data to be passed in call to upgradeToAndCall when a token upgrades its module + * @param _upgradeData Data to be passed in call to upgradeToAndCall when a token upgrades its module */ - function setLogicContract(string calldata _version, address _logicContract, bytes calldata _logicData) external onlyOwner { - require(keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(logicContracts[latestVersion].version)), "Same version"); - require(_logicContract != logicContracts[latestVersion].logicContract, "Same version"); + function setLogicContract(string calldata _version, address _logicContract, bytes calldata _upgradeData) external onlyOwner { + require(keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(logicContracts[latestUpgrade].version)), "Same version"); + require(_logicContract != logicContracts[latestUpgrade].logicContract, "Same version"); require(_logicContract != address(0), "Invalid address"); - latestVersion++; - logicContracts[latestVersion].logicContract = _logicContract; - logicContracts[latestVersion].logicData = _logicData; - logicContracts[latestVersion].version = _version; - emit LogicContractSet(_version, _logicContract, _logicData); + latestUpgrade++; + logicContracts[latestUpgrade].version = _version; + logicContracts[latestUpgrade].logicContract = _logicContract; + logicContracts[latestUpgrade].upgradeData = _upgradeData; + IModuleRegistry moduleRegistry = IModuleRegistry(IPolymathRegistry(polymathRegistry).getAddress("ModuleRegistry")); + moduleRegistry.unverifyModule(address(this)); + emit LogicContractSet(_version, _logicContract, _upgradeData); } /** @@ -83,10 +87,14 @@ contract UpgradableModuleFactory is ModuleFactory { require(moduleToSecurityToken[_module] == msg.sender, "Incorrect caller"); // Only allow issuers to upgrade in single step verisons to preserve upgradeToAndCall semantics uint256 newVersion = modules[msg.sender][_module] + 1; - /* uint256 newVersion = moduleVersions[msg.sender] + 1; */ - require(newVersion <= latestVersion, "Incorrect version"); - OwnedUpgradeabilityProxy(address(uint160(_module))).upgradeToAndCall(logicContracts[newVersion].version, logicContracts[newVersion].logicContract, logicContracts[newVersion].logicData); + require(newVersion <= latestUpgrade, "Incorrect version"); + OwnedUpgradeabilityProxy(address(uint160(_module))).upgradeToAndCall(logicContracts[newVersion].version, logicContracts[newVersion].logicContract, logicContracts[newVersion].upgradeData); modules[msg.sender][_module] = newVersion; + emit ModuleUpgraded( + _module, + msg.sender, + newVersion + ); } /** @@ -97,15 +105,14 @@ contract UpgradableModuleFactory is ModuleFactory { function _initializeModule(address _module, bytes memory _data) internal { super._initializeModule(_module, _data); moduleToSecurityToken[_module] = msg.sender; - modules[msg.sender][_module] = latestVersion; - /* modules[msg.sender] = _module; */ + modules[msg.sender][_module] = latestUpgrade; } /** * @notice Get the version related to the module factory */ function version() external view returns(string memory) { - return logicContracts[latestVersion].version; + return logicContracts[latestUpgrade].version; } } diff --git a/contracts/proxy/OwnedUpgradeabilityProxy.sol b/contracts/proxy/OwnedUpgradeabilityProxy.sol index 314dc23cb..f81fc289d 100644 --- a/contracts/proxy/OwnedUpgradeabilityProxy.sol +++ b/contracts/proxy/OwnedUpgradeabilityProxy.sol @@ -110,6 +110,10 @@ contract OwnedUpgradeabilityProxy is UpgradeabilityProxy { * signature of the implementation to be called with the needed payload */ function upgradeToAndCall(string calldata _newVersion, address _newImplementation, bytes calldata _data) external payable ifOwner { + _upgradeToAndCall(_newVersion, _newImplementation, _data); + } + + function _upgradeToAndCall(string memory _newVersion, address _newImplementation, bytes memory _data) internal { _upgradeTo(_newVersion, _newImplementation); bool success; /*solium-disable-next-line security/no-call-value*/ diff --git a/contracts/tokens/OZStorage.sol b/contracts/tokens/OZStorage.sol index 0556cabe7..01e415c0a 100644 --- a/contracts/tokens/OZStorage.sol +++ b/contracts/tokens/OZStorage.sol @@ -2,13 +2,11 @@ pragma solidity ^0.5.0; contract OZStorage { - mapping (address => uint256) private _balances; + mapping (address => uint256) public _balances; - mapping (address => mapping (address => uint256)) private _allowed; + mapping (address => mapping (address => uint256)) public _allowed; - uint256 private _totalSupply; - - address private _owner; + uint256 public _totalSupply; /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; diff --git a/contracts/tokens/STFactory.sol b/contracts/tokens/STFactory.sol index 2befe7908..d09e04e97 100644 --- a/contracts/tokens/STFactory.sol +++ b/contracts/tokens/STFactory.sol @@ -1,21 +1,62 @@ pragma solidity ^0.5.0; -import "./SecurityToken.sol"; +import "./SecurityTokenProxy.sol"; +import "../proxy/OwnedUpgradeabilityProxy.sol"; import "../interfaces/ISTFactory.sol"; +import "../interfaces/ISecurityToken.sol"; +import "../interfaces/IPolymathRegistry.sol"; +import "../interfaces/IOwnable.sol"; +import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; +import "../interfaces/IModuleRegistry.sol"; +import "../interfaces/IPolymathRegistry.sol"; import "../datastore/DataStoreFactory.sol"; /** * @title Proxy for deploying SecurityToken instances */ -contract STFactory is ISTFactory { +contract STFactory is ISTFactory, Ownable { + address public transferManagerFactory; - address public stDelegate; DataStoreFactory public dataStoreFactory; + IPolymathRegistry public polymathRegistry; + + // Mapping from Security Token address to token upgrade version. + // A mapping to 0 means a token has not yet been deployed + mapping (address => uint256) tokenUpgrade; + + struct LogicContract { + string version; + address logicContract; + bytes initializationData; // Called when first creating token + bytes upgradeData; // Called when upgrading token from previous version + } + + mapping (uint256 => LogicContract) logicContracts; - constructor(address _transferManagerFactory, address _dataStoreFactory, address _stDelegate) public { + uint256 public latestUpgrade; + + event LogicContractSet(string _version, address _logicContract, bytes _upgradeData); + event TokenUpgraded( + address indexed _securityToken, + uint256 indexed _version + ); + event DefaultTransferManagerUpdated(address indexed _oldTransferManagerFactory, address indexed _newTransferManagerFactory); + event DefaultDataStoreUpdated(address indexed _oldDataStoreFactory, address indexed _newDataStoreFactory); + + constructor(address _polymathRegistry, address _transferManagerFactory, address _dataStoreFactory, string memory _version, address _logicContract, bytes memory _initializationData) public { + require(_logicContract != address(0), "Invalid Address"); + require(_transferManagerFactory != address(0), "Invalid Address"); + require(_dataStoreFactory != address(0), "Invalid Address"); + require(_polymathRegistry != address(0), "Invalid Address"); transferManagerFactory = _transferManagerFactory; dataStoreFactory = DataStoreFactory(_dataStoreFactory); - stDelegate = _stDelegate; + polymathRegistry = IPolymathRegistry(_polymathRegistry); + + // Start at 1 so that we can distinguish deployed tokens in tokenUpgrade + latestUpgrade = 1; + logicContracts[latestUpgrade].logicContract = _logicContract; + logicContracts[latestUpgrade].initializationData = _initializationData; + logicContracts[latestUpgrade].version = _version; } /** @@ -30,25 +71,120 @@ contract STFactory is ISTFactory { address _issuer, bool _divisible, address _treasuryWallet, - address _polymathRegistry - ) - external - returns(address) + address /* _polymathRegistry */ + ) + external + returns(address) { - SecurityToken newSecurityToken = new SecurityToken( + address securityToken = _deploy( _name, _symbol, _decimals, - _divisible ? 1 : uint256(10) ** _decimals, _tokenDetails, - _polymathRegistry, - stDelegate + _divisible ); //NB When dataStore is generated, the security token address is automatically set via the constructor in DataStoreProxy. - newSecurityToken.changeDataStore(dataStoreFactory.generateDataStore(address(newSecurityToken))); - newSecurityToken.changeTreasuryWallet(_treasuryWallet); - newSecurityToken.addModule(transferManagerFactory, "", 0, 0); - newSecurityToken.transferOwnership(_issuer); - return address(newSecurityToken); + if (address(dataStoreFactory) != address(0)) { + ISecurityToken(securityToken).changeDataStore(dataStoreFactory.generateDataStore(securityToken)); + } + ISecurityToken(securityToken).changeTreasuryWallet(_treasuryWallet); + if (transferManagerFactory != address(0)) { + ISecurityToken(securityToken).addModule(transferManagerFactory, "", 0, 0, false); + } + IOwnable(securityToken).transferOwnership(_issuer); + return securityToken; } + + function _deploy( + string memory _name, + string memory _symbol, + uint8 _decimals, + string memory _tokenDetails, + bool _divisible + ) internal returns(address) { + // Creates proxy contract and sets some initial storage + SecurityTokenProxy proxy = new SecurityTokenProxy( + _name, + _symbol, + _decimals, + _divisible ? 1 : uint256(10) ** _decimals, + _tokenDetails, + address(polymathRegistry) + ); + // Sets logic contract + proxy.upgradeTo(logicContracts[latestUpgrade].version, logicContracts[latestUpgrade].logicContract); + // Initialises security token contract - needed for functions that can only be called by the + // owner of the contract, or are specific to this particular logic contract (e.g. setting version) + (bool success, ) = address(proxy).call(logicContracts[latestUpgrade].initializationData); + require(success, "Unsuccessful initialization"); + tokenUpgrade[address(proxy)] = latestUpgrade; + return address(proxy); + } + + /** + * @notice Used to set a new token logic contract + * @param _version Version of upgraded module + * @param _logicContract Address of deployed module logic contract referenced from proxy + * @param _upgradeData Data to be passed in call to upgradeToAndCall when a token upgrades its module + */ + function setLogicContract(string calldata _version, address _logicContract, bytes calldata _upgradeData) external onlyOwner { + require(keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(logicContracts[latestUpgrade].version)), "Same version"); + require(_logicContract != logicContracts[latestUpgrade].logicContract, "Same version"); + require(_logicContract != address(0), "Invalid address"); + latestUpgrade++; + logicContracts[latestUpgrade].version = _version; + logicContracts[latestUpgrade].logicContract = _logicContract; + logicContracts[latestUpgrade].upgradeData = _upgradeData; + emit LogicContractSet(_version, _logicContract, _upgradeData); + } + + /** + * @notice Used to upgrade a token + * @param _maxModuleType maximum module type enumeration + */ + function upgradeToken(uint8 _maxModuleType) external { + // Check the token was created by this factory + require(tokenUpgrade[msg.sender] != 0, "Invalid token"); + uint256 newVersion = tokenUpgrade[msg.sender] + 1; + require(newVersion <= latestUpgrade, "Incorrect version"); + OwnedUpgradeabilityProxy(address(uint160(msg.sender))).upgradeToAndCall(logicContracts[newVersion].version, logicContracts[newVersion].logicContract, logicContracts[newVersion].upgradeData); + tokenUpgrade[msg.sender] = newVersion; + // Check that all modules remain valid + IModuleRegistry moduleRegistry = IModuleRegistry(polymathRegistry.getAddress("ModuleRegistry")); + address moduleFactory; + bool isArchived; + for (uint8 i = 1; i < _maxModuleType; i++) { + address[] memory modules = ISecurityToken(msg.sender).getModulesByType(i); + for (uint256 j = 0; j < modules.length; j++) { + (,, moduleFactory, isArchived,,) = ISecurityToken(msg.sender).getModule(modules[j]); + if (!isArchived) { + require(moduleRegistry.isCompatibleModule(moduleFactory, msg.sender), "Incompatible Modules"); + } + } + } + emit TokenUpgraded(msg.sender, newVersion); + } + + /** + * @notice Used to set a new default transfer manager + * @dev Setting this to address(0) means don't deploy a default TM + * @param _transferManagerFactory Address of new default transfer manager factory + */ + function updateDefaultTransferManager(address _transferManagerFactory) external onlyOwner { + // NB - setting this to address(0) means don't deploy a default TM + emit DefaultTransferManagerUpdated(transferManagerFactory, _transferManagerFactory); + transferManagerFactory = _transferManagerFactory; + } + + /** + * @notice Used to set a new default data store + * @dev Setting this to address(0) means don't deploy a default data store + * @param _dataStoreFactory Address of new default data store factory + */ + function updateDefaultDataStore(address _dataStoreFactory) external onlyOwner { + // NB - setting this to address(0) means don't deploy a default TM + emit DefaultDataStoreUpdated(address(dataStoreFactory), address(_dataStoreFactory)); + dataStoreFactory = DataStoreFactory(_dataStoreFactory); + } + } diff --git a/contracts/tokens/STGetter.sol b/contracts/tokens/STGetter.sol index 49bb1eb46..f0ede2cb4 100644 --- a/contracts/tokens/STGetter.sol +++ b/contracts/tokens/STGetter.sol @@ -11,29 +11,6 @@ contract STGetter is OZStorage, SecurityTokenStorage { using SafeMath for uint256; - /** - * @notice Used to return the details of a document with a known name (`bytes32`). - * @param _name Name of the document - * @return string The URI associated with the document. - * @return bytes32 The hash (of the contents) of the document. - * @return uint256 the timestamp at which the document was last modified. - */ - function getDocument(bytes32 _name) external view returns (string memory, bytes32, uint256) { - return ( - _documents[_name].uri, - _documents[_name].docHash, - _documents[_name].lastModified - ); - } - - /** - * @notice Used to retrieve a full list of documents attached to the smart contract. - * @return bytes32 List of all documents names present in the contract. - */ - function getAllDocuments() external view returns (bytes32[] memory) { - return _docNames; - } - /** * @notice Gets list of times that checkpoints were created * @return List of checkpoint times @@ -239,11 +216,33 @@ contract STGetter is OZStorage, SecurityTokenStorage { * @notice Returns the version of the SecurityToken */ function getVersion() external view returns(uint8[] memory) { - uint8[] memory _version = new uint8[](3); - _version[0] = securityTokenVersion.major; - _version[1] = securityTokenVersion.minor; - _version[2] = securityTokenVersion.patch; - return _version; + uint8[] memory version = new uint8[](3); + version[0] = securityTokenVersion.major; + version[1] = securityTokenVersion.minor; + version[2] = securityTokenVersion.patch; + return version; } + /** + * @notice Used to return the details of a document with a known name (`bytes32`). + * @param _name Name of the document + * @return string The URI associated with the document. + * @return bytes32 The hash (of the contents) of the document. + * @return uint256 the timestamp at which the document was last modified. + */ + function getDocument(bytes32 _name) external view returns (string memory, bytes32, uint256) { + return ( + _documents[_name].uri, + _documents[_name].docHash, + _documents[_name].lastModified + ); + } + + /** + * @notice Used to retrieve a full list of documents attached to the smart contract. + * @return bytes32 List of all documents names present in the contract. + */ + function getAllDocuments() external view returns (bytes32[] memory) { + return _docNames; + } } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 8991733ad..1128dfe81 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -7,13 +7,13 @@ import "../interfaces/IModule.sol"; import "./SecurityTokenStorage.sol"; import "../libraries/TokenLib.sol"; import "../interfaces/IDataStore.sol"; +import "../interfaces/IUpgradableTokenFactory.sol"; import "../interfaces/IModuleFactory.sol"; import "../interfaces/token/IERC1594.sol"; import "../interfaces/token/IERC1643.sol"; import "../interfaces/token/IERC1644.sol"; import "../interfaces/IModuleRegistry.sol"; import "../interfaces/ITransferManager.sol"; -import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol"; import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; @@ -27,7 +27,7 @@ import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; * @notice - ST does not inherit from ISecurityToken due to: * @notice - https://github.com/ethereum/solidity/issues/4847 */ -contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, IERC1594, IERC1643, IERC1644, Proxy { +contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594, IERC1643, IERC1644, Proxy { using SafeMath for uint256; @@ -39,7 +39,8 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, address _module, uint256 _moduleCost, uint256 _budget, - bytes32 _label + bytes32 _label, + bool _archived ); // Emit when the token details get updated @@ -67,6 +68,23 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, //Event emit when the global treasury wallet address get changed event TreasuryWalletChanged(address _oldTreasuryWallet, address _newTreasuryWallet); event DisableController(); + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event TokenUpgraded(uint8 _major, uint8 _minor, uint8 _patch); + + /** + * @notice Initialization function + * @dev Expected to be called atomically with the proxy being created, by the owner of the token + * @dev Can only be called once + */ + function initialize(address _getterDelegate) external { + //Expected to be called atomically with the proxy being created + require(!initialized, "Already initialized"); + getterDelegate = _getterDelegate; + securityTokenVersion = SemanticVersion(3, 0, 0); + updateFromRegistry(); + tokenFactory = msg.sender; + initialized = true; + } function _isModule(address _module, uint8 _type) internal view returns(bool) { if (modulesToData[_module].module != _module || modulesToData[_module].isArchived) @@ -93,6 +111,22 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, require(_isTransfer, "Transfer Invalid"); } + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(isOwner()); + _; + } + + /** + * @dev Throws if called by any account other than the STFactory. + */ + modifier onlyTokenFactory() { + require(msg.sender == tokenFactory); + _; + } + // Require msg.sender to be the specified module type modifier onlyModule(uint8 _type) { require(_isModule(msg.sender, _type)); @@ -115,41 +149,6 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, _; } - /** - * @notice constructor - * @param _name Name of the SecurityToken - * @param _symbol Symbol of the Token - * @param _decimals Decimals for the securityToken - * @param _granularity granular level of the token - * @param _tokenDetails Details of the token that are stored off-chain - * @param _polymathRegistry Contract address of the polymath registry - * @param _delegate Contract address of the delegate - */ - constructor( - string memory _name, - string memory _symbol, - uint8 _decimals, - uint256 _granularity, - string memory _tokenDetails, - address _polymathRegistry, - address _delegate - ) - public - { - _zeroAddressCheck(_polymathRegistry); - _zeroAddressCheck(_delegate); - polymathRegistry = _polymathRegistry; - //When it is created, the owner is the STR - updateFromRegistry(); - name = _name; - symbol = _symbol; - decimals = _decimals; - delegate = _delegate; - tokenDetails = _tokenDetails; - granularity = _granularity; - securityTokenVersion = SemanticVersion(3, 0, 0); - } - /** * @notice Attachs a module to the SecurityToken * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it @@ -165,14 +164,15 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, bytes memory _data, uint256 _maxCost, uint256 _budget, - bytes32 _label + bytes32 _label, + bool _archived ) public onlyOwner nonReentrant { //Check that the module factory exists in the ModuleRegistry - will throw otherwise - IModuleRegistry(moduleRegistry).useModule(_moduleFactory); + IModuleRegistry(moduleRegistry).useModule(_moduleFactory, false); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); uint8[] memory moduleTypes = moduleFactory.types(); uint256 moduleCost = moduleFactory.setupCostInPoly(); @@ -184,35 +184,36 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, require(modulesToData[module].module == address(0), "Module exists"); //Approve ongoing budget ERC20(polyToken).approve(module, _budget); - //Add to SecurityToken module map - bytes32 moduleName = moduleFactory.name(); - uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); + _addModuleData(moduleTypes, _moduleFactory, module, moduleCost, _budget, _label, _archived); + } + + function _addModuleData(uint8[] memory _moduleTypes, address _moduleFactory, address _module, uint256 _moduleCost, uint256 _budget, bytes32 _label, bool _archived) internal { + bytes32 moduleName = IModuleFactory(_moduleFactory).name(); + uint256[] memory moduleIndexes = new uint256[](_moduleTypes.length); uint256 i; - for (i = 0; i < moduleTypes.length; i++) { - moduleIndexes[i] = modules[moduleTypes[i]].length; - modules[moduleTypes[i]].push(module); + for (i = 0; i < _moduleTypes.length; i++) { + moduleIndexes[i] = modules[_moduleTypes[i]].length; + modules[_moduleTypes[i]].push(_module); } - modulesToData[module] = ModuleData( + modulesToData[_module] = ModuleData( moduleName, - module, + _module, _moduleFactory, - false, - moduleTypes, + _archived, + _moduleTypes, moduleIndexes, names[moduleName].length, _label ); - names[moduleName].push(module); - //Emit log event - /*solium-disable-next-line security/no-block-members*/ - emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, _label); + names[moduleName].push(_module); + emit ModuleAdded(_moduleTypes, moduleName, _moduleFactory, _module, _moduleCost, _budget, _label, _archived); } /** * @notice addModule function will call addModuleWithLabel() with an empty label for backward compatible */ - function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget) external { - addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, ""); + function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget, bool _archived) external { + addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, "", _archived); } /** @@ -223,8 +224,20 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, TokenLib.archiveModule(modulesToData[_module]); } + /** + * @notice Upgrades a module attached to the SecurityToken + * @param _module address of module to archive + */ function upgradeModule(address _module) external onlyOwner { - TokenLib.upgradeModule(modulesToData[_module]); + TokenLib.upgradeModule(moduleRegistry, modulesToData[_module]); + } + + /** + * @notice Upgrades security token + */ + function upgradeToken() external onlyOwner { + IUpgradableTokenFactory(tokenFactory).upgradeToken(7); + emit TokenUpgraded(securityTokenVersion.major, securityTokenVersion.minor, securityTokenVersion.patch); } /** @@ -232,7 +245,7 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, * @param _module address of module to unarchive */ function unarchiveModule(address _module) external onlyOwner { - TokenLib.unarchiveModule(modulesToData[_module]); + TokenLib.unarchiveModule(moduleRegistry, modulesToData[_module]); } /** @@ -774,7 +787,7 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, } function _implementation() internal view returns(address) { - return delegate; + return getterDelegate; } function updateFromRegistry() public onlyOwner { @@ -782,4 +795,38 @@ contract SecurityToken is ERC20, Ownable, ReentrancyGuard, SecurityTokenStorage, securityTokenRegistry = PolymathRegistry(polymathRegistry).getAddress("SecurityTokenRegistry"); polyToken = PolymathRegistry(polymathRegistry).getAddress("PolyToken"); } + + //Ownable Functions + + /** + * @return the address of the owner. + */ + function owner() public view returns (address) { + return _owner; + } + + /** + * @return true if `msg.sender` is the owner of the contract. + */ + function isOwner() public view returns (bool) { + return msg.sender == _owner; + } + + /** + * @dev Allows the current owner to transfer control of the contract to a newOwner. + * @param newOwner The address to transfer ownership to. + */ + function transferOwnership(address newOwner) public onlyOwner { + _transferOwnership(newOwner); + } + + /** + * @dev Transfers control of the contract to a newOwner. + * @param newOwner The address to transfer ownership to. + */ + function _transferOwnership(address newOwner) internal { + require(newOwner != address(0)); + emit OwnershipTransferred(_owner, newOwner); + _owner = newOwner; + } } diff --git a/contracts/tokens/SecurityTokenProxy.sol b/contracts/tokens/SecurityTokenProxy.sol new file mode 100644 index 000000000..1f20040e4 --- /dev/null +++ b/contracts/tokens/SecurityTokenProxy.sol @@ -0,0 +1,42 @@ +pragma solidity ^0.5.0; + +import "../proxy/OwnedUpgradeabilityProxy.sol"; +import "./OZStorage.sol"; +import "./SecurityTokenStorage.sol"; + +/** + * @title USDTiered STO module Proxy + */ +contract SecurityTokenProxy is OZStorage, SecurityTokenStorage, OwnedUpgradeabilityProxy { + + /** + * @notice constructor + * @param _name Name of the SecurityToken + * @param _symbol Symbol of the Token + * @param _decimals Decimals for the securityToken + * @param _granularity granular level of the token + * @param _tokenDetails Details of the token that are stored off-chain + * @param _polymathRegistry Contract address of the polymath registry + */ + constructor( + string memory _name, + string memory _symbol, + uint8 _decimals, + uint256 _granularity, + string memory _tokenDetails, + address _polymathRegistry + ) + public + { + //Set storage variables - NB implementation not yet set + require(_polymathRegistry != address(0), "Invalid Address"); + name = _name; + symbol = _symbol; + decimals = _decimals; + polymathRegistry = _polymathRegistry; + tokenDetails = _tokenDetails; + granularity = _granularity; + _owner = msg.sender; + } + +} diff --git a/contracts/tokens/SecurityTokenStorage.sol b/contracts/tokens/SecurityTokenStorage.sol index 301b5285d..5f7b400d6 100644 --- a/contracts/tokens/SecurityTokenStorage.sol +++ b/contracts/tokens/SecurityTokenStorage.sol @@ -8,6 +8,8 @@ contract SecurityTokenStorage { uint8 constant CHECKPOINT_KEY = 4; uint8 constant BURN_KEY = 5; uint8 constant DATA_KEY = 6; + uint8 constant WALLET_KEY = 7; + bytes32 internal constant INVESTORSKEY = 0xdf3a8dd24acdd05addfc6aeffef7574d2de3f844535ec91e8e0f3e45dba96731; //keccak256(abi.encodePacked("INVESTORS")) bytes32 internal constant TREASURY = 0xaae8817359f3dcb67d050f44f3e49f982e0359d90ca4b5f18569926304aaece6; //keccak256(abi.encodePacked("TREASURY_WALLET")) @@ -46,6 +48,11 @@ contract SecurityTokenStorage { uint256 value; } + //Naming scheme to match Ownable + address public _owner; + address public tokenFactory; + bool public initialized; + // ERC20 Details string public name; string public symbol; @@ -59,7 +66,7 @@ contract SecurityTokenStorage { address public moduleRegistry; address public securityTokenRegistry; address public polyToken; - address public delegate; + address public getterDelegate; // Address of the data store used to store shared data address public dataStore; diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index a0f718c20..a7821aa43 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -27,9 +27,11 @@ const DevPolyToken = artifacts.require("./helpers/PolyTokenFaucet.sol"); const MockOracle = artifacts.require("./MockOracle.sol"); const StableOracle = artifacts.require("./StableOracle.sol"); const TokenLib = artifacts.require("./TokenLib.sol"); -const SecurityToken = artifacts.require("./tokens/SecurityToken.sol"); +const SecurityTokenLogic = artifacts.require("./tokens/SecurityToken.sol"); +const MockSecurityTokenLogic = artifacts.require("./tokens/MockSecurityTokenLogic.sol"); const STRGetter = artifacts.require('./STRGetter.sol'); const STGetter = artifacts.require('./STGetter.sol'); +const MockSTGetter = artifacts.require('./MockSTGetter.sol'); const DataStoreLogic = artifacts.require('./DataStore.sol'); const DataStoreFactory = artifacts.require('./DataStoreFactory.sol'); const VolumeRestrictionTMFactory = artifacts.require('./VolumeRestrictionTMFactory.sol') @@ -147,17 +149,24 @@ module.exports = function(deployer, network, accounts) { }); } - const functionSignatureProxy = { + const tokenInitBytes = { name: "initialize", type: "function", inputs: [ { type: "address", - name: "_polymathRegistry" - }, + name: "_getterDelegate" + } + ] + }; + + const functionSignatureProxy = { + name: "initialize", + type: "function", + inputs: [ { type: "address", - name: "_STFactory" + name: "_polymathRegistry" }, { type: "uint256", @@ -214,9 +223,11 @@ module.exports = function(deployer, network, accounts) { .then(() => { // Link libraries deployer.link(VolumeRestrictionLib, VolumeRestrictionTMLogic); - deployer.link(TokenLib, SecurityToken); + deployer.link(TokenLib, SecurityTokenLogic); + deployer.link(TokenLib, MockSecurityTokenLogic); deployer.link(TokenLib, STFactory); deployer.link(TokenLib, STGetter); + deployer.link(TokenLib, MockSTGetter); // A) Deploy the ModuleRegistry Contract (It contains the list of verified ModuleFactory) return deployer.deploy(ModuleRegistry, { from: PolymathAccount }); }) @@ -292,6 +303,10 @@ module.exports = function(deployer, network, accounts) { // B) Deploy the DataStoreLogic Contract return deployer.deploy(DataStoreLogic, { from: PolymathAccount }); }) + .then(() => { + // B) Deploy the SecurityTokenLogic Contract + return deployer.deploy(SecurityTokenLogic, "", "", 0, { from: PolymathAccount }); + }) .then(() => { // B) Deploy the DataStoreFactory Contract return deployer.deploy(DataStoreFactory, DataStoreLogic.address, { from: PolymathAccount }); @@ -356,7 +371,8 @@ module.exports = function(deployer, network, accounts) { }) .then(() => { // H) Deploy the STVersionProxy001 Contract which contains the logic of deployment of securityToken. - return deployer.deploy(STFactory, GeneralTransferManagerFactory.address, DataStoreFactory.address, STGetter.address, { from: PolymathAccount }); + let tokenInitBytesCall = web3.eth.abi.encodeFunctionCall(tokenInitBytes, [STGetter.address]); + return deployer.deploy(STFactory, polymathRegistry.address, GeneralTransferManagerFactory.address, DataStoreFactory.address, "3.0.0", SecurityTokenLogic.address, tokenInitBytesCall, { from: PolymathAccount }); }) .then(() => { // K) Deploy the FeatureRegistry contract to control feature switches @@ -382,7 +398,6 @@ module.exports = function(deployer, network, accounts) { .then((securityTokenRegistryProxy) => { let bytesProxy = web3.eth.abi.encodeFunctionCall(functionSignatureProxy, [ PolymathRegistry.address, - STFactory.address, initRegFee, initRegFee, PolymathAccount, @@ -392,6 +407,18 @@ module.exports = function(deployer, network, accounts) { from: PolymathAccount }); }) + .then(() => { + return SecurityTokenRegistry.at(SecurityTokenRegistryProxy.address); + }) + .then((securityTokenRegistry) => { + return securityTokenRegistry.setProtocolFactory(STFactory.address, 3, 0, 0); + }) + .then(() => { + return SecurityTokenRegistry.at(SecurityTokenRegistryProxy.address); + }) + .then((securityTokenRegistry) => { + return securityTokenRegistry.setLatestVersion(3, 0, 0); + }) .then(() => { // Assign the address into the SecurityTokenRegistry key return polymathRegistry.changeAddress("SecurityTokenRegistry", SecurityTokenRegistryProxy.address, { from: PolymathAccount }); @@ -444,49 +471,49 @@ module.exports = function(deployer, network, accounts) { // F) Once the GeneralTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(GeneralTransferManagerFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(GeneralTransferManagerFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the CountTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(CountTransferManagerFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(CountTransferManagerFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the PercentageTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(PercentageTransferManagerFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(PercentageTransferManagerFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the GeneralPermissionManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(GeneralPermissionManagerFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(GeneralPermissionManagerFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the EtherDividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(EtherDividendCheckpointFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(EtherDividendCheckpointFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the ERC20DividendCheckpointFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(ERC20DividendCheckpointFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(ERC20DividendCheckpointFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the VolumeRestrictionTMFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(VolumeRestrictionTMFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(VolumeRestrictionTMFactory.address, { from: PolymathAccount }); }) .then(() => { // G) Once the ManualApprovalTransferManagerFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(ManualApprovalTransferManagerFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(ManualApprovalTransferManagerFactory.address, { from: PolymathAccount }); }) .then(() => { // M) Deploy the CappedSTOFactory (Use to generate the CappedSTO contract which will used to collect the funds ). @@ -501,7 +528,7 @@ module.exports = function(deployer, network, accounts) { // G) Once the CappedSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(CappedSTOFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(CappedSTOFactory.address, { from: PolymathAccount }); }) .then(() => { // H) Deploy the USDTieredSTOFactory (Use to generate the USDTieredSTOFactory contract which will used to collect the funds ). @@ -516,7 +543,7 @@ module.exports = function(deployer, network, accounts) { // J) Once the USDTieredSTOFactory registered with the ModuleRegistry contract then for making them accessble to the securityToken // contract, Factory should comes under the verified list of factories or those factories deployed by the securityToken issuers only. // Here it gets verified because it is deployed by the third party account (Polymath Account) not with the issuer accounts. - return moduleRegistry.verifyModule(USDTieredSTOFactory.address, true, { from: PolymathAccount }); + return moduleRegistry.verifyModule(USDTieredSTOFactory.address, { from: PolymathAccount }); }) .then(() => { return polymathRegistry.changeAddress("PolyUsdOracle", POLYOracle, { from: PolymathAccount }); @@ -525,7 +552,7 @@ module.exports = function(deployer, network, accounts) { return polymathRegistry.changeAddress("EthUsdOracle", ETHOracle, { from: PolymathAccount }); }) .then(() => { - return deployer.deploy(SecurityToken, "a", "a", 18, 1, "a", polymathRegistry.address, STGetter.address, { from: PolymathAccount }); + // return deployer.deploy(SecurityToken, "a", "a", 18, 1, "a", polymathRegistry.address, STGetter.address, { from: PolymathAccount }); return polymathRegistry.changeAddress("StablePolyUsdOracle", StablePOLYOracle, { from: PolymathAccount }); }) .then(() => { diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index 5238e436c..061c002c8 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -6,6 +6,7 @@ import { setUpPolymathNetwork, deployGPMAndVerifyed, deployCappedSTOAndVerifyed, import { catchRevert } from "./helpers/exceptions"; const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); +const STFactory = artifacts.require("./STFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); const DummySTO = artifacts.require("./DummySTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); @@ -137,7 +138,7 @@ contract("CappedSTO", async (accounts) => { I_STFactory, I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, - I_STRProxied, + I_STRProxied, I_STRGetter, I_STGetter ] = instances; @@ -177,13 +178,17 @@ contract("CappedSTO", async (accounts) => { it("Should generate the new security token with the same symbol as registered above", async () => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: token_owner }); + let t = await I_STRGetter.getSTFactoryAddress.call(); + console.log(t); + let foo = await STFactory.at(t); + console.log(await foo.polymathRegistry.call()); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, treasury_wallet, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken_ETH = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken_ETH = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter_eth = await STGetter.at(I_SecurityToken_ETH.address); assert.equal(await stGetter_eth.getTreasuryWallet.call(), treasury_wallet, "Incorrect wallet set") const log = (await I_SecurityToken_ETH.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -208,7 +213,7 @@ contract("CappedSTO", async (accounts) => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, new BN(0), [E_fundRaiseType], account_fundsReceiver]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due to rate is 0", async () => { @@ -218,7 +223,7 @@ contract("CappedSTO", async (accounts) => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, new BN(0), [E_fundRaiseType], account_fundsReceiver]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due funds reciever account 0x", async () => { @@ -227,7 +232,7 @@ contract("CappedSTO", async (accounts) => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], address_zero]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due to raise type of 0 length", async () => { @@ -236,7 +241,7 @@ contract("CappedSTO", async (accounts) => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [], account_fundsReceiver]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due to startTime > endTime", async () => { @@ -249,7 +254,7 @@ contract("CappedSTO", async (accounts) => { account_fundsReceiver ]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due to cap is of 0 securityToken", async () => { @@ -257,14 +262,14 @@ contract("CappedSTO", async (accounts) => { let endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, new BN(0), rate, [E_fundRaiseType], account_fundsReceiver]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to launch the STO due to different value incompare to getInitFunction", async () => { let startTime = await latestTime() + duration.days(1); let endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(["uint256", "uint256", "uint256"], [startTime, endTime, 0]); - await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should successfully attach the STO module to the security token", async () => { @@ -278,7 +283,7 @@ contract("CappedSTO", async (accounts) => { [E_fundRaiseType], account_fundsReceiver ]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); @@ -517,7 +522,7 @@ contract("CappedSTO", async (accounts) => { [E_fundRaiseType], account_fundsReceiver ]); - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); @@ -591,7 +596,7 @@ contract("CappedSTO", async (accounts) => { let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, [E_fundRaiseType], account_fundsReceiver]); for (var STOIndex = 2; STOIndex < MAX_MODULES; STOIndex++) { - const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_ETH.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", `Wrong STO module added at index ${STOIndex}`); I_CappedSTO_Array_ETH.push(await CappedSTO.at(tx.logs[3].args._module)); @@ -638,12 +643,12 @@ contract("CappedSTO", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(P_name, P_symbol, P_tokenDetails, false, treasury_wallet, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, P_symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken_POLY = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken_POLY = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter_poly = await STGetter.at(I_SecurityToken_POLY.address); assert.equal(await stGetter_poly.getTreasuryWallet.call(), treasury_wallet, "Incorrect wallet set") - + const log = (await I_SecurityToken_POLY.getPastEvents('ModuleAdded', {filter: {from: blockNo}}))[0]; // Verify that GeneralTransferManager module get added successfully or not @@ -672,7 +677,7 @@ contract("CappedSTO", async (accounts) => { account_fundsReceiver ]); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); @@ -866,7 +871,7 @@ contract("CappedSTO", async (accounts) => { let endTime = startTime + duration.days(30); const cap = web3.utils.toWei("10000"); const dummyBytesSig = encodeModuleCall(DummySTOParameters, [startTime, endTime, cap, "Hello"]); - const tx = await I_SecurityToken_ETH.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_ETH.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, new BN(0), false, { from: token_owner }); console.log(tx.logs[2]); assert.equal(tx.logs[2].args._types[0], stoKey, `Wrong module type added`); assert.equal( @@ -1019,7 +1024,7 @@ contract("CappedSTO", async (accounts) => { account_fundsReceiver ]); - const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken_POLY.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index effc23f5f..bcb7f88d7 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -129,9 +129,9 @@ contract("Checkpoints", async function(accounts) { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index ff26fe864..f293668d7 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -145,9 +145,9 @@ contract("CountTransferManager", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -165,7 +165,7 @@ contract("CountTransferManager", async (accounts) => { it("Should successfully attach the CountTransferManager factory with the security token", async () => { await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await catchRevert( - I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_CountTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -179,6 +179,7 @@ contract("CountTransferManager", async (accounts) => { bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "CountTransferManagerFactory doesn't get deployed"); @@ -192,7 +193,7 @@ contract("CountTransferManager", async (accounts) => { }); it("Should successfully attach the CountTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -366,7 +367,7 @@ contract("CountTransferManager", async (accounts) => { let tx2 = await I_STRProxied.generateSecurityToken(name, symbol2, tokenDetails, false, token_owner, 0, { from: token_owner }); - I_SecurityToken2 = await SecurityToken.at(tx2.logs[2].args._securityTokenAddress); + I_SecurityToken2 = await SecurityToken.at(tx2.logs[1].args._securityTokenAddress); stGetter2 = await STGetter.at(I_SecurityToken2.address); let moduleData = (await stGetter2.getModulesByType(2))[0]; I_GeneralTransferManager2 = await GeneralTransferManager.at(moduleData); @@ -435,14 +436,14 @@ contract("CountTransferManager", async (accounts) => { it("Should successfully attach the CountTransferManager factory with the security token", async () => { await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await catchRevert( - I_SecurityToken2.addModule(P_CountTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken2.addModule(P_CountTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); }); it("Should successfully attach the CountTransferManager with the security token and set max holder to 2", async () => { - const tx = await I_SecurityToken2.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken2.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -474,6 +475,11 @@ contract("CountTransferManager", async (accounts) => { I_CountTransferManagerFactory.setLogicContract("4.0.0", "0x0000000000000000000000000000000000000000", bytesCM, { from: token_owner }) ); await I_CountTransferManagerFactory.setLogicContract("4.0.0", I_MockCountTransferManagerLogic.address, bytesCM, { from: account_polymath }); + await catchRevert( + // Fails as upgraded module has been unverified + I_SecurityToken2.upgradeModule(I_CountTransferManager2.address, { from: token_owner }) + ); + let tx = await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, { from: account_polymath }); await I_SecurityToken2.upgradeModule(I_CountTransferManager2.address, { from: token_owner }); let I_MockCountTransferManager = await MockCountTransferManager.at(I_CountTransferManager2.address); await I_MockCountTransferManager.newFunction(); @@ -497,6 +503,7 @@ contract("CountTransferManager", async (accounts) => { ); I_MockCountTransferManagerLogic = await MockCountTransferManager.new("0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000", { from: account_polymath }); await I_CountTransferManagerFactory.setLogicContract("6.0.0", I_MockCountTransferManagerLogic.address, bytesCM, { from: account_polymath }); + await I_MRProxied.verifyModule(I_CountTransferManagerFactory.address, { from: account_polymath }); await I_SecurityToken2.upgradeModule(I_CountTransferManager2.address, { from: token_owner }); await I_SecurityToken2.upgradeModule(I_CountTransferManager2.address, { from: token_owner }); }); @@ -589,8 +596,8 @@ contract("CountTransferManager", async (accounts) => { it("Should successfully change the version bound", async () => { await I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1, 2, 1], { from: account_polymath }); - await I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1, 4, 9], { from: account_polymath }); - await catchRevert(I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1, new BN(0), 0], { from: account_polymath })); + await I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1, 0, 9], { from: account_polymath }); + await catchRevert(I_CountTransferManagerFactory.changeSTVersionBounds("lowerBound", [1, 1, 0], { from: account_polymath })); }); }); }); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index eea6f61e5..0a360000c 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -154,9 +154,9 @@ contract("ERC20DividendCheckpoint", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set") @@ -174,7 +174,7 @@ contract("ERC20DividendCheckpoint", async (accounts) => { it("Should successfully attach the ERC20DividendCheckpoint with the security token - fail insufficient payment", async () => { let bytesDividend = encodeModuleCall(DividendParameters, [wallet]); await catchRevert( - I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -185,7 +185,7 @@ contract("ERC20DividendCheckpoint", async (accounts) => { await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await I_PolyToken.transfer(I_SecurityToken.address, new BN(web3.utils.toWei("2000", "ether")), { from: token_owner }); let bytesDividend = encodeModuleCall(DividendParameters, [wallet]); - const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + const tx = await I_SecurityToken.addModule(P_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); @@ -200,7 +200,7 @@ contract("ERC20DividendCheckpoint", async (accounts) => { it("Should successfully attach the ERC20DividendCheckpoint with the security token", async () => { let bytesDividend = encodeModuleCall(DividendParameters, [address_zero]); - const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_ERC20DividendCheckpointFactory.address, bytesDividend, new BN(0), new BN(0), false, { from: token_owner }); console.log(tx.logs[2].args); assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "ERC20DividendCheckpoint doesn't get deployed"); assert.equal( @@ -1014,7 +1014,7 @@ contract("ERC20DividendCheckpoint", async (accounts) => { it("should register a delegate", async () => { [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, 0); - let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 53c993da4..ea5ffb0e8 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -147,12 +147,12 @@ contract("EtherDividendCheckpoint", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, wallet, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), wallet, "Incorrect wallet set") - + const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; // Verify that GeneralTransferManager module get added successfully or not @@ -169,7 +169,7 @@ contract("EtherDividendCheckpoint", async (accounts) => { await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); let bytesDividend = encodeModuleCall(DividendParameters, [wallet]); await catchRevert( - I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -179,7 +179,7 @@ contract("EtherDividendCheckpoint", async (accounts) => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, new BN(web3.utils.toWei("2000", "ether")), { from: token_owner }); let bytesDividend = encodeModuleCall(DividendParameters, [wallet]); - const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + const tx = await I_SecurityToken.addModule(P_EtherDividendCheckpointFactory.address, bytesDividend, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); @@ -194,7 +194,7 @@ contract("EtherDividendCheckpoint", async (accounts) => { it("Should successfully attach the EtherDividendCheckpoint with the security token", async () => { let bytesDividend = encodeModuleCall(DividendParameters, [address_zero]); - const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, bytesDividend, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_EtherDividendCheckpointFactory.address, bytesDividend, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), checkpointKey, "EtherDividendCheckpoint doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -809,7 +809,7 @@ contract("EtherDividendCheckpoint", async (accounts) => { it("should registr a delegate", async () => { [I_GeneralPermissionManagerFactory] = await deployGPMAndVerifyed(account_polymath, I_MRProxied, 0); - let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index a612386df..db3bec583 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -145,9 +145,9 @@ contract("GeneralPermissionManager", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -165,7 +165,7 @@ contract("GeneralPermissionManager", async (accounts) => { let errorThrown = false; await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -179,6 +179,7 @@ contract("GeneralPermissionManager", async (accounts) => { "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); @@ -192,7 +193,7 @@ contract("GeneralPermissionManager", async (accounts) => { }); it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -332,11 +333,11 @@ contract("GeneralPermissionManager", async (accounts) => { let tx2 = await I_STRProxied.generateSecurityToken(name, "DEL", tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx2.logs[2].args._ticker, "DEL", "SecurityToken doesn't get deployed"); + assert.equal(tx2.logs[1].args._ticker, "DEL", "SecurityToken doesn't get deployed"); - let I_SecurityToken_DEL = await SecurityToken.at(tx2.logs[2].args._securityTokenAddress); + let I_SecurityToken_DEL = await SecurityToken.at(tx2.logs[1].args._securityTokenAddress); - const tx = await I_SecurityToken_DEL.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, { from: token_owner }); + const tx = await I_SecurityToken_DEL.addModule(I_GeneralPermissionManagerFactory.address, "0x", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 34b28baae..b12a1d5a4 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -175,9 +175,9 @@ contract("GeneralTransferManager", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -193,14 +193,14 @@ contract("GeneralTransferManager", async (accounts) => { it("Should attach the paid GTM -- failed because of no tokens", async () => { await catchRevert( - I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), { from: account_issuer }) + I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), false, { from: account_issuer }) ); }); it("Should attach the paid GTM", async () => { let snap_id = await takeSnapshot(); await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000")), I_SecurityToken.address); - await I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), { + await I_SecurityToken.addModule(P_GeneralTransferManagerFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), false, { from: account_issuer }); await revertToSnapshot(snap_id); @@ -308,7 +308,7 @@ contract("GeneralTransferManager", async (accounts) => { someString ]); await catchRevert( - I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), { from: token_owner }) + I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), false, { from: token_owner }) ); }); @@ -321,7 +321,7 @@ contract("GeneralTransferManager", async (accounts) => { someString ]); await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000")), I_SecurityToken.address); - const tx = await I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), { + const tx = await I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toNumber(), stoKey, "DummySTO doesn't get deployed"); @@ -336,7 +336,7 @@ contract("GeneralTransferManager", async (accounts) => { it("Should successfully attach the STO factory with the security token - invalid data", async () => { let bytesSTO = encodeModuleCall(["uint256", "string"], [await latestTime() + duration.seconds(1000), someString]); - await catchRevert(I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken.addModule(P_DummySTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner })); }); it("Should successfully attach the STO factory with the security token", async () => { @@ -346,7 +346,7 @@ contract("GeneralTransferManager", async (accounts) => { cap, someString ]); - const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_DummySTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), stoKey, "DummySTO doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -357,7 +357,7 @@ contract("GeneralTransferManager", async (accounts) => { }); it("Should successfully attach the permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -388,7 +388,7 @@ contract("GeneralTransferManager", async (accounts) => { it("should not allow unauthorized people to change transfer requirements", async () => { await catchRevert( I_GeneralTransferManager.modifyTransferRequirementsMulti( - [0, 1, 2], + [0, 1, 2], [true, false, true], [true, true, false], [false, false, false], @@ -754,7 +754,7 @@ contract("GeneralTransferManager", async (accounts) => { assert.equal(new BN(kycData[2][1]).toNumber(), 1, "KYC data not modified correctly"); let nonce = 5; - + let newExpiryTime = new BN(expiryTime).add(new BN(duration.days(200))); const sig = getMultiSignGTMData( I_GeneralTransferManager.address, @@ -769,8 +769,8 @@ contract("GeneralTransferManager", async (accounts) => { ); await increaseTime(10000); - - + + await catchRevert( I_GeneralTransferManager.modifyKYCDataSignedMulti( [account_investor1, account_investor2], @@ -787,7 +787,7 @@ contract("GeneralTransferManager", async (accounts) => { } ) ); - + kycData = await I_GeneralTransferManager.getKYCData([account_investor1, account_investor2]); assert.equal(new BN(kycData[2][0]).toNumber(), 1, "KYC data modified incorrectly"); @@ -798,7 +798,7 @@ contract("GeneralTransferManager", async (accounts) => { let validFrom = await latestTime(); let validTo = await latestTime() + duration.days(5); let nonce = 5; - + let newExpiryTime = new BN(expiryTime).add(new BN(duration.days(200))); const sig = getMultiSignGTMData( I_GeneralTransferManager.address, @@ -813,8 +813,8 @@ contract("GeneralTransferManager", async (accounts) => { ); await increaseTime(10000); - - + + await catchRevert( I_GeneralTransferManager.modifyKYCDataSignedMulti( [account_investor1, account_investor2], @@ -831,7 +831,7 @@ contract("GeneralTransferManager", async (accounts) => { } ) ); - + let kycData = await I_GeneralTransferManager.getKYCData([account_investor1, account_investor2]); assert.equal(new BN(kycData[2][0]).toNumber(), 1, "KYC data modified incorrectly"); @@ -842,7 +842,7 @@ contract("GeneralTransferManager", async (accounts) => { let validFrom = await latestTime(); let validTo = await latestTime() + duration.days(5); let nonce = 5; - + let newExpiryTime = new BN(expiryTime).add(new BN(duration.days(200))); const sig = getMultiSignGTMData( I_GeneralTransferManager.address, @@ -857,8 +857,7 @@ contract("GeneralTransferManager", async (accounts) => { ); await increaseTime(10000); - - + await I_GeneralTransferManager.modifyKYCDataSignedMulti( [account_investor1, account_investor2], [fromTime, fromTime], @@ -873,7 +872,7 @@ contract("GeneralTransferManager", async (accounts) => { gas: 6000000 } ); - + let kycData = await I_GeneralTransferManager.getKYCData([account_investor1, account_investor2]); assert.equal(new BN(kycData[2][0]).toString(), newExpiryTime.toString(), "KYC data not modified correctly"); @@ -1051,7 +1050,7 @@ contract("GeneralTransferManager", async (accounts) => { it("should failed in trasfering the tokens", async () => { await I_GeneralTransferManager.modifyTransferRequirementsMulti( - [0, 1, 2], + [0, 1, 2], [true, false, true], [true, true, false], [false, false, false], diff --git a/test/helpers/createInstances.js b/test/helpers/createInstances.js index 7d1e32474..6bf6de1a0 100644 --- a/test/helpers/createInstances.js +++ b/test/helpers/createInstances.js @@ -10,6 +10,7 @@ const CappedSTO = artifacts.require("./CappedSTO.sol"); const SecurityTokenRegistryProxy = artifacts.require("./SecurityTokenRegistryProxy.sol"); const SecurityTokenRegistry = artifacts.require("./SecurityTokenRegistry.sol"); const SecurityTokenRegistryMock = artifacts.require("./SecurityTokenRegistryMock.sol"); +const SecurityTokenLogic = artifacts.require("./SecurityToken.sol"); const ERC20DividendCheckpoint = artifacts.require("./ERC20DividendCheckpoint.sol"); const EtherDividendCheckpoint = artifacts.require("./EtherDividendCheckpoint.sol"); const ERC20DividendCheckpointFactory = artifacts.require("./ERC20DividendCheckpointFactory.sol"); @@ -111,7 +112,7 @@ let I_StablePOLYOracle; // Initial fee for ticker registry and security token registry const initRegFee = new BN(web3.utils.toWei("250")); -const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; +const STRProxyParameters = ["address", "uint256", "uint256", "address", "address"]; const MRProxyParameters = ["address", "address"]; /// Function use to launch the polymath ecossystem. @@ -237,9 +238,22 @@ async function deployGTM(account_polymath) { async function deploySTFactory(account_polymath) { I_STGetter = await STGetter.new({from: account_polymath}); + I_SecurityToken = await SecurityTokenLogic.new("", "", 0, {from: account_polymath}); + console.log("STL - " + I_SecurityToken.address); let I_DataStoreLogic = await DataStoreLogic.new({ from: account_polymath }); let I_DataStoreFactory = await DataStoreFactory.new(I_DataStoreLogic.address, { from: account_polymath }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, I_DataStoreFactory.address, I_STGetter.address, { from: account_polymath }); + const tokenInitBytes = { + name: "initialize", + type: "function", + inputs: [ + { + type: "address", + name: "_getterDelegate" + } + ] + }; + let tokenInitBytesCall = web3.eth.abi.encodeFunctionCall(tokenInitBytes, [I_STGetter.address]); + I_STFactory = await STFactory.new(I_PolymathRegistry.address, I_GeneralTransferManagerFactory.address, I_DataStoreFactory.address, "3.0.0", I_SecurityToken.address, tokenInitBytesCall, { from: account_polymath }); assert.notEqual(I_STFactory.address.valueOf(), "0x0000000000000000000000000000000000000000", "STFactory contract was not deployed"); @@ -261,7 +275,6 @@ async function deploySTR(account_polymath) { let bytesProxy = encodeProxyCall(STRProxyParameters, [ I_PolymathRegistry.address, - I_STFactory.address, initRegFee, initRegFee, account_polymath, @@ -269,6 +282,8 @@ async function deploySTR(account_polymath) { ]); await I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath }); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + await I_STRProxied.setProtocolFactory(I_STFactory.address, 3, 0, 0); + await I_STRProxied.setLatestVersion(3, 0, 0); I_STRGetter = await STRGetter.at(I_SecurityTokenRegistryProxy.address); return new Array(I_SecurityTokenRegistry, I_SecurityTokenRegistryProxy, I_STRProxied, I_STRGetter); } @@ -283,12 +298,12 @@ async function setInPolymathRegistry(account_polymath) { async function registerGTM(account_polymath) { await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); } async function registerAndVerifyByMR(factoryAdrress, owner, mr) { await mr.registerModule(factoryAdrress, { from: owner }); - await mr.verifyModule(factoryAdrress, true, { from: owner }); + await mr.verifyModule(factoryAdrress, { from: owner }); } /// Deploy the TransferManagers diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 703b6889b..262805de2 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -158,12 +158,12 @@ contract("Issuance", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, account_polymath, 0, { from: account_polymath }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), account_polymath, "Incorrect wallet set") - + const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; // Verify that GeneralTransferManager module get added successfully or not @@ -193,7 +193,7 @@ contract("Issuance", async (accounts) => { await I_PolyToken.getTokens(cappedSTOSetupCostPOLY, account_polymath); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCostPOLY, { from: account_polymath }); - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: account_polymath }); + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: account_polymath }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( @@ -225,7 +225,7 @@ contract("Issuance", async (accounts) => { it("Should add the delegate with permission", async () => { //First attach a permission manager to the token - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: account_polymath }); + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: account_polymath }); let moduleData = (await stGetter.getModulesByType(permissionManagerKey))[0]; I_GeneralPermissionManager = await GeneralPermissionManager.at(moduleData); // Add permission to the deletgate (A regesteration process) diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 6d3b07b8b..285951f1e 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -155,9 +155,9 @@ contract("ManualApprovalTransferManager", accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -232,7 +232,7 @@ contract("ManualApprovalTransferManager", accounts => { it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { await I_PolyToken.getTokens(web3.utils.toWei("2000", "ether"), token_owner); await catchRevert( - I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x0", web3.utils.toWei("2000", "ether"), 0, { + I_SecurityToken.addModule(P_ManualApprovalTransferManagerFactory.address, "0x0", web3.utils.toWei("2000", "ether"), 0, false, { from: token_owner }) ); @@ -246,6 +246,7 @@ contract("ManualApprovalTransferManager", accounts => { "0x0", web3.utils.toWei("2000", "ether"), 0, + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toString(), transferManagerKey, "Manual Approval Transfer Manager doesn't get deployed"); @@ -259,7 +260,7 @@ contract("ManualApprovalTransferManager", accounts => { }); it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "0x0", 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "0x0", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); assert.equal( web3.utils.toUtf8(tx.logs[2].args._name), @@ -783,7 +784,7 @@ contract("ManualApprovalTransferManager", accounts => { [1] ); - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesCountTM, 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), transferManagerKey, "CountTransferManager doesn't get deployed"); let name = web3.utils.toUtf8(tx.logs[2].args._name); assert.equal(name, "CountTransferManager", "CountTransferManager module was not added"); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index 70ce851a7..ab6d280d9 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -7,6 +7,7 @@ import {deployCappedSTOAndVerifyed, setUpPolymathNetwork} from "./helpers/create const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); +const DummySTO = artifacts.require("./DummySTO.sol"); const DummySTOFactory = artifacts.require("./DummySTOFactory.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); const ModuleRegistryProxy = artifacts.require("./ModuleRegistryProxy.sol"); @@ -248,8 +249,8 @@ contract("ModuleRegistry", async (accounts) => { assert.equal(_list.length, 1, "Length should be 1"); assert.equal(_list[0], I_GeneralTransferManagerFactory.address); - let _reputation = await I_MRProxied.getReputationByFactory(I_GeneralTransferManagerFactory.address); - assert.equal(_reputation.length, 0); + let _reputation = await I_MRProxied.getFactoryDetails(I_GeneralTransferManagerFactory.address); + assert.equal(_reputation[1].length, 0); }); it("Should fail the register the module -- Already registered module", async () => { @@ -276,25 +277,27 @@ contract("ModuleRegistry", async (accounts) => { describe("Test case for verifyModule", async () => { it("Should fail in calling the verify module. Because msg.sender should be account_polymath", async () => { - await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_temp })); + await catchRevert(I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, { from: account_temp })); }); it("Should successfully verify the module -- true", async () => { - let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + let tx = await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); assert.equal(tx.logs[0].args._moduleFactory, I_GeneralTransferManagerFactory.address, "Failed in verifying the module"); - assert.equal(tx.logs[0].args._verified, true, "Failed in verifying the module"); + let info = await I_MRProxied.getFactoryDetails.call(I_GeneralTransferManagerFactory.address); + assert.equal(info[0], true); }); it("Should successfully verify the module -- false", async () => { I_CappedSTOFactory1 = await CappedSTOFactory.new(new BN(0), new BN(0), I_CappedSTOLogic.address, I_PolymathRegistry.address, true, { from: account_polymath }); await I_MRProxied.registerModule(I_CappedSTOFactory1.address, { from: account_polymath }); - let tx = await I_MRProxied.verifyModule(I_CappedSTOFactory1.address, false, { from: account_polymath }); + let tx = await I_MRProxied.unverifyModule(I_CappedSTOFactory1.address, { from: account_polymath }); assert.equal(tx.logs[0].args._moduleFactory, I_CappedSTOFactory1.address, "Failed in verifying the module"); - assert.equal(tx.logs[0].args._verified, false, "Failed in verifying the module"); + let info = await I_MRProxied.getFactoryDetails.call(I_CappedSTOFactory1.address); + assert.equal(info[0], false); }); it("Should fail in verifying the module. Because the module is not registered", async () => { - await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, true, { from: account_polymath })); + await catchRevert(I_MRProxied.verifyModule(I_MockFactory.address, { from: account_polymath })); }); }); @@ -304,8 +307,8 @@ contract("ModuleRegistry", async (accounts) => { await I_PolyToken.approve(I_STRProxied.address, new BN(web3.utils.toWei("2000")), { from: account_issuer }); await I_STRProxied.registerTicker(account_issuer, symbol, name, { from: account_issuer }); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, account_issuer, 0, { from: account_issuer }); - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase()); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase()); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), account_issuer, "Incorrect wallet set") }); @@ -315,7 +318,7 @@ contract("ModuleRegistry", async (accounts) => { endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, new BN(0), new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory1.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner })); }); it("Should fail to register module because custom modules not allowed", async () => { @@ -345,7 +348,7 @@ contract("ModuleRegistry", async (accounts) => { endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); let tx = await I_MRProxied.registerModule(I_CappedSTOFactory2.address, { from: token_owner }); - tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + tx = await I_SecurityToken.addModule(I_CappedSTOFactory2.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal( @@ -353,8 +356,8 @@ contract("ModuleRegistry", async (accounts) => { "CappedSTO", "CappedSTOFactory module was not added" ); - let _reputation = await I_MRProxied.getReputationByFactory.call(I_CappedSTOFactory2.address); - assert.equal(_reputation.length, 1); + let _reputation = await I_MRProxied.getFactoryDetails.call(I_CappedSTOFactory2.address); + assert.equal(_reputation[1].length, 1); }); it("Should successfully add module when custom modules switched on -- fail because factory owner is different", async () => { @@ -362,7 +365,7 @@ contract("ModuleRegistry", async (accounts) => { startTime = await latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory3.address, bytesSTO, new BN(0), new BN(0), { from: token_owner })); + catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory3.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner })); }); it("Should successfully add verified module", async () => { @@ -371,27 +374,29 @@ contract("ModuleRegistry", async (accounts) => { from: account_polymath }); await I_MRProxied.registerModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, true, { from: account_polymath }); - let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerFactory.address, { from: account_polymath }); + let tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], permissionManagerKey, "module doesn't get deployed"); }); it("Should failed in adding the TestSTOFactory module because not compatible with the current protocol version --lower", async () => { - I_TestSTOFactory = await TestSTOFactory.new(new BN(0), new BN(0), one_address, I_PolymathRegistry.address, true, { from: account_polymath }); + let I_TestSTOFactoryLogic = await DummySTO.new(address_zero, address_zero); + I_TestSTOFactory = await TestSTOFactory.new(new BN(0), new BN(0), I_TestSTOFactoryLogic.address, I_PolymathRegistry.address, true, { from: account_polymath }); await I_MRProxied.registerModule(I_TestSTOFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_TestSTOFactory.address, true, { from: account_polymath }); + await I_MRProxied.verifyModule(I_TestSTOFactory.address, { from: account_polymath }); // Taking the snapshot the revert the changes from here let id = await takeSnapshot(); - await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [2, 1, 0], { from: account_polymath }); + await I_TestSTOFactory.changeSTVersionBounds("lowerBound", [3, 1, 0], { from: account_polymath }); let _lstVersion = await I_TestSTOFactory.lowerSTVersionBounds.call(); - assert.equal(_lstVersion[2], 0); + assert.equal(_lstVersion[0], 3); assert.equal(_lstVersion[1], 1); + assert.equal(_lstVersion[2], 0); let bytesData = encodeModuleCall( ["uint256", "uint256", "uint256", "string"], [await latestTime(), currentTime.add(new BN(duration.days(1))), cap, "Test STO"] ); - - await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, new BN(0), new BN(0), { from: token_owner })); + console.log("I_TestSTOFactory:" +I_TestSTOFactory.address); + await catchRevert(I_SecurityToken.addModule(I_TestSTOFactory.address, bytesData, new BN(0), new BN(0), false, { from: token_owner })); await revertToSnapshot(id); }); @@ -400,16 +405,16 @@ contract("ModuleRegistry", async (accounts) => { let _ustVersion = await I_TestSTOFactory.upperSTVersionBounds.call(); assert.equal(_ustVersion[0], 0); assert.equal(_ustVersion[2], 1); - await I_STRProxied.setProtocolVersion(I_STFactory.address, 2, new BN(0), 1); - + await I_STRProxied.setProtocolFactory(I_STFactory.address, 2, new BN(0), 1); + await I_STRProxied.setLatestVersion(2, new BN(0), 1); // Generate the new securityToken let newSymbol = "toro"; await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000")), account_issuer); await I_PolyToken.approve(I_STRProxied.address, new BN(web3.utils.toWei("2000")), { from: account_issuer }); await I_STRProxied.registerTicker(account_issuer, newSymbol, name, { from: account_issuer }); let tx = await I_STRProxied.generateSecurityToken(name, newSymbol, tokenDetails, true, account_issuer, 0, { from: account_issuer }); - assert.equal(tx.logs[2].args._ticker, newSymbol.toUpperCase()); - I_SecurityToken2 = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + assert.equal(tx.logs[1].args._ticker, newSymbol.toUpperCase()); + I_SecurityToken2 = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken2.address); assert.equal(await stGetter.getTreasuryWallet.call(), account_issuer, "Incorrect wallet set") let bytesData = encodeModuleCall( @@ -417,19 +422,21 @@ contract("ModuleRegistry", async (accounts) => { [await latestTime(), currentTime.add(new BN(duration.days(1))), cap, "Test STO"] ); - await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, new BN(0), new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken2.addModule(I_TestSTOFactory.address, bytesData, new BN(0), new BN(0), false, { from: token_owner })); }); }); describe("Test case for the getModulesByTypeAndToken()", async () => { it("Should get the list of available modules when the customModulesAllowed", async () => { let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + console.log(_list); assert.equal(_list[0], I_CappedSTOFactory2.address); }); it("Should get the list of available modules when the customModulesAllowed is not allowed", async () => { await I_FeatureRegistry.setFeatureStatus("customModulesAllowed", false, { from: account_polymath }); let _list = await I_MRProxied.getModulesByTypeAndToken.call(3, I_SecurityToken.address); + console.log(_list); assert.equal(_list.length, 0); }); }); @@ -489,7 +496,7 @@ contract("ModuleRegistry", async (accounts) => { assert.equal(sto3_end, sto3); // delete related data assert.equal(await I_MRProxied.getUintValue.call(web3.utils.soliditySha3("registry", sto4)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto4), 0); + assert.equal((await I_MRProxied.getFactoryDetails.call(sto4))[1], 0); assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); assert.equal(await I_MRProxied.getBoolValue.call(web3.utils.soliditySha3("verified", sto4)), false); @@ -515,7 +522,7 @@ contract("ModuleRegistry", async (accounts) => { assert.equal(sto1_end, sto1); // delete related data assert.equal(await I_MRProxied.getUintValue.call(web3.utils.soliditySha3("registry", sto2)), 0); - assert.equal(await I_MRProxied.getReputationByFactory.call(sto2), 0); + assert.equal((await I_MRProxied.getFactoryDetails.call(sto2))[1], 0); assert.equal((await I_MRProxied.getModulesByType.call(3)).length, 3); assert.equal(await I_MRProxied.getBoolValue.call(web3.utils.soliditySha3("verified", sto2)), false); }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index e7ec0f667..bcb9461bb 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -169,9 +169,9 @@ contract("PercentageTransferManager", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set") const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -187,7 +187,7 @@ contract("PercentageTransferManager", async (accounts) => { }); it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -257,7 +257,7 @@ contract("PercentageTransferManager", async (accounts) => { it("Should successfully attach the PercentageTransferManager factory with the security token - failed payment", async () => { await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await catchRevert( - I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_PercentageTransferManagerFactory.address, bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -271,6 +271,7 @@ contract("PercentageTransferManager", async (accounts) => { bytesSTO, new BN(web3.utils.toWei("2000", "ether")), new BN(0), + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManagerFactory doesn't get deployed"); @@ -284,7 +285,7 @@ contract("PercentageTransferManager", async (accounts) => { }); it("Should successfully attach the PercentageTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "PercentageTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index 10ce13c75..1e032830c 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -145,9 +145,9 @@ contract("PreSaleSTO", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set") const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -165,15 +165,15 @@ contract("PreSaleSTO", async (accounts) => { it("Should fail to launch the STO due to endTime is 0", async () => { let bytesSTO = encodeModuleCall(STOParameters, [0]); - await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner })); }); - it("Should successfully attach the Paid STO factory with the security token", async () => { + it("Should successfully attach the Paid STO factory (archived) with the security token", async () => { let snap_id = await takeSnapshot(); endTime = await latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); await I_PolyToken.getTokens(new BN(web3.utils.toWei("500")), I_SecurityToken.address); - const tx = await I_SecurityToken.addModule(P_PreSaleSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("500")), new BN(0), { + const tx = await I_SecurityToken.addModule(P_PreSaleSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("500")), new BN(0), false, { from: token_owner }); @@ -190,14 +190,14 @@ contract("PreSaleSTO", async (accounts) => { it("Should successfully attach the STO factory with the security token -- fail because signature is different", async () => { endTime = await latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(["string"], ["hey"]); - await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner })); }); - it("Should successfully attach the STO factory with the security token", async () => { + it("Should successfully attach the STO factory (archived) with the security token", async () => { endTime = await latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), true, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); assert.equal( @@ -206,13 +206,15 @@ contract("PreSaleSTO", async (accounts) => { "PreSaleSTOFactory module was not added" ); I_PreSaleSTO = await PreSaleSTO.at(tx.logs[2].args._module); + let info = await stGetter.getModule.call(I_PreSaleSTO.address); + assert.equal(info[3], true); }); it("Should successfully attach the STO factory with the security token", async () => { endTime = await latestTime() + duration.days(30); // Start time will be 5000 seconds more than the latest time let bytesSTO = encodeModuleCall(STOParameters, [endTime]); - const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, bytesSTO, new BN(0), new BN(0), true, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], stoKey, "PreSaleSTO doesn't get deployed"); assert.equal( @@ -221,6 +223,9 @@ contract("PreSaleSTO", async (accounts) => { "PreSaleSTOFactory module was not added" ); I_PreSaleSTO = await PreSaleSTO.at(tx.logs[2].args._module); + let info = await stGetter.getModule.call(I_PreSaleSTO.address); + assert.equal(info[3], true); + }); }); @@ -236,9 +241,6 @@ contract("PreSaleSTO", async (accounts) => { }); describe("Buy tokens", async () => { - it("Should allocate the tokens -- failed due to investor not on whitelist", async () => { - await catchRevert(I_PreSaleSTO.allocateTokens(account_investor1, 1000, new BN(web3.utils.toWei("1", "ether")), 0)); - }); it("Should Buy the tokens", async () => { fromTime = await latestTime(); @@ -255,14 +257,24 @@ contract("PreSaleSTO", async (accounts) => { // Jump time await increaseTime(duration.days(1)); + // Fail as module is archived + await catchRevert( + I_PreSaleSTO.allocateTokens(account_investor1, new BN(web3.utils.toWei("1", "ether")), new BN(web3.utils.toWei("1", "ether")), new BN(0), { + from: account_issuer + }) + ); + await I_SecurityToken.unarchiveModule(I_PreSaleSTO.address, {from: token_owner}); + let info = await stGetter.getModule.call(I_PreSaleSTO.address); + assert.equal(info[3], false); + + //Fail as investor is not on whitelist + await catchRevert(I_PreSaleSTO.allocateTokens(account_investor2, 1000, new BN(web3.utils.toWei("1", "ether")), 0)); await I_PreSaleSTO.allocateTokens(account_investor1, new BN(web3.utils.toWei("1", "ether")), new BN(web3.utils.toWei("1", "ether")), new BN(0), { from: account_issuer }); - assert.equal((await I_PreSaleSTO.getRaised.call(0)).div(new BN(10).pow(new BN(18))).toNumber(), 1); console.log(await I_PreSaleSTO.getNumberInvestors.call()); assert.equal((await I_PreSaleSTO.getNumberInvestors.call()).toNumber(), 1); - // assert.isTrue(false); }); it("Should allocate the tokens --failed because of amount is 0", async () => { diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index 66d555c0c..40bb6910c 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -94,7 +94,7 @@ contract("SecurityTokenRegistry", async (accounts) => { const initRegFee = new BN(web3.utils.toWei("250")); const initRegFeePOLY = new BN(web3.utils.toWei("1000")); - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const STRProxyParameters = ["address", "uint256", "uint256", "address", "address"]; const STOParameters = ["uint256", "uint256", "uint256", "string"]; // Capped STO details @@ -185,7 +185,6 @@ contract("SecurityTokenRegistry", async (accounts) => { it("Should successfully update the implementation address -- fail because polymathRegistry address is 0x", async () => { let bytesProxy = encodeProxyCall(STRProxyParameters, [ address_zero, - I_STFactory.address, initRegFee, initRegFee, account_polymath, @@ -199,61 +198,9 @@ contract("SecurityTokenRegistry", async (accounts) => { ); }); - it("Should successfully update the implementation address -- fail because STFactory address is 0x", async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - address_zero, - initRegFee, - initRegFee, - account_polymath, - I_STRGetter.address - ]); - await catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }), - "tx-> revert because STFactory address is 0x" - ); - }); - - it("Should successfully update the implementation address -- fail because STLaunch fee is 0", async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - new BN(0), - initRegFee, - account_polymath, - I_STRGetter.address - ]); - await catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }), - "tx-> revert because STLaunch fee is 0" - ); - }); - - it("Should successfully update the implementation address -- fail because tickerRegFee fee is 0", async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [ - I_PolymathRegistry.address, - I_STFactory.address, - initRegFee, - new BN(0), - account_polymath, - I_STRGetter.address - ]); - await catchRevert( - I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { - from: account_polymath - }), - "tx-> revert because tickerRegFee is 0" - ); - }); - it("Should successfully update the implementation address -- fail because owner address is 0x", async () => { let bytesProxy = encodeProxyCall(STRProxyParameters, [ I_PolymathRegistry.address, - I_STFactory.address, initRegFee, initRegFee, address_zero, @@ -268,7 +215,7 @@ contract("SecurityTokenRegistry", async (accounts) => { }); it("Should successfully update the implementation address -- fail because all params get 0", async () => { - let bytesProxy = encodeProxyCall(STRProxyParameters, [address_zero, address_zero, new BN(0), new BN(0), address_zero, address_zero]); + let bytesProxy = encodeProxyCall(STRProxyParameters, [address_zero, new BN(0), new BN(0), address_zero, address_zero]); await catchRevert( I_SecurityTokenRegistryProxy.upgradeToAndCall("1.0.0", I_SecurityTokenRegistry.address, bytesProxy, { from: account_polymath @@ -280,7 +227,6 @@ contract("SecurityTokenRegistry", async (accounts) => { it("Should successfully update the implementation address", async () => { let bytesProxy = encodeProxyCall(STRProxyParameters, [ I_PolymathRegistry.address, - I_STFactory.address, initRegFee, initRegFee, account_polymath, @@ -291,6 +237,16 @@ contract("SecurityTokenRegistry", async (accounts) => { }); I_Getter = await STRGetter.at(I_SecurityTokenRegistryProxy.address); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); + await I_STRProxied.setProtocolFactory(I_STFactory.address, 3, 0, 0); + await I_STRProxied.setLatestVersion(3, 0, 0); + + console.log(await I_Getter.getSTFactoryAddress()); + let info = await I_Getter.getLatestProtocolVersion(); + for (let i = 0; i < info.length; i++) { + console.log(info[i].toNumber()); + } + console.log(await I_Getter.getLatestProtocolVersion()); + }); }); @@ -325,7 +281,6 @@ contract("SecurityTokenRegistry", async (accounts) => { await catchRevert( I_STRProxied.initialize( I_PolymathRegistry.address, - I_STFactory.address, initRegFee, initRegFee, account_polymath, @@ -590,13 +545,18 @@ contract("SecurityTokenRegistry", async (accounts) => { }); it("Should generate the new security token with the same symbol as registered above", async () => { - + console.log(await I_STRGetter.getSTFactoryAddress()); + let info = await I_STRGetter.getLatestProtocolVersion(); + for (let i = 0; i < info.length; i++) { + console.log(info[i].toNumber()); + } + console.log(await I_STRGetter.getLatestProtocolVersion()); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, treasury_wallet, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), treasury_wallet, "Incorrect wallet set") const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -643,9 +603,9 @@ contract("SecurityTokenRegistry", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, "TMP", tokenDetails, false, account_temp, 0, { from: account_temp }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, "TMP", "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, "TMP", "SecurityToken doesn't get deployed"); - let securityTokenTmp = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + let securityTokenTmp = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); let tokens = await I_Getter.getTokensByOwner.call(token_owner); assert.equal(tokens.length, 1, "tokens array length error"); @@ -663,7 +623,7 @@ contract("SecurityTokenRegistry", async (accounts) => { describe("Generate SecurityToken v2", async () => { it("Should deploy the st version 2", async () => { // Step 7: Deploy the STFactory contract - I_STGetter = await STGetter.new(); + I_STGetter = await STGetter.new({from: account_polymath}); let I_DataStoreLogic = await DataStoreLogic.new({ from: account_polymath }); let I_DataStoreFactory = await DataStoreFactory.new(I_DataStoreLogic.address, { from: account_polymath }); I_TokenLib = await TokenLib.new(); @@ -678,7 +638,7 @@ contract("SecurityTokenRegistry", async (accounts) => { "STFactory002 contract was not deployed" ); let _protocol = await I_Getter.getLatestProtocolVersion.call(); - assert.equal(_protocol[0], 2); + assert.equal(_protocol[0], 3); assert.equal(_protocol[1], 0); assert.equal(_protocol[2], 0); }); @@ -691,12 +651,18 @@ contract("SecurityTokenRegistry", async (accounts) => { }); it("Should change the protocol version", async() => { - await I_STRProxied.setProtocolVersion(I_STFactory002.address, new BN(2), new BN(2), new BN(0), { from: account_polymath }); + await I_STRProxied.setProtocolFactory(I_STFactory002.address, new BN(2), new BN(2), new BN(0), { from: account_polymath }); let _protocol = await I_Getter.getLatestProtocolVersion.call(); + assert.equal(_protocol[0], 3); + assert.equal(_protocol[1], 0); + assert.equal(_protocol[2], 0); + await I_STRProxied.setLatestVersion(new BN(2), new BN(2), new BN(0), { from: account_polymath }); + _protocol = await I_Getter.getLatestProtocolVersion.call(); assert.equal(_protocol[0], 2); assert.equal(_protocol[1], 2); assert.equal(_protocol[2], 0); - await I_STRProxied.setProtocolVersion(I_STFactory.address, new BN(3), new BN(0), new BN(0), { from: account_polymath}); + await I_STRProxied.setProtocolFactory(I_STFactory.address, new BN(3), new BN(0), new BN(0), { from: account_polymath}); + await I_STRProxied.setLatestVersion(new BN(3), new BN(0), new BN(0), { from: account_polymath}); _protocol = await I_Getter.getLatestProtocolVersion.call(); assert.equal(_protocol[0], 3); assert.equal(_protocol[1], 0); @@ -711,12 +677,13 @@ contract("SecurityTokenRegistry", async (accounts) => { }) it("Should generate the new security token with version 2", async () => { + // Version bounds not checked here as MR is called as non-token let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, false, token_owner, _pack(2,2,0), { from: token_owner }); console.log(`Protocol version: ${_pack(2,2,0)}`); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol2, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol2, "SecurityToken doesn't get deployed"); - I_SecurityToken002 = await SecurityTokenMock.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken002 = await SecurityTokenMock.at(tx.logs[1].args._securityTokenAddress); let stGetterV2 = await STGetter.at(I_SecurityToken002.address); let stVersion = await stGetterV2.getVersion.call(); console.log(stVersion); @@ -1128,7 +1095,7 @@ contract("SecurityTokenRegistry", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken("Polymath", "POLY", tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, "POLY", "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, "POLY", "SecurityToken doesn't get deployed"); }); }); @@ -1314,23 +1281,23 @@ contract("SecurityTokenRegistry", async (accounts) => { describe("Test cases for the setProtocolVersion", async () => { it("Should successfully change the protocolVersion -- failed because of bad owner", async () => { - await catchRevert(I_STRProxied.setProtocolVersion(accounts[8], 5, 6, 7, { from: account_temp })); + await catchRevert(I_STRProxied.setProtocolFactory(accounts[8], 5, 6, 7, { from: account_temp })); }); it("Should successfully change the protocolVersion -- failed because factory address is 0x", async () => { await catchRevert( - I_STRProxied.setProtocolVersion(address_zero, 5, 6, 7, { from: account_polymath }) + I_STRProxied.setProtocolFactory(address_zero, 5, 6, 7, { from: account_polymath }) ); }); - it("Should successfully change the protocolVersion -- not a valid vesrion", async () => { - await catchRevert(I_STRProxied.setProtocolVersion(accounts[8], new BN(0), new BN(0), new BN(0), { from: account_polymath })); + it("Should successfully change the protocolVersion -- not a valid version", async () => { + await catchRevert(I_STRProxied.setLatestVersion(new BN(0), new BN(0), new BN(0), { from: account_polymath })); }); it("Should successfully change the protocolVersion -- fail in second attempt because of invalid version", async () => { let snap_Id = await takeSnapshot(); - await I_STRProxied.setProtocolVersion(accounts[8], 3, 1, 1, { from: account_polymath }); - await catchRevert(I_STRProxied.setProtocolVersion(accounts[8], 1, 3, 1, { from: account_polymath })); + await I_STRProxied.setProtocolFactory(accounts[8], 3, 1, 1, { from: account_polymath }); + await catchRevert(I_STRProxied.setLatestVersion(1, 3, 1, { from: account_polymath })); await revertToSnapshot(snap_Id); }); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index c0ea681ef..1e93c066f 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -12,6 +12,8 @@ import { deployMockWrongTypeRedemptionAndVerifyed } from "./helpers/createInstances"; +const MockSecurityTokenLogic = artifacts.require("./MockSecurityTokenLogic.sol"); +const MockSTGetter = artifacts.require("./MockSTGetter.sol"); const CappedSTOFactory = artifacts.require("./CappedSTOFactory.sol"); const CappedSTO = artifacts.require("./CappedSTO.sol"); const SecurityToken = artifacts.require("./SecurityToken.sol"); @@ -191,16 +193,22 @@ contract("SecurityToken", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + for (let i = 0; i < tx.logs.length; i++) { + console.log("LOGS: " + i); + console.log(tx.logs[i]); + } + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set") - const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; + const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; // Verify that GeneralTransferManager module get added successfully or not assert.equal(log.args._types[0].toNumber(), transferManagerKey); assert.equal(web3.utils.toUtf8(log.args._name), "GeneralTransferManager"); + assert.equal(await I_SecurityToken.owner.call(), token_owner); + assert.equal(await I_SecurityToken.initialized.call(), true); }); it("Should not allow unauthorized address to change name", async() => { @@ -208,7 +216,7 @@ contract("SecurityToken", async (accounts) => { }); it("Should allow authorized address to change name", async() => { - let snapId = await takeSnapshot(); + let snapId = await takeSnapshot(); await I_SecurityToken.changeName("new token name", { from: token_owner }); assert.equal((await I_SecurityToken.name()).replace(/\u0000/g, ""), "new token name"); await revertToSnapshot(snapId); @@ -302,7 +310,7 @@ contract("SecurityToken", async (accounts) => { it("Should mint to lots of addresses and check gas", async () => { let id = await takeSnapshot(); await I_GeneralTransferManager.modifyTransferRequirementsMulti( - [0, 1, 2], + [0, 1, 2], [false, false, false], [false, false, false], [false, false, false], @@ -323,7 +331,7 @@ contract("SecurityToken", async (accounts) => { console.log("Cost for issuing to 40 addresses without checkpoint: " + tx.receipt.gasUsed); await revertToSnapshot(id2); - + await I_SecurityToken.createCheckpoint({ from: token_owner }); tx = await I_SecurityToken.issueMulti(mockInvestors, mockAmount, { @@ -349,7 +357,7 @@ contract("SecurityToken", async (accounts) => { assert.isTrue(await I_SecurityToken.isIssuable.call()); }) - + it("Should finish the minting -- fail because owner didn't sign correct acknowledegement", async () => { let trueButOutOfPlaceAcknowledegement = web3.utils.utf8ToHex( "F O'Brien is the best!" @@ -376,7 +384,7 @@ contract("SecurityToken", async (accounts) => { startTime = await latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); - await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner })); + await catchRevert(I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner })); }); it("Should fail to attach the STO factory because max cost too small", async () => { @@ -387,7 +395,7 @@ contract("SecurityToken", async (accounts) => { await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCostPOLY, { from: token_owner }); await catchRevert( - I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("1000", "ether")), new BN(0), { from: token_owner }) + I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("1000", "ether")), new BN(0), false, { from: token_owner }) ); }); @@ -400,7 +408,7 @@ contract("SecurityToken", async (accounts) => { await I_PolyToken.getTokens(cappedSTOSetupCostPOLY, token_owner); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCostPOLY, { from: token_owner }); console.log("0"); - const tx = await I_SecurityToken.addModuleWithLabel(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), web3.utils.fromAscii("stofactory"), { + const tx = await I_SecurityToken.addModuleWithLabel(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), web3.utils.fromAscii("stofactory"), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); @@ -419,7 +427,7 @@ contract("SecurityToken", async (accounts) => { await I_PolyToken.getTokens(cappedSTOSetupCostPOLY, token_owner); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCostPOLY, { from: token_owner }); - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); @@ -530,7 +538,7 @@ contract("SecurityToken", async (accounts) => { FactoryInstances = [D_GPM, D_GPM_1, D_GPM_2]; // Adding module in the ST for (let i = 0; i < FactoryInstances.length; i++) { - let tx = await I_SecurityToken.addModule(FactoryInstances[i].address, "0x0", new BN(0), new BN(0), { from: token_owner }); + let tx = await I_SecurityToken.addModule(FactoryInstances[i].address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], permissionManagerKey, "fail in adding the GPM"); GPMAddress.push(tx.logs[2].args._module); } @@ -668,7 +676,7 @@ contract("SecurityToken", async (accounts) => { it("Should fail to provide the permission to the delegate to change the transfer bools -- Bad owner", async () => { // Add permission to the deletgate (A regesteration process) - await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); let moduleData = (await stGetter.getModulesByType(permissionManagerKey))[0]; I_GeneralPermissionManager = await GeneralPermissionManager.at(moduleData); await catchRevert(I_GeneralPermissionManager.addDelegate(account_delegate, delegateDetails, { from: account_temp })); @@ -768,6 +776,38 @@ contract("SecurityToken", async (accounts) => { assert.equal(transferRestrions[3], false); }); + it("Should upgrade token logic and getter", async () => { + let mockSTGetter = await MockSTGetter.new({from: account_polymath}); + let mockSecurityTokenLogic = await MockSecurityTokenLogic.new("", "", 0, {from: account_polymath}); + const tokenInitBytes = { + name: "upgrade", + type: "function", + inputs: [ + { + type: "address", + name: "_getterDelegate" + }, + { + type: "uint256", + name: "_upgrade" + } + ] + }; + let tokenInitBytesCall = web3.eth.abi.encodeFunctionCall(tokenInitBytes, [mockSTGetter.address, 10]); + await I_STFactory.setLogicContract("3.0.1", mockSecurityTokenLogic.address, tokenInitBytesCall, {from: account_polymath}); + // NB - the mockSecurityTokenLogic sets its internal version to 3.0.0 not 3.0.1 + let tx = await I_SecurityToken.upgradeToken({from: token_owner}); + assert.equal(tx.logs[0].args._major, 3); + assert.equal(tx.logs[0].args._minor, 0); + assert.equal(tx.logs[0].args._patch, 0); + let newToken = await MockSecurityTokenLogic.at(I_SecurityToken.address); + let newGetter = await MockSTGetter.at(I_SecurityToken.address); + tx = await newToken.newFunction(11); + assert.equal(tx.logs[0].args._upgrade, 11); + tx = await newGetter.newGetter(12); + assert.equal(tx.logs[0].args._upgrade, 12); + }); + it("Should transfer from whitelist investor1 to whitelist investor 2", async () => { let tx = await I_GeneralTransferManager.modifyKYCData(account_investor2, fromTime, toTime, expiryTime, { from: token_owner, @@ -1092,7 +1132,7 @@ contract("SecurityToken", async (accounts) => { describe("Test cases for the Mock TrackedRedeemption", async () => { it("Should add the tracked redeemption module successfully", async () => { [I_MockRedemptionManagerFactory] = await deployMockRedemptionAndVerifyed(account_polymath, I_MRProxied, 0); - let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0], burnKey, "fail in adding the burn manager"); I_MockRedemptionManager = await MockRedemptionManager.at(tx.logs[2].args._module); // adding the burn module into the GTM @@ -1131,7 +1171,7 @@ contract("SecurityToken", async (accounts) => { it("Should successfully fail in calling the burn functions", async () => { [I_MockRedemptionManagerFactory] = await deployMockWrongTypeRedemptionAndVerifyed(account_polymath, I_MRProxied, 0); - let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + let tx = await I_SecurityToken.addModule(I_MockRedemptionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); I_MockRedemptionManager = await MockRedemptionManager.at(tx.logs[2].args._module); // adding the burn module into the GTM @@ -1369,28 +1409,28 @@ contract("SecurityToken", async (accounts) => { `); assert.equal( await I_SecurityToken.name.call(), - (web3.utils.toAscii(await readStorage(I_SecurityToken.address, 5)).replace(/\u0000/g, "")).replace(/\u0014/g, "") + (web3.utils.toAscii(await readStorage(I_SecurityToken.address, 6)).replace(/\u0000/g, "")).replace(/\u0014/g, "") ) console.log(` Name of the ST: ${await I_SecurityToken.name.call()} - Name of the ST from the storage: ${web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 5))} + Name of the ST from the storage: ${web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 6))} `); assert.equal( await I_SecurityToken.symbol.call(), - (web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 6)).replace(/\u0000/g, "")).replace(/\u0006/g, "") + (web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 7)).replace(/\u0000/g, "")).replace(/\u0006/g, "") ); console.log(` Symbol of the ST: ${await I_SecurityToken.symbol.call()} - Symbol of the ST from the storage: ${web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 6))} + Symbol of the ST from the storage: ${web3.utils.toUtf8(await readStorage(I_SecurityToken.address, 7))} `); console.log(` Address of the owner: ${await I_SecurityToken.owner.call()} - Address of the owner from the storage: ${(await readStorage(I_SecurityToken.address, 3)).substring(0, 42)} + Address of the owner from the storage: ${(await readStorage(I_SecurityToken.address, 4)).substring(0, 42)} `) assert.equal( await I_SecurityToken.owner.call(), - web3.utils.toChecksumAddress((await readStorage(I_SecurityToken.address, 3)).substring(0, 42)) + web3.utils.toChecksumAddress((await readStorage(I_SecurityToken.address, 4)).substring(0, 42)) ); }); @@ -1399,13 +1439,13 @@ contract("SecurityToken", async (accounts) => { console.log(` Controller address from the contract: ${await stGetter.controller.call()} - decimals from the contract: ${await stGetter.decimals.call()} - controller address from the storage + uint8 decimals: ${await readStorage(I_SecurityToken.address, 7)} + decimals from the contract: ${await stGetter.decimals.call()} + controller address from the storage + uint8 decimals: ${await readStorage(I_SecurityToken.address, 8)} `) // Controller address is packed with decimals so if controller address is 0x0, only decimals will be returned from read storage. assert.oneOf( - await readStorage(I_SecurityToken.address, 7), + await readStorage(I_SecurityToken.address, 8), [ (await stGetter.controller.call()).toLowerCase() + "12", "0x12" // When controller address = 0x0, web3 converts 0x00000..000012 to 0x12 @@ -1414,89 +1454,89 @@ contract("SecurityToken", async (accounts) => { console.log(` PolymathRegistry address from the contract: ${await stGetter.polymathRegistry.call()} - PolymathRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 8)} + PolymathRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 9)} `) assert.equal( await stGetter.polymathRegistry.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 8)) + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 9)) ); console.log(` ModuleRegistry address from the contract: ${await stGetter.moduleRegistry.call()} - ModuleRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 9)} + ModuleRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 10)} `) assert.equal( await stGetter.moduleRegistry.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 9)) + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 10)) ); console.log(` SecurityTokenRegistry address from the contract: ${await stGetter.securityTokenRegistry.call()} - SecurityTokenRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 10)} + SecurityTokenRegistry address from the storage: ${await readStorage(I_SecurityToken.address, 11)} `) assert.equal( await stGetter.securityTokenRegistry.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 10)) + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 11)) ); console.log(` PolyToken address from the contract: ${await stGetter.polyToken.call()} - PolyToken address from the storage: ${await readStorage(I_SecurityToken.address, 11)} + PolyToken address from the storage: ${await readStorage(I_SecurityToken.address, 12)} `) assert.equal( await stGetter.polyToken.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 11)) + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 12)) ); console.log(` - Delegate address from the contract: ${await stGetter.delegate.call()} - Delegate address from the storage: ${await readStorage(I_SecurityToken.address, 12)} + Delegate address from the contract: ${await stGetter.getterDelegate.call()} + Delegate address from the storage: ${await readStorage(I_SecurityToken.address, 13)} `) assert.equal( - await stGetter.delegate.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 12)) + await stGetter.getterDelegate.call(), + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 13)) ); console.log(` Datastore address from the contract: ${await stGetter.dataStore.call()} - Datastore address from the storage: ${await readStorage(I_SecurityToken.address, 13)} + Datastore address from the storage: ${await readStorage(I_SecurityToken.address, 14)} `) assert.equal( await stGetter.dataStore.call(), - web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 13)) + web3.utils.toChecksumAddress(await readStorage(I_SecurityToken.address, 14)) ); console.log(` Granularity value from the contract: ${await stGetter.granularity.call()} - Granularity value from the storage: ${(web3.utils.toBN(await readStorage(I_SecurityToken.address, 14))).toString()} + Granularity value from the storage: ${(web3.utils.toBN(await readStorage(I_SecurityToken.address, 15))).toString()} `) assert.equal( web3.utils.fromWei(await stGetter.granularity.call()), - web3.utils.fromWei((web3.utils.toBN(await readStorage(I_SecurityToken.address, 14))).toString()) + web3.utils.fromWei((web3.utils.toBN(await readStorage(I_SecurityToken.address, 15))).toString()) ); console.log(` Current checkpoint ID from the contract: ${await stGetter.currentCheckpointId.call()} - Current checkpoint ID from the storage: ${(web3.utils.toBN(await readStorage(I_SecurityToken.address, 15))).toString()} + Current checkpoint ID from the storage: ${(web3.utils.toBN(await readStorage(I_SecurityToken.address, 16))).toString()} `) assert.equal( await stGetter.currentCheckpointId.call(), - (web3.utils.toBN(await readStorage(I_SecurityToken.address, 15))).toString() + (web3.utils.toBN(await readStorage(I_SecurityToken.address, 16))).toString() ); console.log(` TokenDetails from the contract: ${await stGetter.tokenDetails.call()} - TokenDetails from the storage: ${(web3.utils.toUtf8((await readStorage(I_SecurityToken.address, 16)).substring(0, 60)))} + TokenDetails from the storage: ${(web3.utils.toUtf8((await readStorage(I_SecurityToken.address, 17)).substring(0, 60)))} `) assert.equal( await stGetter.tokenDetails.call(), - (web3.utils.toUtf8((await readStorage(I_SecurityToken.address, 16)).substring(0, 60))).replace(/\u0000/g, "") + (web3.utils.toUtf8((await readStorage(I_SecurityToken.address, 17)).substring(0, 60))).replace(/\u0000/g, "") ); }); diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 4eec0a9f0..1d87329b4 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -287,9 +287,9 @@ contract("USDTieredSTO", async (accounts) => { await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, ISSUER, 0, { from: ISSUER }); - assert.equal(tx.logs[2].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), ISSUER, "Incorrect wallet set") const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -338,7 +338,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -412,7 +412,7 @@ contract("USDTieredSTO", async (accounts) => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); await catchRevert( - I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), { + I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }) @@ -439,7 +439,7 @@ contract("USDTieredSTO", async (accounts) => { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000")), I_SecurityToken.address); - let tx = await I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), { + let tx = await I_SecurityToken.addModule(P_USDTieredSTOFactory.address, bytesSTO, new BN(web3.utils.toWei("2000")), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); @@ -527,7 +527,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -611,7 +611,7 @@ contract("USDTieredSTO", async (accounts) => { _usdToken[stoId] ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -650,7 +650,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -689,7 +689,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -731,7 +731,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, 0, 0, false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); @@ -809,7 +809,7 @@ contract("USDTieredSTO", async (accounts) => { for (var i = 0; i < config.length; i++) { let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config[i]); - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER })); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER })); } }); @@ -833,7 +833,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER })); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER })); }); it("Should fail because Zero address is not permitted for wallet", async () => { @@ -856,7 +856,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER })); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER })); }); it("Should fail because end time before start time", async () => { @@ -880,7 +880,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER })); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER })); }); it("Should fail because start time is in the past", async () => { @@ -904,7 +904,7 @@ contract("USDTieredSTO", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER })); + await catchRevert(I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER })); }); }); diff --git a/test/q_usd_tiered_sto_sim.js b/test/q_usd_tiered_sto_sim.js index 2c49de887..1c37f05fd 100644 --- a/test/q_usd_tiered_sto_sim.js +++ b/test/q_usd_tiered_sto_sim.js @@ -262,9 +262,9 @@ contract("USDTieredSTO Sim", async (accounts) => { await I_PolyToken.approve(I_STRProxied.address, REGFEE, { from: ISSUER }); let tx = await I_STRProxied.generateSecurityToken(NAME, SYMBOL, TOKENDETAILS, true, ISSUER, 0, { from: ISSUER }); - assert.equal(tx.logs[2].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, SYMBOL, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), ISSUER, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -311,7 +311,7 @@ contract("USDTieredSTO Sim", async (accounts) => { ]; let bytesSTO = web3.eth.abi.encodeFunctionCall(functionSignature, config); - let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), { from: ISSUER, gasPrice: GAS_PRICE }); + let tx = await I_SecurityToken.addModule(I_USDTieredSTOFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: ISSUER, gasPrice: GAS_PRICE }); console.log(" Gas addModule: ".grey + tx.receipt.gasUsed.toString().grey); assert.equal(tx.logs[2].args._types[0], STOKEY, "USDTieredSTO doesn't get deployed"); assert.equal(web3.utils.hexToString(tx.logs[2].args._name), "USDTieredSTO", "USDTieredSTOFactory module was not added"); diff --git a/test/r_concurrent_STO.js b/test/r_concurrent_STO.js index 558b77ceb..0fc1bbb60 100644 --- a/test/r_concurrent_STO.js +++ b/test/r_concurrent_STO.js @@ -149,9 +149,9 @@ contract("Concurrent STO", async (accounts) => { await I_PolyToken.approve(I_STRProxied.address, initRegFee, { from: account_issuer }); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, account_issuer, 0, { from: account_issuer }); - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), account_issuer, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -208,7 +208,7 @@ contract("Concurrent STO", async (accounts) => { switch (STOIndex % 3) { case 0: // Capped STO - let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, { + let tx1 = await I_SecurityToken.addModule(I_CappedSTOFactory.address, cappedBytesSig, maxCost, budget, false, { from: account_issuer }); assert.equal(tx1.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); @@ -221,7 +221,7 @@ contract("Concurrent STO", async (accounts) => { break; case 1: // Dummy STO - let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, { + let tx2 = await I_SecurityToken.addModule(I_DummySTOFactory.address, dummyBytesSig, maxCost, budget, false, { from: account_issuer }); assert.equal(tx2.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); @@ -234,7 +234,7 @@ contract("Concurrent STO", async (accounts) => { break; case 2: // Pre Sale STO - let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, { + let tx3 = await I_SecurityToken.addModule(I_PreSaleSTOFactory.address, presaleBytesSig, maxCost, budget, false, { from: account_issuer }); assert.equal(tx3.logs[3].args._types[0], stoKey, `Wrong module type added at index ${STOIndex}`); diff --git a/test/t_security_token_registry_proxy.js b/test/t_security_token_registry_proxy.js index bc05c934c..a92764fd4 100644 --- a/test/t_security_token_registry_proxy.js +++ b/test/t_security_token_registry_proxy.js @@ -56,7 +56,7 @@ contract("SecurityTokenRegistryProxy", async (accounts) => { const address_zero = "0x0000000000000000000000000000000000000000"; const one_address = "0x0000000000000000000000000000000000000001"; - const STRProxyParameters = ["address", "address", "uint256", "uint256", "address", "address"]; + const STRProxyParameters = ["address", "uint256", "uint256", "address", "address"]; async function readStorage(contractAddress, slot) { return await web3.eth.getStorageAt(contractAddress, slot); @@ -115,7 +115,6 @@ contract("SecurityTokenRegistryProxy", async (accounts) => { I_STRGetter = await STRGetter.new({from: account_polymath}); let bytesProxy = encodeProxyCall(STRProxyParameters, [ I_PolymathRegistry.address, - I_STFactory.address, initRegFee, initRegFee, account_polymath, @@ -135,6 +134,8 @@ contract("SecurityTokenRegistryProxy", async (accounts) => { ); I_STRProxied = await SecurityTokenRegistry.at(I_SecurityTokenRegistryProxy.address); I_STRGetter = await STRGetter.at(I_SecurityTokenRegistryProxy.address); + await I_STRProxied.setProtocolFactory(I_STFactory.address, 3, 0, 0); + await I_STRProxied.setLatestVersion(3, 0, 0); }); it("Verify the initialize data", async () => { @@ -165,9 +166,9 @@ contract("SecurityTokenRegistryProxy", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol, "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol, "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; diff --git a/test/u_module_registry_proxy.js b/test/u_module_registry_proxy.js index 6b44ae8c0..e3447bf27 100644 --- a/test/u_module_registry_proxy.js +++ b/test/u_module_registry_proxy.js @@ -139,6 +139,13 @@ contract("ModuleRegistryProxy", async (accounts) => { { from: account_polymath } ); + let I_SecurityTokenLogic = await SecurityToken.new( + "", + "", + 0, + { from: account_polymath } + ); + I_GeneralTransferManagerFactory = await GeneralTransferManagerFactory.new(new BN(0), new BN(0), I_GeneralTransferManagerLogic.address, I_PolymathRegistry.address, true, { from: account_polymath }); @@ -153,13 +160,24 @@ contract("ModuleRegistryProxy", async (accounts) => { // (A) : Register the GeneralTransferManagerFactory await I_MRProxied.registerModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, true, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralTransferManagerFactory.address, { from: account_polymath }); // Step 3: Deploy the STFactory contract - I_STGetter = await STGetter.new(); + I_STGetter = await STGetter.new({from: account_polymath}); let I_DataStoreLogic = await DataStoreLogic.new({ from: account_polymath }); let I_DataStoreFactory = await DataStoreFactory.new(I_DataStoreLogic.address, { from: account_polymath }); - I_STFactory = await STFactory.new(I_GeneralTransferManagerFactory.address, I_DataStoreFactory.address, I_STGetter.address, { from: account_polymath }); + const tokenInitBytes = { + name: "initialize", + type: "function", + inputs: [ + { + type: "address", + name: "_getterDelegate" + } + ] + }; + let tokenInitBytesCall = web3.eth.abi.encodeFunctionCall(tokenInitBytes, [I_STGetter.address]); + I_STFactory = await STFactory.new(I_PolymathRegistry.address, I_GeneralTransferManagerFactory.address, I_DataStoreFactory.address, "3.0.0", I_SecurityTokenLogic.address, tokenInitBytesCall, { from: account_polymath }); assert.notEqual(I_STFactory.address.valueOf(), address_zero, "STFactory contract was not deployed"); }); @@ -188,7 +206,7 @@ contract("ModuleRegistryProxy", async (accounts) => { ); await I_MRProxied.registerModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); - await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, true, { from: account_polymath }); + await I_MRProxied.verifyModule(I_GeneralPermissionManagerfactory.address, { from: account_polymath }); }); }); @@ -238,16 +256,16 @@ contract("ModuleRegistryProxy", async (accounts) => { describe("Execute functionality of the implementation contract on the earlier storage", async () => { it("Should get the previous data", async () => { - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, new BN(0), "Should give the original length"); + let _data = await I_MRProxied.getFactoryDetails.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data[1].length, new BN(0), "Should give the original length"); }); it("Should alter the old storage", async () => { await I_MRProxied.addMoreReputation(I_GeneralTransferManagerFactory.address, [account_polymath, account_temp], { from: account_polymath }); - let _data = await I_MRProxied.getReputationByFactory.call(I_GeneralTransferManagerFactory.address); - assert.equal(_data.length, 2, "Should give the updated length"); + let _data = await I_MRProxied.getFactoryDetails.call(I_GeneralTransferManagerFactory.address); + assert.equal(_data[1].length, 2, "Should give the updated length"); }); }); diff --git a/test/v_tracked_redemptions.js b/test/v_tracked_redemptions.js index d8cc67f7e..dd01ba03c 100644 --- a/test/v_tracked_redemptions.js +++ b/test/v_tracked_redemptions.js @@ -143,9 +143,9 @@ contract("TrackedRedemption", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -163,7 +163,7 @@ contract("TrackedRedemption", async (accounts) => { it("Should successfully attach the paid TrackedRedemption with the security token", async () => { let snapId = await takeSnapshot(); await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000")), I_SecurityToken.address); - const tx = await I_SecurityToken.addModule(P_TrackedRedemptionFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), { + const tx = await I_SecurityToken.addModule(P_TrackedRedemptionFactory.address, "0x0", new BN(web3.utils.toWei("2000")), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); @@ -177,7 +177,7 @@ contract("TrackedRedemption", async (accounts) => { }); it("Should successfully attach the TrackedRedemption with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_TrackedRedemptionFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), burnKey, "TrackedRedemption doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -246,7 +246,7 @@ contract("TrackedRedemption", async (accounts) => { it("Redeem some tokens - fail insufficient allowance", async () => { await I_GeneralTransferManager.modifyTransferRequirementsMulti( - [0, 1, 2], + [0, 1, 2], [true, false, false], [true, true, false], [false, false, false], diff --git a/test/w_lockup_transfer_manager.js b/test/w_lockup_transfer_manager.js index d3df639aa..a056f5fd4 100644 --- a/test/w_lockup_transfer_manager.js +++ b/test/w_lockup_transfer_manager.js @@ -144,9 +144,9 @@ contract('LockUpTransferManager', accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -177,9 +177,9 @@ contract('LockUpTransferManager', accounts => { let tx = await I_STRProxied.generateSecurityToken(name2, symbol2, tokenDetails, true, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol2.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol2.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken_div = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken_div = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter_div = await STGetter.at(I_SecurityToken_div.address); assert.equal(await stGetter_div.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken_div.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -255,7 +255,7 @@ contract('LockUpTransferManager', accounts => { it("Should unsuccessfully attach the LockUpTransferManager factory with the security token -- failed because Token is not paid", async () => { await I_PolyToken.getTokens(web3.utils.toWei("2000", "ether"), token_owner); await catchRevert( - I_SecurityToken.addModule(P_LockUpTransferManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), 0, { from: token_owner }) + I_SecurityToken.addModule(P_LockUpTransferManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), 0, false, { from: token_owner }) ) }); @@ -263,7 +263,7 @@ contract('LockUpTransferManager', accounts => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, new BN(web3.utils.toWei("2000", "ether")), {from: token_owner}); console.log((await P_LockUpTransferManagerFactory.setupCost.call()).toString()); - const tx = await I_SecurityToken.addModule(P_LockUpTransferManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_LockUpTransferManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toString(), transferManagerKey, "LockUpVolumeRestrictionTMFactory doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) @@ -276,7 +276,7 @@ contract('LockUpTransferManager', accounts => { }); it("Should successfully attach the LockUpVolumeRestrictionTMFactory with the non-divisible security token", async () => { - const tx = await I_SecurityToken.addModule(I_LockUpTransferManagerFactory.address, "0x", 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_LockUpTransferManagerFactory.address, "0x", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), transferManagerKey, "LockUpVolumeRestrictionTMFactory doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) @@ -288,7 +288,7 @@ contract('LockUpTransferManager', accounts => { }); it("Should successfully attach the LockUpVolumeRestrictionTMFactory with the divisible security token", async () => { - const tx = await I_SecurityToken_div.addModule(I_LockUpTransferManagerFactory.address, "0x", 0, 0, { from: token_owner }); + const tx = await I_SecurityToken_div.addModule(I_LockUpTransferManagerFactory.address, "0x", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), transferManagerKey, "LockUpVolumeRestrictionTMFactory doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name) @@ -959,7 +959,7 @@ contract('LockUpTransferManager', accounts => { I_LockUpTransferManager.removeLockupType(web3.utils.fromAscii("l_lockup"), {from: token_owner}) ); }) - + it("Should get the data of all lockups", async() => { console.log(await I_LockUpTransferManager.getAllLockupData.call()); }); diff --git a/test/x_scheduled_checkpoints.js b/test/x_scheduled_checkpoints.js index d8d33d4bf..c67db9d99 100644 --- a/test/x_scheduled_checkpoints.js +++ b/test/x_scheduled_checkpoints.js @@ -139,9 +139,9 @@ process.env.COVERAGE ? contract.skip : contract("ScheduledCheckpoint", async (ac let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -160,7 +160,7 @@ process.env.COVERAGE ? contract.skip : contract("ScheduledCheckpoint", async (ac describe("Buy tokens using on-chain whitelist", async () => { it("Should successfully attach the ScheduledCheckpoint with the security token", async () => { await I_SecurityToken.changeGranularity(1, { from: token_owner }); - const tx = await I_SecurityToken.addModule(I_ScheduledCheckpointFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_ScheduledCheckpointFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), 4, "ScheduledCheckpoint doesn't get deployed"); assert.equal(tx.logs[2].args._types[1].toString(), 2, "ScheduledCheckpoint doesn't get deployed"); assert.equal( diff --git a/test/y_volume_restriction_tm.js b/test/y_volume_restriction_tm.js index 6c19daa4d..1b8819940 100644 --- a/test/y_volume_restriction_tm.js +++ b/test/y_volume_restriction_tm.js @@ -197,9 +197,9 @@ contract('VolumeRestrictionTransferManager', accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, true, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -217,7 +217,7 @@ contract('VolumeRestrictionTransferManager', accounts => { describe("Attach the VRTM", async() => { it("Deploy the VRTM and attach with the ST", async()=> { - let tx = await I_SecurityToken.addModule(I_VolumeRestrictionTMFactory.address, "0x0", new BN(0), new BN(0), {from: token_owner }); + let tx = await I_SecurityToken.addModule(I_VolumeRestrictionTMFactory.address, "0x0", new BN(0), new BN(0), false, {from: token_owner }); assert.equal(tx.logs[2].args._moduleFactory, I_VolumeRestrictionTMFactory.address); assert.equal( web3.utils.toUtf8(tx.logs[2].args._name), diff --git a/test/z_blacklist_transfer_manager.js b/test/z_blacklist_transfer_manager.js index 9bb74f197..053568628 100644 --- a/test/z_blacklist_transfer_manager.js +++ b/test/z_blacklist_transfer_manager.js @@ -153,9 +153,9 @@ contract('BlacklistTransferManager', accounts => { let _blockNo = latestBlock(); let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -178,7 +178,7 @@ contract('BlacklistTransferManager', accounts => { it("Should successfully attach the BlacklistTransferManager factory with the security token", async () => { await I_PolyToken.getTokens(web3.utils.toWei("2000", "ether"), token_owner); await catchRevert ( - I_SecurityToken.addModule(P_BlacklistTransferManagerFactory.address, bytesSTO, web3.utils.toWei("2000", "ether"), 0, { + I_SecurityToken.addModule(P_BlacklistTransferManagerFactory.address, bytesSTO, web3.utils.toWei("2000", "ether"), 0, false, { from: token_owner }) ); @@ -187,7 +187,7 @@ contract('BlacklistTransferManager', accounts => { it("Should successfully attach the BlacklistTransferManager factory with the security token", async () => { let snapId = await takeSnapshot(); await I_PolyToken.transfer(I_SecurityToken.address, web3.utils.toWei("2000", "ether"), {from: token_owner}); - const tx = await I_SecurityToken.addModule(P_BlacklistTransferManagerFactory.address, bytesSTO, web3.utils.toWei("2000", "ether"), 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(P_BlacklistTransferManagerFactory.address, bytesSTO, web3.utils.toWei("2000", "ether"), 0, false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toString(), transferManagerKey, "BlacklistTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[3].args._name) @@ -200,7 +200,7 @@ contract('BlacklistTransferManager', accounts => { }); it("Should successfully attach the BlacklistTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_BlacklistTransferManagerFactory.address, bytesSTO, 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_BlacklistTransferManagerFactory.address, bytesSTO, 0, 0, false, { from: token_owner }); console.log(tx); assert.equal(tx.logs[2].args._types[0].toString(), transferManagerKey, "BlacklistTransferManager doesn't get deployed"); assert.equal( diff --git a/test/z_fuzz_test_adding_removing_modules_ST.js b/test/z_fuzz_test_adding_removing_modules_ST.js index b4bba2b39..c275918c0 100644 --- a/test/z_fuzz_test_adding_removing_modules_ST.js +++ b/test/z_fuzz_test_adding_removing_modules_ST.js @@ -195,9 +195,9 @@ contract('GeneralPermissionManager', accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -216,7 +216,7 @@ contract('GeneralPermissionManager', accounts => { let errorThrown = false; await I_PolyToken.getTokens(web3.utils.toWei("2000", "ether"), token_owner); await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x0", web3.utils.toWei("2000", "ether"), 0, { from: token_owner }) + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x0", web3.utils.toWei("2000", "ether"), 0, false, { from: token_owner }) ); }); @@ -228,6 +228,7 @@ contract('GeneralPermissionManager', accounts => { "0x0", web3.utils.toWei("2000", "ether"), 0, + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); @@ -241,7 +242,7 @@ contract('GeneralPermissionManager', accounts => { }); it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", 0, 0, false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -296,7 +297,7 @@ contract('GeneralPermissionManager', accounts => { } // attach it to the ST - let tx = await I_SecurityToken.addModule(randomFactory.address, bytesSTO, 0, 0, { from: token_owner }); + let tx = await I_SecurityToken.addModule(randomFactory.address, bytesSTO, 0, 0, false, { from: token_owner }); console.log("1.3"); let randomModuleInstance = await randomModule.at(tx.logs[2].args._module); console.log("successfully attached module " + randomModuleInstance.address); diff --git a/test/z_fuzzer_volumn_restriction_transfer_manager.js b/test/z_fuzzer_volumn_restriction_transfer_manager.js index b2a9215f5..8f6724eb1 100644 --- a/test/z_fuzzer_volumn_restriction_transfer_manager.js +++ b/test/z_fuzzer_volumn_restriction_transfer_manager.js @@ -185,9 +185,9 @@ contract('VolumeRestrictionTransferManager', accounts => { console.log(tx.logs); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -205,7 +205,7 @@ contract('VolumeRestrictionTransferManager', accounts => { describe("Attach the VRTM", async() => { it("Deploy the VRTM and attach with the ST", async()=> { - let tx = await I_SecurityToken.addModule(I_VolumeRestrictionTMFactory.address, "0x0", 0, 0, {from: token_owner }); + let tx = await I_SecurityToken.addModule(I_VolumeRestrictionTMFactory.address, "0x0", 0, 0, false, {from: token_owner }); assert.equal(tx.logs[2].args._moduleFactory, I_VolumeRestrictionTMFactory.address); assert.equal( web3.utils.toUtf8(tx.logs[2].args._name), diff --git a/test/z_general_permission_manager_fuzzer.js b/test/z_general_permission_manager_fuzzer.js index e61032d80..3c11b5ef3 100644 --- a/test/z_general_permission_manager_fuzzer.js +++ b/test/z_general_permission_manager_fuzzer.js @@ -190,9 +190,9 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -211,7 +211,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { let errorThrown = false; await I_PolyToken.getTokens(new BN(web3.utils.toWei("2000", "ether")), token_owner); await catchRevert( - I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), { + I_SecurityToken.addModule(P_GeneralPermissionManagerFactory.address, "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), false, { from: token_owner }) ); @@ -225,6 +225,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { "0x", new BN(web3.utils.toWei("2000", "ether")), new BN(0), + false, { from: token_owner } ); assert.equal(tx.logs[3].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); @@ -238,7 +239,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { }); it("Should successfully attach the General permission manager factory with the security token - free module", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -358,7 +359,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { describe("fuzz test for count transfer manager", async () => { it("Should successfully attach the CountTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_CountTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "CountTransferManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -431,7 +432,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { it("Should successfully attach the percentage transfer manager with the security token", async () => { console.log("1"); - const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_PercentageTransferManagerFactory.address, bytesSTO, new BN(0), new BN(0), false, { from: token_owner }); I_PercentageTransferManager = await PercentageTransferManager.at(tx.logs[2].args._module); }); @@ -579,7 +580,7 @@ contract("GeneralPermissionManager Fuzz", async (accounts) => { describe("fuzz test for manual approval transfer manager", async () => { it("Should successfully attach the ManualApprovalTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_ManualApprovalTransferManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "ManualApprovalTransferManager doesn't get deployed"); assert.equal( web3.utils.toUtf8(tx.logs[2].args._name), diff --git a/test/z_vesting_escrow_wallet.js b/test/z_vesting_escrow_wallet.js index 3b90a5d56..ded4a5b5a 100644 --- a/test/z_vesting_escrow_wallet.js +++ b/test/z_vesting_escrow_wallet.js @@ -149,9 +149,9 @@ contract('VestingEscrowWallet', accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -168,7 +168,7 @@ contract('VestingEscrowWallet', accounts => { }); it("Should successfully attach the General permission manager factory with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toString(), delegateManagerKey, "General Permission Manager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""), @@ -185,7 +185,7 @@ contract('VestingEscrowWallet', accounts => { ); await I_SecurityToken.changeGranularity(1, {from: token_owner}); - const tx = await I_SecurityToken.addModule(I_VestingEscrowWalletFactory.address, bytesData, 0, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_VestingEscrowWalletFactory.address, bytesData, 0, 0, false, { from: token_owner }); assert.equal(tx.logs[3].args._types[0].toString(), 7, "VestingEscrowWallet doesn't get deployed"); assert.equal( diff --git a/test/za_datastore.js b/test/za_datastore.js index 39d8d4f37..f0f963696 100644 --- a/test/za_datastore.js +++ b/test/za_datastore.js @@ -103,9 +103,9 @@ contract("Data store", async (accounts) => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', { filter: { transactionHash: tx.transactionHash } }))[0]; diff --git a/test/zb_signed_transfer_manager.js b/test/zb_signed_transfer_manager.js index c9aac2c7b..ceed2b1a5 100644 --- a/test/zb_signed_transfer_manager.js +++ b/test/zb_signed_transfer_manager.js @@ -142,9 +142,9 @@ contract("SignedTransferManager", accounts => { let tx = await I_STRProxied.generateSecurityToken(name, symbol, tokenDetails, false, token_owner, 0, { from: token_owner }); // Verify the successful generation of the security token - assert.equal(tx.logs[2].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); + assert.equal(tx.logs[1].args._ticker, symbol.toUpperCase(), "SecurityToken doesn't get deployed"); - I_SecurityToken = await SecurityToken.at(tx.logs[2].args._securityTokenAddress); + I_SecurityToken = await SecurityToken.at(tx.logs[1].args._securityTokenAddress); stGetter = await STGetter.at(I_SecurityToken.address); assert.equal(await stGetter.getTreasuryWallet.call(), token_owner, "Incorrect wallet set"); const log = (await I_SecurityToken.getPastEvents('ModuleAdded', {filter: {transactionHash: tx.transactionHash}}))[0]; @@ -193,7 +193,7 @@ contract("SignedTransferManager", accounts => { it("Should successfully attach the SignedTransferManager with the security token", async () => { - const tx = await I_SecurityToken.addModule(I_SignedTransferManagerFactory.address, "0x0",new BN(0),new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_SignedTransferManagerFactory.address, "0x0",new BN(0),new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), transferManagerKey, "SignedTransferManager doesn't get deployed"); assert.equal( web3.utils.toUtf8(tx.logs[2].args._name), @@ -209,7 +209,7 @@ contract("SignedTransferManager", accounts => { it("Should successfully attach the permission manager factory with the security token", async () => { console.log((await I_GeneralPermissionManagerFactory.setupCostInPoly.call()).toString()); - const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), { from: token_owner }); + const tx = await I_SecurityToken.addModule(I_GeneralPermissionManagerFactory.address, "0x0", new BN(0), new BN(0), false, { from: token_owner }); assert.equal(tx.logs[2].args._types[0].toNumber(), delegateManagerKey, "GeneralPermissionManager doesn't get deployed"); assert.equal( web3.utils.toAscii(tx.logs[2].args._name).replace(/\u0000/g, ""),