From d3d6b05ffbeed3bca4eb378dddfeadc3011c39a4 Mon Sep 17 00:00:00 2001 From: Stephane Gosselin Date: Tue, 28 Aug 2018 01:13:47 -0400 Subject: [PATCH 1/5] modify freeze minting functionality --- contracts/ModuleRegistry.sol | 18 ++++++ contracts/interfaces/IModuleRegistry.sol | 6 ++ contracts/interfaces/ISecurityToken.sol | 9 +-- contracts/tokens/SecurityToken.sol | 76 ++++++++++-------------- test/o_security_token.js | 69 ++++++++++----------- 5 files changed, 90 insertions(+), 88 deletions(-) diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 4de0bfb5a..101fe0711 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -24,6 +24,9 @@ contract ModuleRegistry is IModuleRegistry, Pausable, RegistryUpdater, ReclaimTo // Contains the list of the available tags corresponds to the module type mapping (uint8 => bytes32[]) public availableTags; + // Indicate if minting can be frozen permanently by issuers + bool public freezeMintingAllowed; + // Emit when Module been used by the securityToken event LogModuleUsed(address indexed _moduleFactory, address indexed _securityToken); // Emit when the Module Factory get registered with the ModuleRegistry contract @@ -118,6 +121,21 @@ contract ModuleRegistry is IModuleRegistry, Pausable, RegistryUpdater, ReclaimTo } } + /** + * @notice One-way feature switch to enable permanently freezing minting + */ + function allowFreezeMinting() external onlyOwner { + freezeMintingAllowed = true; + } + + /** + * @notice Getter function for freezeMintingAllowed + * @return bool + */ + function freezeMintingAllowed() external view returns(bool) { + return freezeMintingAllowed; + } + /** * @notice pause registration function */ diff --git a/contracts/interfaces/IModuleRegistry.sol b/contracts/interfaces/IModuleRegistry.sol index 466bb554b..7867edec6 100644 --- a/contracts/interfaces/IModuleRegistry.sol +++ b/contracts/interfaces/IModuleRegistry.sol @@ -46,4 +46,10 @@ interface IModuleRegistry { */ function removeTagByModuleType(uint8 _moduleType, bytes32[] _removedTags) external; + /** + * @notice Indicate if minting can be frozen permanently by issuers + * @return bool + */ + function freezeMintingAllowed() external view returns(bool); + } diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index 69fa1d15d..265e3431b 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -145,14 +145,9 @@ interface ISecurityToken { function unfreezeTransfers() external; /** - * @notice End token minting period permanently for Issuer + * @notice End token minting period permanently */ - function finishMintingIssuer() external; - - /** - * @notice End token minting period permanently for STOs - */ - function finishMintingSTO() external; + function freezeMinting() external; /** * @notice mints new tokens and assigns them to the target _investor. diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 3120ae18f..8c98f4201 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -49,8 +49,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr // Reference to token burner contract ITokenBurner public tokenBurner; - // Use to halt all the transactions - bool public freeze = false; + // Use to temporarily halt all transactions + bool public transfersFrozen; + + // Use to permanently halt all minting + bool public mintingFrozen; struct ModuleData { bytes32 name; @@ -66,9 +69,6 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr mapping (address => Checkpoint[]) public checkpointBalances; Checkpoint[] public checkpointTotalSupply; - bool public finishedIssuerMinting = false; - bool public finishedSTOMinting = false; - mapping (bytes4 => bool) transferFunctions; // Module list should be order agnostic! @@ -97,14 +97,12 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr event LogModuleRemoved(uint8 indexed _type, address _module, uint256 _timestamp); // Emit when the budget allocated to a module is changed event LogModuleBudgetChanged(uint8 indexed _moduleType, address _module, uint256 _budget); - // Emit when all the transfers get freeze - event LogFreezeTransfers(bool _freeze, uint256 _timestamp); + // Emit when transfers are frozen or unfrozen + event LogFreezeTransfers(bool _status, uint256 _timestamp); // Emit when new checkpoint created event LogCheckpointCreated(uint256 indexed _checkpointId, uint256 _timestamp); - // Emit when the minting get finished for the Issuer - event LogFinishMintingIssuer(uint256 _timestamp); - // Emit when the minting get finished for the STOs - event LogFinishMintingSTO(uint256 _timestamp); + // Emit when is permanently frozen by the issuer + event LogFreezeMinting(uint256 _timestamp); // Change the STR address in the event of a upgrade event LogChangeSTRAddress(address indexed _oldAddress, address indexed _newAddress); // Events to log minting and burning @@ -135,14 +133,8 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr _; } - // Checks whether the minting is allowed or not, check for the owner if owner is no the msg.sender then check - // for the finishedSTOMinting flag because only STOs and owner are allowed for minting - modifier isMintingAllowed() { - if (msg.sender == owner) { - require(!finishedIssuerMinting, "Minting is finished for Issuer"); - } else { - require(!finishedSTOMinting, "Minting is finished for STOs"); - } + modifier mintingAllowed() { + require(!mintingFrozen, "Minting is permanently frozen"); _; } @@ -381,21 +373,21 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice freeze all the transfers + * @notice freeze transfers */ function freezeTransfers() external onlyOwner { - require(!freeze); - freeze = true; - emit LogFreezeTransfers(freeze, now); + require(!transfersFrozen); + transfersFrozen = true; + emit LogFreezeTransfers(true, now); } /** - * @notice un-freeze all the transfers + * @notice unfreeze transfers */ function unfreezeTransfers() external onlyOwner { - require(freeze); - freeze = false; - emit LogFreezeTransfers(freeze, now); + require(transfersFrozen); + transfersFrozen = false; + emit LogFreezeTransfers(false, now); } /** @@ -486,7 +478,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @return bool */ function verifyTransfer(address _from, address _to, uint256 _amount) public checkGranularity(_amount) returns (bool) { - if (!freeze) { + if (!transfersFrozen) { bool isTransfer = false; if (transferFunctions[getSig(msg.data)]) { isTransfer = true; @@ -515,29 +507,23 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr } /** - * @notice End token minting period permanently for Issuer - */ - function finishMintingIssuer() external onlyOwner { - finishedIssuerMinting = true; - emit LogFinishMintingIssuer(now); - } - - /** - * @notice End token minting period permanently for STOs + * @notice Permanently freeze minting of this security token. + * @dev It MUST NOT be possible to increase `totalSuppy` after this function is called. */ - function finishMintingSTO() external onlyOwner { - finishedSTOMinting = true; - emit LogFinishMintingSTO(now); + function freezeMinting() external mintingAllowed() onlyOwner { + require(IModuleRegistry(moduleRegistry).freezeMintingAllowed()); + mintingFrozen = true; + emit LogFreezeMinting(now); } /** * @notice mints new tokens and assigns them to the target _investor. - * @dev Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet) - * @param _investor Address to whom the minted tokens will be dilivered - * @param _amount Number of tokens get minted + * @dev Can only be called by the issuer or STO attached to the token + * @param _investor Address where the minted tokens will be delivered + * @param _amount Number of tokens be minted * @return success */ - function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) isMintingAllowed() returns (bool success) { + function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) mintingAllowed() returns (bool success) { require(_investor != address(0), "Investor address should not be 0x"); adjustInvestorCount(address(0), _investor, _amount); require(verifyTransfer(address(0), _investor, _amount), "Transfer is not valid"); @@ -552,7 +538,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr /** * @notice mints new tokens and assigns them to the target _investor. - * Can only be called by the STO attached to the token (Or by the ST owner if there's no STO attached yet) + * @dev Can only be called by the issuer or STO attached to the token. * @param _investors A list of addresses to whom the minted tokens will be dilivered * @param _amounts A list of number of tokens get minted and transfer to corresponding address of the investor from _investor[] list * @return success diff --git a/test/o_security_token.js b/test/o_security_token.js index 2072fe742..a371cc12d 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -421,45 +421,63 @@ contract('SecurityToken', accounts => { assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 110); }); - it("Should finish the minting -- fail because msg.sender is not the owner", async() => { + it("Should finish the minting -- fail because feature is not activated", async() => { let errorThrown = false; try { - await I_SecurityToken.finishMintingIssuer({from: account_temp}); + await I_SecurityToken.freezeMinting({from: account_issuer}); } catch(error) { - console.log(` tx revert -> finishMintingIssuer only be called by the owner of the SecurityToken`.grey); + console.log(` tx revert -> freezeMinting cannot be called before activated by polymath`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); }); - it("Should finish minting & rstrict the further minting", async() => { - let id = await takeSnapshot(); - await I_SecurityToken.finishMintingIssuer({from: account_issuer}); + it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { let errorThrown = false; try { - await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + await I_ModuleRegistry.allowFreezeMinting({from: account_issuer}); } catch(error) { - console.log(` tx revert -> Minting is finished`.grey); + console.log(` tx revert -> allowFreezeMinting mus be called by polymath`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); - await revertToSnapshot(id); + }); + + it("Should finish the minting -- successfully activate the feature", async() => { + assert.equal(false, await I_ModuleRegistry.freezeMintingAllowed()); + await I_ModuleRegistry.allowFreezeMinting({from: account_polymath}); + assert.equal(true, await I_ModuleRegistry.freezeMintingAllowed()); }); it("Should finish the minting -- fail because msg.sender is not the owner", async() => { let errorThrown = false; try { - await I_SecurityToken.finishMintingSTO({from: account_temp}); + await I_SecurityToken.freezeMinting({from: account_temp}); } catch(error) { - console.log(` tx revert -> finishMintingSTO only be called by the owner of the SecurityToken`.grey); + console.log(` tx revert -> finishMintingIssuer only be called by the owner of the SecurityToken`.grey); errorThrown = true; ensureException(error); } assert.ok(errorThrown, message); }); + it("Should finish minting & rstrict the further minting", async() => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({from: account_issuer}); + let errorThrown = false; + try { + await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + } catch(error) { + console.log(` tx revert -> Minting is finished`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + await revertToSnapshot(id); + }); + it("Should fail to attach the STO factory because not enough poly in contract", async () => { startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); @@ -677,27 +695,6 @@ contract('SecurityToken', accounts => { ); }); - it("Should finish minting & rstrict the further minting", async() => { - let id = await takeSnapshot(); - await I_SecurityToken.finishMintingSTO({from: account_issuer}); - let errorThrown = false; - try { - // Fallback transaction - await web3.eth.sendTransaction({ - from: account_investor1, - to: I_CappedSTO.address, - gas: 2100000, - value: web3.utils.toWei('2', 'ether') - }); - } catch(error) { - console.log(` tx revert -> Minting is finished`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); - await revertToSnapshot(id); - }); - it("Should Fail in transferring the token from one whitelist investor 1 to non whitelist investor 2", async() => { let errorThrown = false; try { @@ -986,10 +983,10 @@ contract('SecurityToken', accounts => { it("Should freeze the transfers", async() => { let tx = await I_SecurityToken.freezeTransfers({from: token_owner}); - assert.isTrue(tx.logs[0].args._freeze); + assert.isTrue(tx.logs[0].args._status); }); - it("Should freeze the transfers", async() => { + it("Should fail to freeze the transfers", async() => { let errorThrown = false; try { await I_SecurityToken.freezeTransfers({from: token_owner}); @@ -1047,9 +1044,9 @@ contract('SecurityToken', accounts => { assert.ok(errorThrown, message); }); - it("Should un freeze all the transfers", async() => { + it("Should unfreeze all the transfers", async() => { let tx = await I_SecurityToken.unfreezeTransfers({from: token_owner}); - assert.isFalse(tx.logs[0].args._freeze); + assert.isFalse(tx.logs[0].args._status); }); it("Should freeze the transfers", async() => { From 4c11baae8d64ac3fbbbf4fa6cab64d44571f555a Mon Sep 17 00:00:00 2001 From: Stephane Gosselin Date: Tue, 28 Aug 2018 09:46:34 -0400 Subject: [PATCH 2/5] fix isMintingAllowed --- contracts/tokens/SecurityToken.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 8c98f4201..9e79b58ec 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -133,7 +133,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr _; } - modifier mintingAllowed() { + modifier isMintingAllowed() { require(!mintingFrozen, "Minting is permanently frozen"); _; } @@ -510,7 +510,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice Permanently freeze minting of this security token. * @dev It MUST NOT be possible to increase `totalSuppy` after this function is called. */ - function freezeMinting() external mintingAllowed() onlyOwner { + function freezeMinting() external isMintingAllowed() onlyOwner { require(IModuleRegistry(moduleRegistry).freezeMintingAllowed()); mintingFrozen = true; emit LogFreezeMinting(now); @@ -523,7 +523,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _amount Number of tokens be minted * @return success */ - function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) mintingAllowed() returns (bool success) { + function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) isMintingAllowed() returns (bool success) { require(_investor != address(0), "Investor address should not be 0x"); adjustInvestorCount(address(0), _investor, _amount); require(verifyTransfer(address(0), _investor, _amount), "Transfer is not valid"); From 8e5129536326201af30da2e435efe97dec404020 Mon Sep 17 00:00:00 2001 From: Stephane Gosselin Date: Tue, 28 Aug 2018 14:24:50 -0400 Subject: [PATCH 3/5] move feature switch to new Feature Registry contract --- contracts/FeatureRegistry.sol | 37 ++++++++++ contracts/ModuleRegistry.sol | 18 ----- contracts/RegistryUpdater.sol | 2 + contracts/interfaces/IFeatureRegistry.sol | 15 ++++ contracts/interfaces/IModuleRegistry.sol | 6 -- contracts/tokens/SecurityToken.sol | 9 ++- migrations/2_deploy_contracts.js | 44 +++++++----- test/b_capped_sto.js | 44 ++++++++---- test/c_checkpoints.js | 40 ++++++++--- test/d_count_transfer_manager.js | 44 ++++++++---- test/e_erc20_dividends.js | 44 ++++++++---- test/f_ether_dividends.js | 50 ++++++++----- test/g_general_permission_manager.js | 45 ++++++++---- test/h_general_transfer_manager.js | 49 ++++++++----- test/i_Issuance.js | 38 +++++++--- test/j_manual_approval_transfer_manager.js | 40 ++++++++--- test/k_module_registry.js | 38 +++++++--- test/l_percentage_transfer_manager.js | 45 ++++++++---- test/m_presale_sto.js | 47 +++++++++---- test/n_security_token_registry.js | 48 ++++++++----- test/o_security_token.js | 82 ++++++++++++++++------ test/p_ticker_registry.js | 47 +++++++++---- test/q_usd_tiered_sto.js | 50 ++++++++----- test/r_usd_tiered_sto_sim.js | 50 ++++++++----- test/s_concurrent_STO.js | 50 ++++++++----- test/t_v130_to_v140_upgrade.js | 52 +++++++++----- 26 files changed, 717 insertions(+), 317 deletions(-) create mode 100644 contracts/FeatureRegistry.sol create mode 100644 contracts/interfaces/IFeatureRegistry.sol diff --git a/contracts/FeatureRegistry.sol b/contracts/FeatureRegistry.sol new file mode 100644 index 000000000..a771aace7 --- /dev/null +++ b/contracts/FeatureRegistry.sol @@ -0,0 +1,37 @@ +pragma solidity ^0.4.24; + +import "./ReclaimTokens.sol"; +import "./interfaces/IFeatureRegistry.sol"; + +/** + * @title Registry for managing polymath feature switches + */ +contract FeatureRegistry is IFeatureRegistry, ReclaimTokens { + + mapping (bytes32 => bool) public featureStatus; + + event LogChangeFeatureStatus(string _nameKey, bool _newStatus); + + /** + * @notice Get the status of a feature + * @param _nameKey is the key for the feature status mapping + * @return bool + */ + function getFeatureStatus(string _nameKey) external view returns(bool) { + bytes32 key = keccak256(bytes(_nameKey)); + return featureStatus[key]; + } + + /** + * @notice change a feature status + * @param _nameKey is the key for the feature status mapping + * @param _newStatus is the new feature status + */ + function setFeatureStatus(string _nameKey, bool _newStatus) public onlyOwner { + bytes32 key = keccak256(bytes(_nameKey)); + require(featureStatus[key] != _newStatus); + emit LogChangeFeatureStatus(_nameKey, _newStatus); + featureStatus[key] = _newStatus; + } + +} diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index 101fe0711..4de0bfb5a 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -24,9 +24,6 @@ contract ModuleRegistry is IModuleRegistry, Pausable, RegistryUpdater, ReclaimTo // Contains the list of the available tags corresponds to the module type mapping (uint8 => bytes32[]) public availableTags; - // Indicate if minting can be frozen permanently by issuers - bool public freezeMintingAllowed; - // Emit when Module been used by the securityToken event LogModuleUsed(address indexed _moduleFactory, address indexed _securityToken); // Emit when the Module Factory get registered with the ModuleRegistry contract @@ -121,21 +118,6 @@ contract ModuleRegistry is IModuleRegistry, Pausable, RegistryUpdater, ReclaimTo } } - /** - * @notice One-way feature switch to enable permanently freezing minting - */ - function allowFreezeMinting() external onlyOwner { - freezeMintingAllowed = true; - } - - /** - * @notice Getter function for freezeMintingAllowed - * @return bool - */ - function freezeMintingAllowed() external view returns(bool) { - return freezeMintingAllowed; - } - /** * @notice pause registration function */ diff --git a/contracts/RegistryUpdater.sol b/contracts/RegistryUpdater.sol index 906d2e527..0fa25fb12 100644 --- a/contracts/RegistryUpdater.sol +++ b/contracts/RegistryUpdater.sol @@ -9,6 +9,7 @@ contract RegistryUpdater is Ownable { address public moduleRegistry; address public securityTokenRegistry; address public tickerRegistry; + address public featureRegistry; address public polyToken; constructor (address _polymathRegistry) public { @@ -20,6 +21,7 @@ contract RegistryUpdater is Ownable { moduleRegistry = PolymathRegistry(polymathRegistry).getAddress("ModuleRegistry"); securityTokenRegistry = PolymathRegistry(polymathRegistry).getAddress("SecurityTokenRegistry"); tickerRegistry = PolymathRegistry(polymathRegistry).getAddress("TickerRegistry"); + featureRegistry = PolymathRegistry(polymathRegistry).getAddress("FeatureRegistry"); polyToken = PolymathRegistry(polymathRegistry).getAddress("PolyToken"); } diff --git a/contracts/interfaces/IFeatureRegistry.sol b/contracts/interfaces/IFeatureRegistry.sol new file mode 100644 index 000000000..574f412a5 --- /dev/null +++ b/contracts/interfaces/IFeatureRegistry.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.4.24; + +/** + * @title Interface for managing polymath feature switches + */ +interface IFeatureRegistry { + + /** + * @notice Get the status of a feature + * @param _nameKey is the key for the feature status mapping + * @return bool + */ + function getFeatureStatus(string _nameKey) external view returns(bool); + +} diff --git a/contracts/interfaces/IModuleRegistry.sol b/contracts/interfaces/IModuleRegistry.sol index 7867edec6..466bb554b 100644 --- a/contracts/interfaces/IModuleRegistry.sol +++ b/contracts/interfaces/IModuleRegistry.sol @@ -46,10 +46,4 @@ interface IModuleRegistry { */ function removeTagByModuleType(uint8 _moduleType, bytes32[] _removedTags) external; - /** - * @notice Indicate if minting can be frozen permanently by issuers - * @return bool - */ - function freezeMintingAllowed() external view returns(bool); - } diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 9e79b58ec..eb7149eb6 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -5,6 +5,7 @@ import "../interfaces/IPolyToken.sol"; import "../interfaces/IModule.sol"; import "../interfaces/IModuleFactory.sol"; import "../interfaces/IModuleRegistry.sol"; +import "../interfaces/IFeatureRegistry.sol"; import "../modules/TransferManager/ITransferManager.sol"; import "../modules/PermissionManager/IPermissionManager.sol"; import "../interfaces/ITokenBurner.sol"; @@ -138,6 +139,11 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr _; } + modifier isEnabled(string _nameKey) { + require(IFeatureRegistry(featureRegistry).getFeatureStatus(_nameKey)); + _; + } + /** * @notice Constructor * @param _name Name of the SecurityToken @@ -510,8 +516,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice Permanently freeze minting of this security token. * @dev It MUST NOT be possible to increase `totalSuppy` after this function is called. */ - function freezeMinting() external isMintingAllowed() onlyOwner { - require(IModuleRegistry(moduleRegistry).freezeMintingAllowed()); + function freezeMinting() external isMintingAllowed() isEnabled("freezeMintingAllowed") onlyOwner { mintingFrozen = true; emit LogFreezeMinting(now); } diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 7cb4a2ff6..883841760 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -7,9 +7,10 @@ const CountTransferManagerFactory = artifacts.require('./CountTransferManagerFac const EtherDividendCheckpointFactory = artifacts.require('./EtherDividendCheckpointFactory.sol') const ERC20DividendCheckpointFactory = artifacts.require('./ERC20DividendCheckpointFactory.sol') const CappedSTOFactory = artifacts.require('./CappedSTOFactory.sol') -const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol'); +const USDTieredSTOFactory = artifacts.require('./USDTieredSTOFactory.sol') const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol') const TickerRegistry = artifacts.require('./TickerRegistry.sol') +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol') const STFactory = artifacts.require('./tokens/STFactory.sol') const DevPolyToken = artifacts.require('./helpers/PolyTokenFaucet.sol') const MockOracle = artifacts.require('./MockOracle.sol') @@ -179,6 +180,12 @@ module.exports = function (deployer, network, accounts) { }).then(() => { // Assign the address into the SecurityTokenRegistry key return polymathRegistry.changeAddress("SecurityTokenRegistry", SecurityTokenRegistry.address, {from: PolymathAccount}); + }).then(() => { + // K) Deploy the FeatureRegistry contract to control feature switches + return deployer.deploy(FeatureRegistry, PolymathRegistry.address, {from: PolymathAccount}); + }).then(() => { + // Assign the address into the FeatureRegistry key + return polymathRegistry.changeAddress("FeatureRegistry", FeatureRegistry.address, {from: PolymathAccount}); }).then(() => { // Update all addresses into the registry contract by calling the function updateFromregistry return SecurityTokenRegistry.at(SecurityTokenRegistry.address).updateFromRegistry({from: PolymathAccount}); @@ -219,28 +226,29 @@ module.exports = function (deployer, network, accounts) { }).then(() => { console.log('\n'); console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${PolymathRegistry.address} - TickerRegistry: ${TickerRegistry.address} - ModuleRegistry: ${ModuleRegistry.address} - SecurityTokenRegistry: ${SecurityTokenRegistry.address} + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} - ETHOracle: ${ETHOracle.address} - POLYOracle: ${POLYOracle.address} + ETHOracle: ${ETHOracle} + POLYOracle: ${POLYOracle} - STFactory: ${STFactory.address} - GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} - CappedSTOFactory: ${CappedSTOFactory.address} - USDTieredSTOFactory: ${USDTieredSTOFactory.address} + CappedSTOFactory: ${CappedSTOFactory.address} + USDTieredSTOFactory: ${USDTieredSTOFactory.address} - CountTransferManagerFactory: ${CountTransferManagerFactory.address} - PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} + CountTransferManagerFactory: ${CountTransferManagerFactory.address} + PercentageTransferManagerFactory: ${PercentageTransferManagerFactory.address} - EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} - ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} - --------------------------------------------------------------------------- + EtherDividendCheckpointFactory: ${EtherDividendCheckpointFactory.address} + ERC20DividendCheckpointFactory: ${ERC20DividendCheckpointFactory.address} + ----------------------------------------------------------------------------- `); console.log('\n'); // -------- END OF POLYMATH NETWORK Configuration -------// diff --git a/test/b_capped_sto.js b/test/b_capped_sto.js index c71cec8d5..c2b84e139 100644 --- a/test/b_capped_sto.js +++ b/test/b_capped_sto.js @@ -9,6 +9,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -47,6 +48,7 @@ contract('CappedSTO', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_CappedSTOFactory; let I_STFactory; @@ -236,25 +238,41 @@ contract('CappedSTO', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - CappedSTOFactory: ${I_CappedSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + CappedSTOFactory: ${I_CappedSTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/c_checkpoints.js b/test/c_checkpoints.js index d1e6cab48..8099113ac 100644 --- a/test/c_checkpoints.js +++ b/test/c_checkpoints.js @@ -6,6 +6,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -43,6 +44,7 @@ contract('Checkpoints', accounts => { let I_ExchangeTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -163,23 +165,39 @@ contract('Checkpoints', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/d_count_transfer_manager.js b/test/d_count_transfer_manager.js index 41818e695..b76f5cf95 100644 --- a/test/d_count_transfer_manager.js +++ b/test/d_count_transfer_manager.js @@ -7,6 +7,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -50,6 +51,7 @@ contract('CountTransferManager', accounts => { let I_ExchangeTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -209,25 +211,41 @@ contract('CountTransferManager', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/e_erc20_dividends.js b/test/e_erc20_dividends.js index 04e1d6635..ced946e8f 100644 --- a/test/e_erc20_dividends.js +++ b/test/e_erc20_dividends.js @@ -7,6 +7,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -51,6 +52,7 @@ contract('ERC20DividendCheckpoint', accounts => { let I_ExchangeTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -200,25 +202,41 @@ contract('ERC20DividendCheckpoint', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - ERC20DividendCheckpointFactory: ${I_ERC20DividendCheckpointFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + ERC20DividendCheckpointFactory: ${I_ERC20DividendCheckpointFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/f_ether_dividends.js b/test/f_ether_dividends.js index 5c25d3b64..0fde2fc4d 100644 --- a/test/f_ether_dividends.js +++ b/test/f_ether_dividends.js @@ -7,6 +7,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -51,6 +52,7 @@ contract('EtherDividendCheckpoint', accounts => { let I_ExchangeTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -200,25 +202,41 @@ contract('EtherDividendCheckpoint', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + EtherDividendCheckpointFactory: ${I_EtherDividendCheckpointFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/g_general_permission_manager.js b/test/g_general_permission_manager.js index 4586139e1..5f6a78f33 100644 --- a/test/g_general_permission_manager.js +++ b/test/g_general_permission_manager.js @@ -8,6 +8,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -50,6 +51,7 @@ contract('GeneralPermissionManager', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_DummySTOFactory; let I_STFactory; @@ -230,26 +232,41 @@ contract('GeneralPermissionManager', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); - // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - DummySTOFactory: ${I_DummySTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + DummySTOFactory: ${I_DummySTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/h_general_transfer_manager.js b/test/h_general_transfer_manager.js index 30eb5991e..b488309e3 100644 --- a/test/h_general_transfer_manager.js +++ b/test/h_general_transfer_manager.js @@ -8,6 +8,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -51,6 +52,7 @@ contract('GeneralTransferManager', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_DummySTOFactory; let I_STFactory; @@ -218,26 +220,41 @@ contract('GeneralTransferManager', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - DummySTOFactory: ${I_DummySTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + DummySTOFactory: ${I_DummySTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/i_Issuance.js b/test/i_Issuance.js index 8a5f450a2..71adf748e 100644 --- a/test/i_Issuance.js +++ b/test/i_Issuance.js @@ -8,6 +8,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -48,6 +49,7 @@ contract('Issuance', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_CappedSTOFactory; let I_STFactory; @@ -218,25 +220,41 @@ contract('Issuance', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} CappedSTOFactory: ${I_CappedSTOFactory.address} - --------------------------------------------------------------------------- + ----------------------------------------------------------------------------- `); }); diff --git a/test/j_manual_approval_transfer_manager.js b/test/j_manual_approval_transfer_manager.js index 1e474f55b..8f29840c1 100644 --- a/test/j_manual_approval_transfer_manager.js +++ b/test/j_manual_approval_transfer_manager.js @@ -7,6 +7,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -54,6 +55,7 @@ contract('ManualApprovalTransferManager', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -215,26 +217,42 @@ contract('ManualApprovalTransferManager', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} ManualApprovalTransferManagerFactory: ${I_ManualApprovalTransferManagerFactory.address} - CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} - --------------------------------------------------------------------------- + CountTransferManagerFactory: ${I_CountTransferManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/k_module_registry.js b/test/k_module_registry.js index f8d9623a3..7c79933c8 100644 --- a/test/k_module_registry.js +++ b/test/k_module_registry.js @@ -9,6 +9,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -49,6 +50,7 @@ contract('ModuleRegistry', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_CappedSTOFactory; let I_STFactory; @@ -182,19 +184,37 @@ contract('ModuleRegistry', accounts => { }); await I_PolymathRegistry.changeAddress("SecurityTokenRegistry", I_SecurityTokenRegistry.address, {from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/l_percentage_transfer_manager.js b/test/l_percentage_transfer_manager.js index e9ca7c95f..d400a13b2 100644 --- a/test/l_percentage_transfer_manager.js +++ b/test/l_percentage_transfer_manager.js @@ -6,6 +6,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -48,6 +49,7 @@ contract('PercentageTransferManager', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -209,26 +211,41 @@ contract('PercentageTransferManager', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); - // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + PercentageTransferManagerFactory: ${I_PercentageTransferManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/m_presale_sto.js b/test/m_presale_sto.js index ee0ecb2b8..ad04e33d3 100644 --- a/test/m_presale_sto.js +++ b/test/m_presale_sto.js @@ -8,6 +8,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -43,6 +44,7 @@ contract('PreSaleSTO', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_PreSaleSTOFactory; let I_STFactory; @@ -196,27 +198,42 @@ contract('PreSaleSTO', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); await I_TickerRegistry.updateFromRegistry({from: account_polymath}); - // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - PreSaleSTOFactory: ${I_PreSaleSTOFactory.address} - LatestTime: ${latestTime()}\n - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + PreSaleSTOFactory: ${I_PreSaleSTOFactory.address} + LatestTime: ${latestTime()}\n + ----------------------------------------------------------------------------- `); }); diff --git a/test/n_security_token_registry.js b/test/n_security_token_registry.js index b9fc5ad5c..a37572ecd 100644 --- a/test/n_security_token_registry.js +++ b/test/n_security_token_registry.js @@ -9,6 +9,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const STFactory002 = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); @@ -52,6 +53,7 @@ contract('SecurityTokenRegistry', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_TestSTOFactory; let I_STFactory; @@ -221,27 +223,41 @@ contract('SecurityTokenRegistry', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - TestSTOFactory: ${I_TestSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + TestSTOFactory: ${I_TestSTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/o_security_token.js b/test/o_security_token.js index a371cc12d..923635dd4 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -9,6 +9,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -54,6 +55,7 @@ contract('SecurityToken', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_CappedSTOFactory; let I_STFactory; @@ -237,25 +239,41 @@ contract('SecurityToken', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - CappedSTOFactory: ${I_CappedSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + CappedSTOFactory: ${I_CappedSTOFactory.address} + ----------------------------------------------------------------------------- `); }); @@ -436,9 +454,9 @@ contract('SecurityToken', accounts => { it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { let errorThrown = false; try { - await I_ModuleRegistry.allowFreezeMinting({from: account_issuer}); + await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_issuer}); } catch(error) { - console.log(` tx revert -> allowFreezeMinting mus be called by polymath`.grey); + console.log(` tx revert -> allowFreezeMinting must be called by polymath`.grey); errorThrown = true; ensureException(error); } @@ -446,9 +464,29 @@ contract('SecurityToken', accounts => { }); it("Should finish the minting -- successfully activate the feature", async() => { - assert.equal(false, await I_ModuleRegistry.freezeMintingAllowed()); - await I_ModuleRegistry.allowFreezeMinting({from: account_polymath}); - assert.equal(true, await I_ModuleRegistry.freezeMintingAllowed()); + let errorThrown1 = false; + try { + await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", false, {from: account_polymath}); + } catch(error) { + console.log(` tx revert -> must change state`.grey); + errorThrown1 = true; + ensureException(error); + } + assert.ok(errorThrown1, message); + + assert.equal(false, await I_FeatureRegistry.getFeatureStatus("freezeMintingAllowed", {from: account_temp})); + await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath}); + assert.equal(true, await I_FeatureRegistry.getFeatureStatus("freezeMintingAllowed", {from: account_temp})); + + let errorThrown2 = false; + try { + await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_polymath}); + } catch(error) { + console.log(` tx revert -> must change state`.grey); + errorThrown2 = true; + ensureException(error); + } + assert.ok(errorThrown2, message); }); it("Should finish the minting -- fail because msg.sender is not the owner", async() => { @@ -463,7 +501,7 @@ contract('SecurityToken', accounts => { assert.ok(errorThrown, message); }); - it("Should finish minting & rstrict the further minting", async() => { + it("Should finish minting & restrict the further minting", async() => { let id = await takeSnapshot(); await I_SecurityToken.freezeMinting({from: account_issuer}); let errorThrown = false; diff --git a/test/p_ticker_registry.js b/test/p_ticker_registry.js index 305aba6d6..61a90a84e 100644 --- a/test/p_ticker_registry.js +++ b/test/p_ticker_registry.js @@ -6,6 +6,7 @@ const PolymathRegistry = artifacts.require('./PolymathRegistry.sol') const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -43,6 +44,7 @@ contract('TickerRegistry', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_STFactory; let I_SecurityToken; @@ -173,24 +175,39 @@ contract('TickerRegistry', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 8: Set the STR in TickerRegistry - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/q_usd_tiered_sto.js b/test/q_usd_tiered_sto.js index 381b763d4..1939aef47 100644 --- a/test/q_usd_tiered_sto.js +++ b/test/q_usd_tiered_sto.js @@ -10,6 +10,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -46,6 +47,7 @@ contract('USDTieredSTO', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_USDTieredSTOFactory; let I_USDOracle; @@ -283,12 +285,27 @@ contract('USDTieredSTO', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: POLYMATH + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: POLYMATH}); await I_ModuleRegistry.updateFromRegistry({from: POLYMATH}); await I_TickerRegistry.updateFromRegistry({from: POLYMATH}); - // Step 11: Deploy & Register Mock Oracles + // Step 12: Deploy & Register Mock Oracles I_USDOracle = await MockOracle.new(0, "ETH", "USD", USDETH, { from: POLYMATH }); // 500 dollars per POLY I_POLYOracle = await MockOracle.new(I_PolyToken.address, "POLY", "USD", USDPOLY, { from: POLYMATH }); // 25 cents per POLY await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); @@ -296,20 +313,21 @@ contract('USDTieredSTO', accounts => { // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - USDOracle: ${I_USDOracle.address} - POLYOracle: ${I_POLYOracle.address} - USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + USDOracle: ${I_USDOracle.address} + POLYOracle: ${I_POLYOracle.address} + USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/r_usd_tiered_sto_sim.js b/test/r_usd_tiered_sto_sim.js index cc466e6c6..638837cdc 100644 --- a/test/r_usd_tiered_sto_sim.js +++ b/test/r_usd_tiered_sto_sim.js @@ -10,6 +10,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -47,6 +48,7 @@ contract('USDTieredSTO', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_SecurityTokenRegistry; let I_USDTieredSTOFactory; let I_USDOracle; @@ -259,12 +261,27 @@ contract('USDTieredSTO', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: POLYMATH + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: POLYMATH}); await I_ModuleRegistry.updateFromRegistry({from: POLYMATH}); await I_TickerRegistry.updateFromRegistry({from: POLYMATH}); - // Step 11: Deploy & Register Mock Oracles + // Step 12: Deploy & Register Mock Oracles I_USDOracle = await MockOracle.new(0, "ETH", "USD", USDETH, { from: POLYMATH }); // 500 dollars per POLY I_POLYOracle = await MockOracle.new(I_PolyToken.address, "POLY", "USD", USDPOLY, { from: POLYMATH }); // 25 cents per POLY await I_PolymathRegistry.changeAddress("EthUsdOracle", I_USDOracle.address, { from: POLYMATH }); @@ -272,20 +289,21 @@ contract('USDTieredSTO', accounts => { // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - USDOracle: ${I_USDOracle.address} - POLYOracle: ${I_POLYOracle.address} - USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + USDOracle: ${I_USDOracle.address} + POLYOracle: ${I_POLYOracle.address} + USDTieredSTOFactory: ${I_USDTieredSTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/s_concurrent_STO.js b/test/s_concurrent_STO.js index 3ad51475f..14b4859aa 100644 --- a/test/s_concurrent_STO.js +++ b/test/s_concurrent_STO.js @@ -14,6 +14,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -41,6 +42,7 @@ contract('SecurityToken addModule Cap', accounts => { let I_GeneralTransferManager; let I_ModuleRegistry; let I_TickerRegistry; + let I_FeatureRegistry; let I_STFactory; let I_SecurityTokenRegistry; let I_SecurityToken; @@ -225,25 +227,41 @@ contract('SecurityToken addModule Cap', accounts => { "SecurityTokenRegistry contract was not deployed", ); - // Step 10: update the registries addresses from the PolymathRegistry contract - await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); - await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); - await I_TickerRegistry.updateFromRegistry({from: account_polymath}); + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: account_polymath + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: account_polymath}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract + await I_SecurityTokenRegistry.updateFromRegistry({from: account_polymath}); + await I_ModuleRegistry.updateFromRegistry({from: account_polymath}); + await I_TickerRegistry.updateFromRegistry({from: account_polymath}); // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - CappedSTOFactory: ${I_CappedSTOFactory.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + CappedSTOFactory: ${I_CappedSTOFactory.address} + ----------------------------------------------------------------------------- `); }); diff --git a/test/t_v130_to_v140_upgrade.js b/test/t_v130_to_v140_upgrade.js index 83ef9e21e..641a8a5c7 100644 --- a/test/t_v130_to_v140_upgrade.js +++ b/test/t_v130_to_v140_upgrade.js @@ -16,6 +16,7 @@ const ModuleRegistry = artifacts.require('./ModuleRegistry.sol'); const SecurityToken = artifacts.require('./SecurityToken.sol'); const SecurityTokenRegistry = artifacts.require('./SecurityTokenRegistry.sol'); const TickerRegistry = artifacts.require('./TickerRegistry.sol'); +const FeatureRegistry = artifacts.require('./FeatureRegistry.sol'); const STFactory = artifacts.require('./STFactory.sol'); const GeneralPermissionManagerFactory = artifacts.require('./GeneralPermissionManagerFactory.sol'); const GeneralTransferManagerFactory = artifacts.require('./GeneralTransferManagerFactory.sol'); @@ -65,6 +66,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { let I_GeneralTransferManagerFactory; let I_GeneralPermissionManagerFactory; let I_TickerRegistry; + let I_FeatureRegistry; let I_STFactory; let I_SecurityTokenRegistry; @@ -197,17 +199,32 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { assert.equal(tx.logs[0].args._nameKey, "SecurityTokenRegistry"); assert.equal(tx.logs[0].args._newAddress, I_SecurityTokenRegistry.address); - // Step 10: update the registries addresses from the PolymathRegistry contract + // Step 10: Deploy the FeatureRegistry + + I_FeatureRegistry = await FeatureRegistry.new( + I_PolymathRegistry.address, + { + from: POLYMATH + }); + await I_PolymathRegistry.changeAddress("FeatureRegistry", I_FeatureRegistry.address, {from: POLYMATH}); + + assert.notEqual( + I_FeatureRegistry.address.valueOf(), + "0x0000000000000000000000000000000000000000", + "FeatureRegistry contract was not deployed", + ); + + // Step 11: update the registries addresses from the PolymathRegistry contract await I_SecurityTokenRegistry.updateFromRegistry({from: POLYMATH}); await I_ModuleRegistry.updateFromRegistry({from: POLYMATH}); await I_TickerRegistry.updateFromRegistry({from: POLYMATH}); - // Step 11: Mint tokens to ISSUERs + // Step 12: Mint tokens to ISSUERs await I_PolyToken.getTokens(REGFEE * 2, ISSUER1); await I_PolyToken.getTokens(REGFEE * 2, ISSUER2); await I_PolyToken.getTokens(REGFEE * 2, ISSUER3); - // Step 12: Register tokens + // Step 13: Register tokens // (A) : TOK1 await I_PolyToken.approve(I_TickerRegistry.address, REGFEE, { from: ISSUER1 }); tx = await I_TickerRegistry.registerTicker(ISSUER1, symbol1, name1, swarmHash1, { from : ISSUER1 }); @@ -226,7 +243,7 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { assert.equal(tx.logs[0].args._owner, ISSUER3); assert.equal(tx.logs[0].args._symbol, symbol3); - // Step 13: Deploy tokens + // Step 14: Deploy tokens // (A) : TOK1 await I_PolyToken.approve(I_SecurityTokenRegistry.address, REGFEE, { from: ISSUER1}); let tx = await I_SecurityTokenRegistry.generateSecurityToken(name1, symbol1, tokenDetails1, false, { from: ISSUER1 }); @@ -241,19 +258,20 @@ contract('Upgrade from v1.3.0 to v1.4.0', accounts => { // Printing all the contract addresses console.log(` - -------------------- Polymath Network Smart Contracts: -------------------- - PolymathRegistry: ${I_PolymathRegistry.address} - TickerRegistry: ${I_TickerRegistry.address} - SecurityTokenRegistry: ${I_SecurityTokenRegistry.address} - ModuleRegistry: ${I_ModuleRegistry.address} - - STFactory: ${I_STFactory.address} - GeneralTransferManagerFactory: ${I_GeneralTransferManagerFactory.address} - GeneralPermissionManagerFactory: ${I_GeneralPermissionManagerFactory.address} - - SecurityToken TOK1: ${I_SecurityToken1.address} - SecurityToken TOK2: ${I_SecurityToken2.address} - --------------------------------------------------------------------------- + --------------------- Polymath Network Smart Contracts: --------------------- + PolymathRegistry: ${PolymathRegistry.address} + TickerRegistry: ${TickerRegistry.address} + SecurityTokenRegistry: ${SecurityTokenRegistry.address} + ModuleRegistry: ${ModuleRegistry.address} + FeatureRegistry: ${FeatureRegistry.address} + + STFactory: ${STFactory.address} + GeneralTransferManagerFactory: ${GeneralTransferManagerFactory.address} + GeneralPermissionManagerFactory: ${GeneralPermissionManagerFactory.address} + + SecurityToken TOK1: ${I_SecurityToken1.address} + SecurityToken TOK2: ${I_SecurityToken2.address} + ----------------------------------------------------------------------------- `); }); From 03b4a8fb0908688e0819f3e89e5b20a43dd8ebda Mon Sep 17 00:00:00 2001 From: Stephane Gosselin Date: Wed, 29 Aug 2018 21:43:42 -0400 Subject: [PATCH 4/5] simplify onlyModule() and add onlyModuleOrOwner() --- contracts/tokens/SecurityToken.sol | 29 +++++----- test/o_security_token.js | 87 ++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index ce0fd1a4a..463ee4981 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -110,22 +110,23 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr event Minted(address indexed to, uint256 amount); event Burnt(address indexed _burner, uint256 _value); - // If _fallback is true, then for STO module type we only allow the module if it is set, if it is not set we only allow the owner - // for other _moduleType we allow both issuer and module. - modifier onlyModule(uint8 _moduleType, bool _fallback) { - //Loop over all modules of type _moduleType + // Require msg.sender to be the specified module type + modifier onlyModule(uint8 _moduleType) { bool isModuleType = false; for (uint8 i = 0; i < modules[_moduleType].length; i++) { isModuleType = isModuleType || (modules[_moduleType][i].moduleAddress == msg.sender); } - if (_fallback && !isModuleType) { - if (_moduleType == STO_KEY) - require(modules[_moduleType].length == 0 && msg.sender == owner, "Sender is not owner or STO module is attached"); - else - require(msg.sender == owner, "Sender is not owner"); - } else { - require(isModuleType, "Sender is not correct module type"); + require(isModuleType, "msg.sender is not correct module type"); + _; + } + + // Require msg.sender to be the specified module type or the owner of the token + modifier onlyModuleOrOwner(uint8 _moduleType) { + bool isModuleType = false; + for (uint8 i = 0; i < modules[_moduleType].length; i++) { + isModuleType = isModuleType || (modules[_moduleType][i].moduleAddress == msg.sender); } + require(msg.sender == owner || isModuleType, "msg.sender is not owner and not correct module type"); _; } @@ -558,7 +559,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _amount Number of tokens be minted * @return success */ - function mint(address _investor, uint256 _amount) public onlyModule(STO_KEY, true) checkGranularity(_amount) isMintingAllowed() returns (bool success) { + function mint(address _investor, uint256 _amount) public onlyModuleOrOwner(STO_KEY) checkGranularity(_amount) isMintingAllowed() returns (bool success) { require(_investor != address(0), "Investor address should not be 0x"); adjustInvestorCount(address(0), _investor, _amount); require(verifyTransfer(address(0), _investor, _amount), "Transfer is not valid"); @@ -578,7 +579,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @param _amounts A list of number of tokens get minted and transfer to corresponding address of the investor from _investor[] list * @return success */ - function mintMulti(address[] _investors, uint256[] _amounts) external onlyModule(STO_KEY, true) returns (bool success) { + function mintMulti(address[] _investors, uint256[] _amounts) external onlyModuleOrOwner(STO_KEY) returns (bool success) { require(_investors.length == _amounts.length, "Mis-match in the length of the arrays"); for (uint256 i = 0; i < _investors.length; i++) { mint(_investors[i], _amounts[i]); @@ -653,7 +654,7 @@ contract SecurityToken is StandardToken, DetailedERC20, ReentrancyGuard, Registr * @notice Creates a checkpoint that can be used to query historical balances / totalSuppy * @return uint256 */ - function createCheckpoint() external onlyModule(CHECKPOINT_KEY, true) returns(uint256) { + function createCheckpoint() external onlyModuleOrOwner(CHECKPOINT_KEY) returns(uint256) { require(currentCheckpointId < 2**256 - 1); currentCheckpointId = currentCheckpointId + 1; emit LogCheckpointCreated(currentCheckpointId, now); diff --git a/test/o_security_token.js b/test/o_security_token.js index 41702d84d..c32f515da 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -442,7 +442,7 @@ contract('SecurityToken', accounts => { it("Should finish the minting -- fail because feature is not activated", async() => { let errorThrown = false; try { - await I_SecurityToken.freezeMinting({from: account_issuer}); + await I_SecurityToken.freezeMinting({from: token_owner}); } catch(error) { console.log(` tx revert -> freezeMinting cannot be called before activated by polymath`.grey); errorThrown = true; @@ -454,7 +454,7 @@ contract('SecurityToken', accounts => { it("Should finish the minting -- fail to activate the feature because msg.sender is not polymath", async() => { let errorThrown = false; try { - await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: account_issuer}); + await I_FeatureRegistry.setFeatureStatus("freezeMintingAllowed", true, {from: token_owner}); } catch(error) { console.log(` tx revert -> allowFreezeMinting must be called by polymath`.grey); errorThrown = true; @@ -503,7 +503,7 @@ contract('SecurityToken', accounts => { it("Should finish minting & restrict the further minting", async() => { let id = await takeSnapshot(); - await I_SecurityToken.freezeMinting({from: account_issuer}); + await I_SecurityToken.freezeMinting({from: token_owner}); let errorThrown = false; try { await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); @@ -563,6 +563,27 @@ contract('SecurityToken', accounts => { I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); }); + it("Should successfully mint tokens while STO attached", async () => { + await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + let balance = await I_SecurityToken.balanceOf(account_affiliate1); + assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 300); + }); + + it("Should fail to mint tokens while STO attached after freezeMinting called", async () => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({from: token_owner}); + let errorThrown = false; + try { + await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + } catch(error) { + console.log(` tx revert -> Minting is finished`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + await revertToSnapshot(id); + }); + }); describe("Module related functions", async() => { @@ -862,7 +883,7 @@ contract('SecurityToken', accounts => { expiryTime, true, { - from: account_issuer, + from: token_owner, gas: 500000 }); @@ -891,7 +912,7 @@ contract('SecurityToken', accounts => { expiryTime, true, { - from: account_issuer, + from: token_owner, gas: 500000 }); @@ -913,28 +934,18 @@ contract('SecurityToken', accounts => { await revertToSnapshot(ID_snap); }); - it("Should fail in minting the tokens from Issuer", async() => { - let errorThrown = false; - try { - await I_SecurityToken.mint(account_investor1, (10 * Math.pow(10, 18)), { from : token_owner, gas: 2500000}); - } catch(error) { - console.log(` Tx-> revert because Issuer is not allowed to mint after attaching the STO`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should successfully mint tokens while STO attached", async () => { + await I_SecurityToken.mint(account_affiliate1, (100 * Math.pow(10, 18)), {from: token_owner, gas: 500000}); + let balance = await I_SecurityToken.balanceOf(account_affiliate1); + assert.equal(balance.dividedBy(new BigNumber(10).pow(18)).toNumber(), 400); }); - it("Should fail in minting the tokens from Issuer", async() => { - let errorThrown = false; - try { - await I_SecurityToken.mintMulti([account_investor1, account_investor2], [web3.utils.toWei("10"), web3.utils.toWei("10")], { from : token_owner, gas: 2500000}); - } catch(error) { - console.log(` Tx-> revert because Issuer is not allowed to mint after attaching the STO`.grey); - errorThrown = true; - ensureException(error); - } - assert.ok(errorThrown, message); + it("Should mint the tokens for multiple afiliated investors while STO attached", async() => { + await I_SecurityToken.mintMulti([account_affiliate1, account_affiliate2], [(100 * Math.pow(10, 18)), (110 * Math.pow(10, 18))], {from: token_owner, gas: 500000}); + let balance1 = await I_SecurityToken.balanceOf(account_affiliate1); + assert.equal(balance1.dividedBy(new BigNumber(10).pow(18)).toNumber(), 500); + let balance2 = await I_SecurityToken.balanceOf(account_affiliate2); + assert.equal(balance2.dividedBy(new BigNumber(10).pow(18)).toNumber(), 220); }); it("Should provide more permissions to the delegate", async() => { @@ -960,13 +971,13 @@ contract('SecurityToken', accounts => { }); it("should account_temp successfully buy the token", async() => { - // Fallback transaction - await web3.eth.sendTransaction({ + // Fallback transaction + await web3.eth.sendTransaction({ from: account_temp, to: I_CappedSTO.address, gas: 2100000, value: web3.utils.toWei('1', 'ether') - }); + }); assert.equal( (await I_CappedSTO.getRaisedEther.call()) @@ -985,6 +996,26 @@ contract('SecurityToken', accounts => { ); }); + it("STO should fail to mint tokens after minting is frozen", async() => { + let id = await takeSnapshot(); + await I_SecurityToken.freezeMinting({from: token_owner}); + let errorThrown = false; + try { + await web3.eth.sendTransaction({ + from: account_temp, + to: I_CappedSTO.address, + gas: 2100000, + value: web3.utils.toWei('1', 'ether') + }); + } catch(error) { + console.log(` tx revert -> Minting is finished`.grey); + errorThrown = true; + ensureException(error); + } + assert.ok(errorThrown, message); + await revertToSnapshot(id); + }); + it("Should remove investor from the whitelist by the delegate", async() => { let tx = await I_GeneralTransferManager.modifyWhitelist( account_temp, From d64b8b1900fc84dac8aeb5e7c16a75d9a5132dc2 Mon Sep 17 00:00:00 2001 From: Stephane Gosselin Date: Wed, 29 Aug 2018 23:28:25 -0400 Subject: [PATCH 5/5] add revert message --- contracts/FeatureRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/FeatureRegistry.sol b/contracts/FeatureRegistry.sol index a771aace7..ab9f208a2 100644 --- a/contracts/FeatureRegistry.sol +++ b/contracts/FeatureRegistry.sol @@ -29,7 +29,7 @@ contract FeatureRegistry is IFeatureRegistry, ReclaimTokens { */ function setFeatureStatus(string _nameKey, bool _newStatus) public onlyOwner { bytes32 key = keccak256(bytes(_nameKey)); - require(featureStatus[key] != _newStatus); + require(featureStatus[key] != _newStatus, "New feature status must be different than existing status"); emit LogChangeFeatureStatus(_nameKey, _newStatus); featureStatus[key] = _newStatus; }