From eca2cb8b7a78354c53b337435e5b546ca7bbc334 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Wed, 21 Nov 2018 12:57:50 +0100 Subject: [PATCH 1/9] adding label into module data --- contracts/libraries/TokenLib.sol | 1 + contracts/tokens/SecurityToken.sol | 74 ++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index 42e5bebff..8c823ae29 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -16,6 +16,7 @@ library TokenLib { uint8[] moduleTypes; uint256[] moduleIndexes; uint256 nameIndex; + bytes32 label; } // Structures to maintain checkpoints of balances for governance / dividends diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 9cb54865c..3d3e8fa1e 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -213,20 +213,57 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater securityTokenVersion = SemanticVersion(2,0,0); } - /** - * @notice Attachs a module to the SecurityToken - * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it - * @dev to control restrictions on transfers. - * @param _moduleFactory is the address of the module factory to be added - * @param _data is data packed into bytes used to further configure the module (See STO usage) - * @param _maxCost max amount of POLY willing to pay to the module. - * @param _budget max amount of ongoing POLY willing to assign to the module. - */ - function addModule( + // /** + // * @notice Attachs a module to the SecurityToken + // * @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it + // * @dev to control restrictions on transfers. + // * @param _moduleFactory is the address of the module factory to be added + // * @param _data is data packed into bytes used to further configure the module (See STO usage) + // * @param _maxCost max amount of POLY willing to pay to the module. + // * @param _budget max amount of ongoing POLY willing to assign to the module. + // */ + // function addModule( + // address _moduleFactory, + // bytes _data, + // uint256 _maxCost, + // uint256 _budget + // ) external onlyOwner nonReentrant { + // //Check that the module factory exists in the ModuleRegistry - will throw otherwise + // IModuleRegistry(moduleRegistry).useModule(_moduleFactory); + // IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); + // uint8[] memory moduleTypes = moduleFactory.getTypes(); + // uint256 moduleCost = moduleFactory.getSetupCost(); + // require(moduleCost <= _maxCost, "Invalid cost"); + // //Approve fee for module + // ERC20(polyToken).approve(_moduleFactory, moduleCost); + // //Creates instance of module from factory + // address module = moduleFactory.deploy(_data); + // require(modulesToData[module].module == address(0), "Module exists"); + // //Approve ongoing budget + // ERC20(polyToken).approve(module, _budget); + // //Add to SecurityToken module map + // bytes32 moduleName = moduleFactory.getName(); + // uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); + // uint256 i; + // for (i = 0; i < moduleTypes.length; i++) { + // moduleIndexes[i] = modules[moduleTypes[i]].length; + // modules[moduleTypes[i]].push(module); + // } + // modulesToData[module] = TokenLib.ModuleData( + // moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length + // ); + // names[moduleName].push(module); + // //Emit log event + // /*solium-disable-next-line security/no-block-members*/ + // emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); + // } + + function addModuleWithLabel( address _moduleFactory, bytes _data, uint256 _maxCost, - uint256 _budget + uint256 _budget, + bytes32 _label ) external onlyOwner nonReentrant { //Check that the module factory exists in the ModuleRegistry - will throw otherwise IModuleRegistry(moduleRegistry).useModule(_moduleFactory); @@ -250,7 +287,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater modules[moduleTypes[i]].push(module); } modulesToData[module] = TokenLib.ModuleData( - moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length + moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length, _label ); names[moduleName].push(module); //Emit log event @@ -258,6 +295,16 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); } + + function addModule( + address _moduleFactory, + bytes _data, + uint256 _maxCost, + uint256 _budget + ){ + addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, "NA"); + } + /** * @notice Archives a module attached to the SecurityToken * @param _module address of module to archive @@ -330,12 +377,13 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater * @return bool module archived * @return uint8 module type */ - function getModule(address _module) external view returns (bytes32, address, address, bool, uint8[]) { + function getModule(address _module) external view returns (bytes32, address, address, bool, uint8[], bytes32) { return (modulesToData[_module].name, modulesToData[_module].module, modulesToData[_module].moduleFactory, modulesToData[_module].isArchived, modulesToData[_module].moduleTypes); + modulesToData[_module].label); } /** From 7cae2a1d18e94652a251ef1c53ff0f40d7fceec0 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 22 Nov 2018 12:41:08 +0100 Subject: [PATCH 2/9] fixing test --- contracts/tokens/SecurityToken.sol | 4 ++-- test/o_security_token.js | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 3d3e8fa1e..ce3528b4d 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -302,7 +302,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater uint256 _maxCost, uint256 _budget ){ - addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, "NA"); + return addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, ""); } /** @@ -382,7 +382,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater modulesToData[_module].module, modulesToData[_module].moduleFactory, modulesToData[_module].isArchived, - modulesToData[_module].moduleTypes); + modulesToData[_module].moduleTypes, modulesToData[_module].label); } diff --git a/test/o_security_token.js b/test/o_security_token.js index 9cee77f80..a06f8593e 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -311,6 +311,21 @@ contract("SecurityToken", accounts => { I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); }); + it("Should successfully attach the STO factory with the security token", async () => { + startTime = latestTime() + duration.seconds(5000); + endTime = startTime + duration.days(30); + let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); + + await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); + await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner }); + + const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + + assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); + assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); + 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); @@ -334,6 +349,7 @@ contract("SecurityToken", accounts => { assert.equal(moduleData[2], I_CappedSTOFactory.address); assert.equal(moduleData[3], false); assert.equal(moduleData[4][0], 3); + assert.equal(moduleData[5], 'NA'); }); it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { From 4182cd97c789b7998e61bf2c17d66c6e37209fbf Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 22 Nov 2018 13:22:17 +0100 Subject: [PATCH 3/9] debug test --- contracts/tokens/SecurityToken.sol | 10 +++++----- test/o_security_token.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index ce3528b4d..d6061b01b 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -90,6 +90,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater address _module, uint256 _moduleCost, uint256 _budget, + bytes32 _label, uint256 _timestamp ); @@ -262,9 +263,9 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater address _moduleFactory, bytes _data, uint256 _maxCost, - uint256 _budget, + uint256 _budget, bytes32 _label - ) external onlyOwner nonReentrant { + ) onlyOwner nonReentrant { //Check that the module factory exists in the ModuleRegistry - will throw otherwise IModuleRegistry(moduleRegistry).useModule(_moduleFactory); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); @@ -292,16 +293,15 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater names[moduleName].push(module); //Emit log event /*solium-disable-next-line security/no-block-members*/ - emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); + emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, _label, now); } - function addModule( address _moduleFactory, bytes _data, uint256 _maxCost, uint256 _budget - ){ + ) external { return addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, ""); } diff --git a/test/o_security_token.js b/test/o_security_token.js index a06f8593e..9ff26e3d3 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -342,14 +342,14 @@ contract("SecurityToken", accounts => { }); describe("Module related functions", async () => { - it("Should get the modules of the securityToken by index", async () => { + it(" Should get the modules of the securityToken by name", async () => { let moduleData = await I_SecurityToken.getModule.call(I_CappedSTO.address); assert.equal(web3.utils.toAscii(moduleData[0]).replace(/\u0000/g, ""), "CappedSTO"); assert.equal(moduleData[1], I_CappedSTO.address); assert.equal(moduleData[2], I_CappedSTOFactory.address); assert.equal(moduleData[3], false); assert.equal(moduleData[4][0], 3); - assert.equal(moduleData[5], 'NA'); + assert.equal(moduleData[5], 0x0000000000000000000000000000000000000000); }); it("Should get the modules of the securityToken by index (not added into the security token yet)", async () => { From 02a334a85d0fdb7832b07091ba467ad7f76159fc Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 22 Nov 2018 13:54:48 +0100 Subject: [PATCH 4/9] fixing test cases --- test/o_security_token.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/o_security_token.js b/test/o_security_token.js index 9ff26e3d3..79241b93f 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -296,7 +296,8 @@ contract("SecurityToken", accounts => { ); }); - it("Should successfully attach the STO factory with the security token", async () => { + it("Should successfully add module with label", async () => { + let snapId = await takeSnapshot(); startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); @@ -304,14 +305,18 @@ contract("SecurityToken", accounts => { await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner }); - const tx = await I_SecurityToken.addModule(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, { from: token_owner }); + const tx = await I_SecurityToken.addModuleWithLabel(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, "stofactory", { from: token_owner }); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); + console.log("module label is .. "+ web3.utils.toAscii(tx.logs[3].args._label)); + assert(web3.utils.toAscii(tx.logs[3].args._label), "stofactory", "label doesnt match" ); I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); + await revertToSnapshot(snapId); }); it("Should successfully attach the STO factory with the security token", async () => { + startTime = latestTime() + duration.seconds(5000); endTime = startTime + duration.days(30); let bytesSTO = encodeModuleCall(STOParameters, [startTime, endTime, cap, rate, fundRaiseType, account_fundsReceiver]); From 114b929b32a063fa0d11187dd228f28d3851a9e8 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Thu, 22 Nov 2018 13:55:28 +0100 Subject: [PATCH 5/9] testing module label --- test/o_security_token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/o_security_token.js b/test/o_security_token.js index 79241b93f..a9b746f2b 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -310,7 +310,7 @@ contract("SecurityToken", accounts => { assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); console.log("module label is .. "+ web3.utils.toAscii(tx.logs[3].args._label)); - assert(web3.utils.toAscii(tx.logs[3].args._label), "stofactory", "label doesnt match" ); + assert(web3.utils.toAscii(tx.logs[3].args._glabel), "stofactory", "label doesnt match" ); I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); await revertToSnapshot(snapId); }); From 535d957c136c18433fbc88486daf820f1f8d8f82 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Fri, 23 Nov 2018 13:41:31 +0100 Subject: [PATCH 6/9] finish labeling module --- contracts/tokens/SecurityToken.sol | 39 +++--------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index d6061b01b..2d7237f80 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -222,42 +222,8 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater // * @param _data is data packed into bytes used to further configure the module (See STO usage) // * @param _maxCost max amount of POLY willing to pay to the module. // * @param _budget max amount of ongoing POLY willing to assign to the module. + // * @param _label custom module label. // */ - // function addModule( - // address _moduleFactory, - // bytes _data, - // uint256 _maxCost, - // uint256 _budget - // ) external onlyOwner nonReentrant { - // //Check that the module factory exists in the ModuleRegistry - will throw otherwise - // IModuleRegistry(moduleRegistry).useModule(_moduleFactory); - // IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); - // uint8[] memory moduleTypes = moduleFactory.getTypes(); - // uint256 moduleCost = moduleFactory.getSetupCost(); - // require(moduleCost <= _maxCost, "Invalid cost"); - // //Approve fee for module - // ERC20(polyToken).approve(_moduleFactory, moduleCost); - // //Creates instance of module from factory - // address module = moduleFactory.deploy(_data); - // require(modulesToData[module].module == address(0), "Module exists"); - // //Approve ongoing budget - // ERC20(polyToken).approve(module, _budget); - // //Add to SecurityToken module map - // bytes32 moduleName = moduleFactory.getName(); - // uint256[] memory moduleIndexes = new uint256[](moduleTypes.length); - // uint256 i; - // for (i = 0; i < moduleTypes.length; i++) { - // moduleIndexes[i] = modules[moduleTypes[i]].length; - // modules[moduleTypes[i]].push(module); - // } - // modulesToData[module] = TokenLib.ModuleData( - // moduleName, module, _moduleFactory, false, moduleTypes, moduleIndexes, names[moduleName].length - // ); - // names[moduleName].push(module); - // //Emit log event - // /*solium-disable-next-line security/no-block-members*/ - // emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, now); - // } function addModuleWithLabel( address _moduleFactory, @@ -296,6 +262,9 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater emit ModuleAdded(moduleTypes, moduleName, _moduleFactory, module, moduleCost, _budget, _label, now); } + /** + * @notice addModule function will call addModuleWithLabel() with an empty label for backward compatible + */ function addModule( address _moduleFactory, bytes _data, From 8d52ecb20dc6b3bc08c2224528415dc1fa9bebf3 Mon Sep 17 00:00:00 2001 From: comeonbuddy Date: Fri, 23 Nov 2018 16:13:49 +0100 Subject: [PATCH 7/9] fixed test --- test/o_security_token.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/o_security_token.js b/test/o_security_token.js index a9b746f2b..39b026828 100644 --- a/test/o_security_token.js +++ b/test/o_security_token.js @@ -304,13 +304,13 @@ contract("SecurityToken", accounts => { await I_PolyToken.getTokens(cappedSTOSetupCost, token_owner); await I_PolyToken.transfer(I_SecurityToken.address, cappedSTOSetupCost, { from: token_owner }); - - const tx = await I_SecurityToken.addModuleWithLabel(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, "stofactory", { from: token_owner }); - + console.log("0"); + const tx = await I_SecurityToken.addModuleWithLabel(I_CappedSTOFactory.address, bytesSTO, maxCost, 0, 'stofactory', { from: token_owner }); + console.log("1"); assert.equal(tx.logs[3].args._types[0], stoKey, "CappedSTO doesn't get deployed"); assert.equal(web3.utils.toUtf8(tx.logs[3].args._name), "CappedSTO", "CappedSTOFactory module was not added"); console.log("module label is .. "+ web3.utils.toAscii(tx.logs[3].args._label)); - assert(web3.utils.toAscii(tx.logs[3].args._glabel), "stofactory", "label doesnt match" ); + assert(web3.utils.toAscii(tx.logs[3].args._label), "stofactory", "label doesnt match"); I_CappedSTO = CappedSTO.at(tx.logs[3].args._module); await revertToSnapshot(snapId); }); From ad29b9f7b6a4a40d460ba7235aab85880ea48f56 Mon Sep 17 00:00:00 2001 From: Ricko Date: Tue, 27 Nov 2018 11:52:36 +0100 Subject: [PATCH 8/9] updating addModuleWithLabel adding public --- contracts/tokens/SecurityToken.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 2d7237f80..1a5d1268e 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -231,7 +231,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater uint256 _maxCost, uint256 _budget, bytes32 _label - ) onlyOwner nonReentrant { + ) public onlyOwner nonReentrant { //Check that the module factory exists in the ModuleRegistry - will throw otherwise IModuleRegistry(moduleRegistry).useModule(_moduleFactory); IModuleFactory moduleFactory = IModuleFactory(_moduleFactory); From 6e6b137d51064366f7ab80779d7f23fbb1d9278e Mon Sep 17 00:00:00 2001 From: Ricko Date: Tue, 27 Nov 2018 11:53:54 +0100 Subject: [PATCH 9/9] updateding addModule get rid of return --- contracts/tokens/SecurityToken.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index 1a5d1268e..3c27d7d94 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -271,7 +271,7 @@ contract SecurityToken is ERC20, ERC20Detailed, ReentrancyGuard, RegistryUpdater uint256 _maxCost, uint256 _budget ) external { - return addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, ""); + addModuleWithLabel(_moduleFactory, _data, _maxCost, _budget, ""); } /**